💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

707 lines
22 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "game/system/terrain.hpp"
  20. #include "game/component/terrain.hpp"
  21. #include "game/component/camera.hpp"
  22. #include "geom/meshes/grid.hpp"
  23. #include "geom/mesh-functions.hpp"
  24. #include "geom/morton.hpp"
  25. #include "geom/quadtree.hpp"
  26. #include "geom/primitive/ray.hpp"
  27. #include "gl/vertex-attribute.hpp"
  28. #include "math/quaternion.hpp"
  29. #include "render/vertex-attribute.hpp"
  30. #include "utility/fundamental-types.hpp"
  31. #include "math/compile.hpp"
  32. #include <functional>
  33. #include <iostream>
  34. namespace game {
  35. namespace system {
  36. terrain::terrain(entity::registry& registry):
  37. updatable(registry),
  38. patch_side_length(0.0f),
  39. patch_subdivisions(0),
  40. patch_material(nullptr),
  41. elevation_function(nullptr),
  42. scene_collection(nullptr),
  43. patch_base_mesh(nullptr),
  44. patch_vertex_size(0),
  45. patch_vertex_stride(0),
  46. patch_vertex_data(nullptr)
  47. {
  48. // Specify vertex size and stride
  49. // (position + uv + normal + tangent + barycentric + target)
  50. patch_vertex_size = 3 + 2 + 3 + 4 + 3 + 3;
  51. patch_vertex_stride = patch_vertex_size * sizeof(float);
  52. // Init quadtee node sizes at each depth
  53. for (std::size_t i = 0; i <= quadtree_type::max_depth; ++i)
  54. quadtree_node_size[i] = 0.0f;
  55. geom::quadtree64<geom::hyperoctree_order::dfs_pre> q;
  56. q.insert(q.node(4, 0));
  57. //q.insert(q.node(8, geom::morton::encode<std::uint64_t>(4, 4)));
  58. // std::cout << "q size: " << q.size() << std::endl;
  59. // q.erase(q.node(1, 0));
  60. // std::cout << "q size: " << q.size() << std::endl;
  61. std::cout << "q maxd : " << (std::size_t)q.max_depth << std::endl;
  62. std::cout << "q res : " << (std::size_t)q.resolution << std::endl;
  63. std::cout << "q cap : " << q.max_size() << std::endl;
  64. std::cout << "set cap: " << std::set<std::uint64_t>().max_size() << std::endl;
  65. std::cout << "q size: " << q.size() << std::endl;
  66. for (auto it = q.begin(); it != q.end(); ++it)
  67. {
  68. const auto& node = *it;
  69. auto [depth, location] = q.split(node);
  70. std::cout << "depth: " << (std::size_t)depth << "; location: " << (std::size_t)location << std::endl;
  71. }
  72. registry.on_construct<component::terrain>().connect<&terrain::on_terrain_construct>(this);
  73. registry.on_update<component::terrain>().connect<&terrain::on_terrain_update>(this);
  74. registry.on_destroy<component::terrain>().connect<&terrain::on_terrain_destroy>(this);
  75. }
  76. terrain::~terrain()
  77. {
  78. registry.on_construct<component::terrain>().disconnect<&terrain::on_terrain_construct>(this);
  79. registry.on_update<component::terrain>().disconnect<&terrain::on_terrain_update>(this);
  80. registry.on_destroy<component::terrain>().disconnect<&terrain::on_terrain_destroy>(this);
  81. }
  82. void terrain::update(double t, double dt)
  83. {
  84. // Clear quadtree
  85. quadtree.clear();
  86. // For each camera
  87. this->registry.view<component::camera>().each
  88. (
  89. [&](entity::id camera_eid, const auto& camera)
  90. {
  91. if (!camera.object)
  92. return;
  93. const scene::camera& cam = *camera.object;
  94. // for (int i = 0; i < 8; ++i)
  95. // std::cout << "corner " << i << ": " << cam.get_view_frustum().get_corners()[i] << std::endl;
  96. geom::primitive::ray<float, 3> rays[8];
  97. rays[0] = cam.pick({-1, -1});
  98. rays[1] = cam.pick({-1, 1});
  99. rays[2] = cam.pick({ 1, 1});
  100. rays[3] = cam.pick({ 1, -1});
  101. float3 ntl = rays[0].origin;
  102. float3 nbl = rays[1].origin;
  103. float3 nbr = rays[2].origin;
  104. float3 ntr = rays[3].origin;
  105. float3 ftl = rays[0].origin + rays[0].direction * (cam.get_clip_far() - cam.get_clip_near());
  106. float3 fbl = rays[1].origin + rays[1].direction * (cam.get_clip_far() - cam.get_clip_near());
  107. float3 fbr = rays[2].origin + rays[2].direction * (cam.get_clip_far() - cam.get_clip_near());
  108. float3 ftr = rays[3].origin + rays[3].direction * (cam.get_clip_far() - cam.get_clip_near());
  109. // for (int i = 0; i < 8; ++i)
  110. // std::cout << "ray or " << i << ": " << rays[i].origin << std::endl;
  111. geom::convex_hull<float> hull(6);
  112. hull.planes[0] = geom::plane<float>(ftl, fbl, nbl);
  113. hull.planes[1] = geom::plane<float>(ntr, nbr, fbr);
  114. hull.planes[2] = geom::plane<float>(fbl, fbr, nbr);
  115. hull.planes[3] = geom::plane<float>(ftl, ntl, ntr);
  116. hull.planes[4] = geom::plane<float>(ntl, nbl, nbr);
  117. hull.planes[5] = geom::plane<float>(ftr, fbr, fbl);
  118. geom::sphere<float> sphere;
  119. sphere.center = cam.get_translation();
  120. sphere.radius = patch_side_length;
  121. //visit_quadtree(cam.get_view_frustum().get_bounds(), quadtree_type::root);
  122. visit_quadtree(sphere, quadtree_type::root);
  123. }
  124. );
  125. //std::cout << "qsize: " << quadtree.size() << std::endl;
  126. std::size_t qvis = 0;
  127. /// Toggle visibility of terrain scene objects
  128. for (auto it = patches.begin(); it != patches.end(); ++it)
  129. {
  130. bool active = (quadtree.contains(it->first) && quadtree.is_leaf(it->first));
  131. it->second->model_instance->set_active(active);
  132. if (active)
  133. ++qvis;
  134. }
  135. //std::cout << "qvis: " << qvis << std::endl;
  136. }
  137. void terrain::set_patch_side_length(float length)
  138. {
  139. patch_side_length = length;
  140. // Recalculate node sizes at each quadtree depth
  141. for (std::size_t i = 0; i <= quadtree_type::max_depth; ++i)
  142. {
  143. quadtree_node_size[i] = std::exp2(quadtree_type::max_depth - i) * patch_side_length;
  144. //std::cout << quadtree_node_size[i] << std::endl;
  145. }
  146. }
  147. void terrain::set_patch_subdivisions(std::size_t n)
  148. {
  149. patch_subdivisions = n;
  150. // Recalculate patch properties
  151. patch_cell_count = (patch_subdivisions + 1) * (patch_subdivisions + 1);
  152. patch_triangle_count = patch_cell_count * 2;
  153. // Resize patch vertex data buffer
  154. delete[] patch_vertex_data;
  155. patch_vertex_data = new float[patch_triangle_count * 3 * patch_vertex_size];
  156. // Resize patch buffers
  157. std::size_t vertex_buffer_row_size = patch_subdivisions + 4;
  158. std::size_t vertex_buffer_column_size = vertex_buffer_row_size;
  159. patch_vertex_buffer.resize(vertex_buffer_row_size);
  160. for (std::size_t i = 0; i < patch_vertex_buffer.size(); ++i)
  161. patch_vertex_buffer[i].resize(vertex_buffer_column_size);
  162. rebuild_patch_base_mesh();
  163. }
  164. void terrain::set_patch_material(::render::material* material)
  165. {
  166. patch_material = material;
  167. }
  168. void terrain::set_elevation_function(const std::function<float(float, float)>& f)
  169. {
  170. elevation_function = f;
  171. }
  172. void terrain::set_scene_collection(scene::collection* collection)
  173. {
  174. scene_collection = collection;
  175. }
  176. void terrain::on_terrain_construct(entity::registry& registry, entity::id entity_id)
  177. {
  178. }
  179. void terrain::on_terrain_update(entity::registry& registry, entity::id entity_id)
  180. {
  181. }
  182. void terrain::on_terrain_destroy(entity::registry& registry, entity::id entity_id)
  183. {
  184. }
  185. float terrain::get_patch_size(quadtree_node_type node) const
  186. {
  187. return quadtree_node_size[quadtree_type::depth(node)];
  188. }
  189. float3 terrain::get_patch_center(quadtree_node_type node) const
  190. {
  191. const float node_size = get_patch_size(node);
  192. const float node_offset = quadtree_node_size[0] * -0.5f + node_size * 0.5f;
  193. // Extract node location from Morton location code
  194. quadtree_type::node_type node_location = quadtree_type::location(node);
  195. quadtree_type::node_type node_location_x;
  196. quadtree_type::node_type node_location_y;
  197. geom::morton::decode(node_location, node_location_x, node_location_y);
  198. return float3
  199. {
  200. node_offset + static_cast<float>(node_location_x) * node_size,
  201. 0.0f,
  202. node_offset + static_cast<float>(node_location_y) * node_size
  203. };
  204. }
  205. void terrain::rebuild_patch_base_mesh()
  206. {
  207. // Rebuild grid
  208. delete patch_base_mesh;
  209. patch_base_mesh = geom::meshes::grid_xy(1.0f, patch_subdivisions, patch_subdivisions);
  210. // Convert quads to triangle fans
  211. for (std::size_t i = 0; i < patch_base_mesh->get_faces().size(); ++i)
  212. {
  213. geom::mesh::face* face = patch_base_mesh->get_faces()[i];
  214. std::size_t edge_count = 1;
  215. for (geom::mesh::edge* edge = face->edge->next; edge != face->edge; edge = edge->next)
  216. ++edge_count;
  217. if (edge_count > 3)
  218. {
  219. geom::poke_face(*patch_base_mesh, face->index);
  220. --i;
  221. }
  222. }
  223. // Transform patch base mesh coordinates from XY plane to XZ plane
  224. const math::quaternion<float> xy_to_xz = math::quaternion<float>::rotate_x(math::half_pi<float>);
  225. for (geom::mesh::vertex* vertex: patch_base_mesh->get_vertices())
  226. {
  227. vertex->position = xy_to_xz * vertex->position;
  228. }
  229. }
  230. void terrain::visit_quadtree(const geom::bounding_volume<float>& volume, quadtree_node_type node)
  231. {
  232. const float root_offset = quadtree_node_size[0] * -0.5f;
  233. // Extract node depth
  234. quadtree_type::node_type node_depth = quadtree_type::depth(node);
  235. const float node_size = get_patch_size(node);
  236. const float3 node_center = get_patch_center(node);
  237. // Build node bounds AABB
  238. geom::aabb<float> node_bounds;
  239. node_bounds.min_point =
  240. {
  241. node_center.x() - node_size * 0.5f,
  242. -std::numeric_limits<float>::infinity(),
  243. node_center.z() - node_size * 0.5f
  244. };
  245. node_bounds.max_point =
  246. {
  247. node_bounds.min_point.x() + node_size,
  248. std::numeric_limits<float>::infinity(),
  249. node_bounds.min_point.z() + node_size
  250. };
  251. // If volume intersects node
  252. if (volume.intersects(node_bounds))
  253. {
  254. // Subdivide leaf nodes
  255. if (quadtree.is_leaf(node))
  256. {
  257. quadtree.insert(quadtree_type::child(node, 0));
  258. for (quadtree_node_type i = 0; i < quadtree_type::children_per_node; ++i)
  259. {
  260. quadtree_node_type child = quadtree_type::child(node, i);
  261. if (patches.find(child) == patches.end())
  262. {
  263. patch* child_patch = generate_patch(child);
  264. patches[child] = child_patch;
  265. scene_collection->add_object(child_patch->model_instance);
  266. }
  267. }
  268. }
  269. // Visit children
  270. if (node_depth < quadtree_type::max_depth - 1)
  271. {
  272. for (quadtree_node_type i = 0; i < quadtree_type::children_per_node; ++i)
  273. visit_quadtree(volume, quadtree_type::child(node, i));
  274. }
  275. }
  276. }
  277. geom::mesh* terrain::generate_patch_mesh(quadtree_node_type node) const
  278. {
  279. // Extract node depth
  280. const quadtree_type::node_type node_depth = quadtree_type::depth(node);
  281. // Get size of node at depth
  282. const float node_size = quadtree_node_size[node_depth];
  283. // Extract node Morton location code and decode location
  284. const quadtree_type::node_type node_location = quadtree_type::location(node);
  285. quadtree_type::node_type node_location_x;
  286. quadtree_type::node_type node_location_y;
  287. geom::morton::decode(node_location, node_location_x, node_location_y);
  288. // Determine center of node
  289. const float node_offset = quadtree_node_size[0] * -0.5f + node_size * 0.5f;
  290. const float3 node_center =
  291. {
  292. node_offset + static_cast<float>(node_location_x) * node_size,
  293. 0.0f,
  294. node_offset + static_cast<float>(node_location_y) * node_size
  295. };
  296. // Copy patch base mesh
  297. geom::mesh* patch_mesh = new geom::mesh(*patch_base_mesh);
  298. // Modify patch mesh vertex positions
  299. for (geom::mesh::vertex* v: patch_mesh->get_vertices())
  300. {
  301. v->position.x() = node_center.x() + v->position.x() * node_size;
  302. v->position.z() = node_center.z() + v->position.z() * node_size;
  303. v->position.y() = elevation_function(v->position.x(), v->position.z());
  304. }
  305. return patch_mesh;
  306. }
  307. ::render::model* terrain::generate_patch_model(quadtree_node_type node) const
  308. {
  309. // Get size and position of patch
  310. const float patch_size = get_patch_size(node);
  311. const float3 patch_center = get_patch_center(node);
  312. // Calculate size of a patch cell
  313. const float cell_size = patch_size / static_cast<float>(patch_subdivisions + 1);
  314. const float half_cell_size = cell_size * 0.5f;
  315. // Init patch bounds
  316. geom::aabb<float> patch_bounds;
  317. patch_bounds.min_point.x() = patch_center.x() - patch_size * 0.5f;
  318. patch_bounds.min_point.y() = std::numeric_limits<float>::infinity();
  319. patch_bounds.min_point.z() = patch_center.z() - patch_size * 0.5f;
  320. patch_bounds.max_point.x() = patch_center.x() + patch_size * 0.5f;
  321. patch_bounds.max_point.y() = -std::numeric_limits<float>::infinity();
  322. patch_bounds.max_point.z() = patch_center.z() + patch_size * 0.5f;
  323. // Calculate positions and UVs of patch vertices and immediately neighboring vertices
  324. float3 first_vertex_position =
  325. {
  326. patch_bounds.min_point.x() - cell_size,
  327. patch_center.y(),
  328. patch_bounds.min_point.z() - cell_size
  329. };
  330. float3 vertex_position = first_vertex_position;
  331. for (std::size_t i = 0; i < patch_vertex_buffer.size(); ++i)
  332. {
  333. // For each column
  334. for (std::size_t j = 0; j < patch_vertex_buffer[i].size(); ++j)
  335. {
  336. // Calculate vertex elevation
  337. vertex_position.y() = elevation_function(vertex_position.x(), vertex_position.z());
  338. // Update patch bounds
  339. patch_bounds.min_point.y() = std::min(patch_bounds.min_point.y(), vertex_position.y());
  340. patch_bounds.max_point.y() = std::max(patch_bounds.max_point.y(), vertex_position.y());
  341. // Update patch vertex position
  342. patch_vertex_buffer[i][j].position = vertex_position;
  343. // Calculate patch vertex UV
  344. patch_vertex_buffer[i][j].uv.x() = (vertex_position.x() - patch_bounds.min_point.x()) / patch_size;
  345. patch_vertex_buffer[i][j].uv.y() = (vertex_position.z() - patch_bounds.min_point.z()) / patch_size;
  346. // Init patch vertex normal, tangent, and bitangent
  347. patch_vertex_buffer[i][j].normal = {0, 0, 0};
  348. patch_vertex_buffer[i][j].tangent = {0, 0, 0};
  349. patch_vertex_buffer[i][j].bitangent = {0, 0, 0};
  350. vertex_position.x() += cell_size;
  351. }
  352. vertex_position.z() += cell_size;
  353. vertex_position.x() = first_vertex_position.x();
  354. }
  355. // Accumulate normals, tangents, and bitangents
  356. for (std::size_t i = 0; i < patch_vertex_buffer.size() - 1; ++i)
  357. {
  358. for (std::size_t j = 0; j < patch_vertex_buffer[i].size() - 1; ++j)
  359. {
  360. patch_vertex& a = patch_vertex_buffer[i ][j];
  361. patch_vertex& b = patch_vertex_buffer[i+1][j];
  362. patch_vertex& c = patch_vertex_buffer[i ][j+1];
  363. patch_vertex& d = patch_vertex_buffer[i+1][j+1];
  364. auto add_ntb = [](auto& a, auto& b, auto& c)
  365. {
  366. const float3 ba = b.position - a.position;
  367. const float3 ca = c.position - a.position;
  368. const float2 uvba = b.uv - a.uv;
  369. const float2 uvca = c.uv - a.uv;
  370. const float3 normal = math::normalize(math::cross(ba, ca));
  371. const float f = 1.0f / (uvba.x() * uvca.y() - uvca.x() * uvba.y());
  372. const float3 tangent = (ba * uvca.y() - ca * uvba.y()) * f;
  373. const float3 bitangent = (ba * -uvca.x() + ca * uvba.x()) * f;
  374. a.normal += normal;
  375. a.tangent += tangent;
  376. a.bitangent += bitangent;
  377. b.normal += normal;
  378. b.tangent += tangent;
  379. b.bitangent += bitangent;
  380. c.normal += normal;
  381. c.tangent += tangent;
  382. c.bitangent += bitangent;
  383. };
  384. if ((j + i) % 2)
  385. {
  386. add_ntb(a, b, c);
  387. add_ntb(c, b, d);
  388. }
  389. else
  390. {
  391. add_ntb(a, b, d);
  392. add_ntb(a, d, c);
  393. }
  394. }
  395. }
  396. // Finalize normals, tangents, and bitangent signs of patch vertices
  397. for (std::size_t i = 1; i < patch_vertex_buffer.size() - 1; ++i)
  398. {
  399. for (std::size_t j = 1; j < patch_vertex_buffer[i].size() - 1; ++j)
  400. {
  401. auto& vertex = patch_vertex_buffer[i][j];
  402. // Normalize normal
  403. vertex.normal = math::normalize(vertex.normal);
  404. // Gram-Schmidt orthogonalize tangent
  405. vertex.tangent = math::normalize(vertex.tangent - vertex.normal * math::dot(vertex.normal, vertex.tangent));
  406. // Calculate bitangent sign
  407. vertex.bitangent_sign = std::copysign(1.0f, math::dot(math::cross(vertex.normal, vertex.tangent), vertex.bitangent));
  408. }
  409. }
  410. /*
  411. 0 subdivisions:
  412. +---+---+---+
  413. | |
  414. + +---+ +
  415. | | | |
  416. + +---+ +
  417. | |
  418. +---+---+---+
  419. 1 subdivision:
  420. +---+---+---+---+
  421. | |
  422. + +---+---+ +
  423. | | | | |
  424. + +---+---+ +
  425. | | | | |
  426. + +---+---+ +
  427. | |
  428. +---+---+---+---+
  429. 2 subdivisions:
  430. +---+---+---+---+---+
  431. | |
  432. + +---+---+---+ +
  433. | | | | | |
  434. + +---+---+---+ +
  435. | | | | | |
  436. + +---+---+---+ +
  437. | | | | | |
  438. + +---+---+---+ +
  439. | |
  440. +---+---+---+---+---+
  441. */
  442. // For each row
  443. float* v = patch_vertex_data;
  444. for (std::size_t i = 1; i < patch_vertex_buffer.size() - 2; ++i)
  445. {
  446. // For each column
  447. for (std::size_t j = 1; j < patch_vertex_buffer[i].size() - 2; ++j)
  448. {
  449. // a---c
  450. // | |
  451. // b---d
  452. const patch_vertex& a = patch_vertex_buffer[i ][j];
  453. const patch_vertex& b = patch_vertex_buffer[i+1][j];
  454. const patch_vertex& c = patch_vertex_buffer[i ][j+1];
  455. const patch_vertex& d = patch_vertex_buffer[i+1][j+1];
  456. auto add_triangle = [&v](const patch_vertex& a, const patch_vertex& b, const patch_vertex& c)
  457. {
  458. auto add_vertex = [&v](const patch_vertex& vertex, const float3& barycentric)
  459. {
  460. // Position
  461. *(v++) = vertex.position[0];
  462. *(v++) = vertex.position[1];
  463. *(v++) = vertex.position[2];
  464. // UV
  465. *(v++) = vertex.uv[0];
  466. *(v++) = vertex.uv[1];
  467. // Normal
  468. *(v++) = vertex.normal[0];
  469. *(v++) = vertex.normal[1];
  470. *(v++) = vertex.normal[2];
  471. /// Tangent
  472. *(v++) = vertex.tangent[0];
  473. *(v++) = vertex.tangent[1];
  474. *(v++) = vertex.tangent[2];
  475. *(v++) = vertex.bitangent_sign;
  476. // Barycentric
  477. *(v++) = barycentric[0];
  478. *(v++) = barycentric[1];
  479. *(v++) = barycentric[2];
  480. // Morph target (LOD transition)
  481. *(v++) = 0.0f;
  482. *(v++) = 0.0f;
  483. *(v++) = 0.0f;
  484. };
  485. add_vertex(a, float3{1, 0, 0});
  486. add_vertex(b, float3{0, 1, 0});
  487. add_vertex(c, float3{0, 0, 1});
  488. };
  489. if ((j + i) % 2)
  490. {
  491. add_triangle(a, b, c);
  492. add_triangle(c, b, d);
  493. }
  494. else
  495. {
  496. add_triangle(a, b, d);
  497. add_triangle(a, d, c);
  498. }
  499. }
  500. }
  501. // Allocate patch model
  502. ::render::model* patch_model = new ::render::model();
  503. // Get model VBO and VAO
  504. gl::vertex_buffer* vbo = patch_model->get_vertex_buffer();
  505. gl::vertex_array* vao = patch_model->get_vertex_array();
  506. // Resize model VBO and upload vertex data
  507. vbo->resize(patch_triangle_count * 3 * patch_vertex_stride, patch_vertex_data);
  508. std::size_t attribute_offset = 0;
  509. // Define position vertex attribute
  510. gl::vertex_attribute position_attribute;
  511. position_attribute.buffer = vbo;
  512. position_attribute.offset = attribute_offset;
  513. position_attribute.stride = patch_vertex_stride;
  514. position_attribute.type = gl::vertex_attribute_type::float_32;
  515. position_attribute.components = 3;
  516. attribute_offset += position_attribute.components * sizeof(float);
  517. // Define UV vertex attribute
  518. gl::vertex_attribute uv_attribute;
  519. uv_attribute.buffer = vbo;
  520. uv_attribute.offset = attribute_offset;
  521. uv_attribute.stride = patch_vertex_stride;
  522. uv_attribute.type = gl::vertex_attribute_type::float_32;
  523. uv_attribute.components = 2;
  524. attribute_offset += uv_attribute.components * sizeof(float);
  525. // Define normal vertex attribute
  526. gl::vertex_attribute normal_attribute;
  527. normal_attribute.buffer = vbo;
  528. normal_attribute.offset = attribute_offset;
  529. normal_attribute.stride = patch_vertex_stride;
  530. normal_attribute.type = gl::vertex_attribute_type::float_32;
  531. normal_attribute.components = 3;
  532. attribute_offset += normal_attribute.components * sizeof(float);
  533. // Define tangent vertex attribute
  534. gl::vertex_attribute tangent_attribute;
  535. tangent_attribute.buffer = vbo;
  536. tangent_attribute.offset = attribute_offset;
  537. tangent_attribute.stride = patch_vertex_stride;
  538. tangent_attribute.type = gl::vertex_attribute_type::float_32;
  539. tangent_attribute.components = 4;
  540. attribute_offset += tangent_attribute.components * sizeof(float);
  541. // Define barycentric vertex attribute
  542. gl::vertex_attribute barycentric_attribute;
  543. barycentric_attribute.buffer = vbo;
  544. barycentric_attribute.offset = attribute_offset;
  545. barycentric_attribute.stride = patch_vertex_stride;
  546. barycentric_attribute.type = gl::vertex_attribute_type::float_32;
  547. barycentric_attribute.components = 3;
  548. attribute_offset += barycentric_attribute.components * sizeof(float);
  549. // Define target vertex attribute
  550. gl::vertex_attribute target_attribute;
  551. target_attribute.buffer = vbo;
  552. target_attribute.offset = attribute_offset;
  553. target_attribute.stride = patch_vertex_stride;
  554. target_attribute.type = gl::vertex_attribute_type::float_32;
  555. target_attribute.components = 3;
  556. attribute_offset += target_attribute.components * sizeof(float);
  557. // Bind vertex attributes to VAO
  558. vao->bind(::render::vertex_attribute::position, position_attribute);
  559. vao->bind(::render::vertex_attribute::uv, uv_attribute);
  560. vao->bind(::render::vertex_attribute::normal, normal_attribute);
  561. vao->bind(::render::vertex_attribute::tangent, tangent_attribute);
  562. vao->bind(::render::vertex_attribute::barycentric, barycentric_attribute);
  563. vao->bind(::render::vertex_attribute::target, target_attribute);
  564. // Create model group
  565. ::render::model_group* patch_model_group = patch_model->add_group("terrain");
  566. patch_model_group->set_material(patch_material);
  567. patch_model_group->set_drawing_mode(gl::drawing_mode::triangles);
  568. patch_model_group->set_start_index(0);
  569. patch_model_group->set_index_count(patch_triangle_count * 3);
  570. // Set patch model bounds
  571. patch_model->set_bounds(patch_bounds);
  572. //std::cout << "depth: " << quadtree_type::depth(node) << "; size: " << (patch_bounds.max_point + patch_bounds.min_point) * 0.5f << std::endl;
  573. return patch_model;
  574. }
  575. terrain::patch* terrain::generate_patch(quadtree_node_type node)
  576. {
  577. patch* node_patch = new patch();
  578. node_patch->mesh = nullptr;//generate_patch_mesh(node);
  579. node_patch->model = generate_patch_model(node);
  580. node_patch->model_instance = new scene::model_instance(node_patch->model);
  581. return node_patch;
  582. }
  583. } // namespace system
  584. } // namespace game