TerrainPatch.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. #include "Base.h"
  2. #include "TerrainPatch.h"
  3. #include "Terrain.h"
  4. #include "MeshPart.h"
  5. #include "Scene.h"
  6. #include "Game.h"
  7. namespace gameplay
  8. {
  9. /**
  10. * @script{ignore}
  11. */
  12. template <class T> T clamp(T value, T min, T max) { return value < min ? min : (value > max ? max : value); }
  13. #define TERRAINPATCH_DIRTY_MATERIAL 1
  14. #define TERRAINPATCH_DIRTY_BOUNDS 2
  15. #define TERRAINPATCH_DIRTY_LEVEL 4
  16. #define TERRAINPATCH_DIRTY_ALL (TERRAINPATCH_DIRTY_MATERIAL | TERRAINPATCH_DIRTY_BOUNDS | TERRAINPATCH_DIRTY_LEVEL)
  17. /**
  18. * Custom material auto-binding resolver for terrain.
  19. * @script{ignore}
  20. */
  21. class TerrainAutoBindingResolver : RenderState::AutoBindingResolver
  22. {
  23. bool resolveAutoBinding(const char* autoBinding, Node* node, MaterialParameter* parameter);
  24. };
  25. static TerrainAutoBindingResolver __autoBindingResolver;
  26. static int __currentPatchIndex = -1;
  27. TerrainPatch::TerrainPatch() :
  28. _terrain(NULL), _row(0), _column(0), _camera(NULL), _level(0), _bits(TERRAINPATCH_DIRTY_ALL)
  29. {
  30. }
  31. TerrainPatch::~TerrainPatch()
  32. {
  33. for (size_t i = 0, count = _levels.size(); i < count; ++i)
  34. {
  35. Level* level = _levels[i];
  36. SAFE_RELEASE(level->model);
  37. SAFE_DELETE(level);
  38. }
  39. while (_layers.size() > 0)
  40. {
  41. deleteLayer(*_layers.begin());
  42. }
  43. if (_camera != NULL)
  44. {
  45. _camera->removeListener(this);
  46. SAFE_RELEASE(_camera);
  47. }
  48. }
  49. TerrainPatch* TerrainPatch::create(Terrain* terrain, unsigned int index,
  50. unsigned int row, unsigned int column,
  51. float* heights, unsigned int width, unsigned int height,
  52. unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
  53. float xOffset, float zOffset,
  54. unsigned int maxStep, float verticalSkirtSize)
  55. {
  56. // Create patch
  57. TerrainPatch* patch = new TerrainPatch();
  58. patch->_terrain = terrain;
  59. patch->_index = index;
  60. patch->_row = row;
  61. patch->_column = column;
  62. // Add patch lods
  63. for (unsigned int step = 1; step <= maxStep; step *= 2)
  64. {
  65. patch->addLOD(heights, width, height, x1, z1, x2, z2, xOffset, zOffset, step, verticalSkirtSize);
  66. }
  67. // Set our bounding box using the base LOD mesh
  68. BoundingBox& bounds = patch->_boundingBox;
  69. bounds.set(patch->_levels[0]->model->getMesh()->getBoundingBox());
  70. return patch;
  71. }
  72. unsigned int TerrainPatch::getMaterialCount() const
  73. {
  74. return _levels.size();
  75. }
  76. Material* TerrainPatch::getMaterial(int index) const
  77. {
  78. if (index == -1)
  79. {
  80. Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
  81. Camera* camera = scene ? scene->getActiveCamera() : NULL;
  82. if (!camera)
  83. {
  84. _level = const_cast<TerrainPatch*>(this)->computeLOD(camera, getBoundingBox(true));
  85. }
  86. else
  87. {
  88. _level = 0;
  89. }
  90. return _levels[_level]->model->getMaterial();
  91. }
  92. return _levels[index]->model->getMaterial();
  93. }
  94. void TerrainPatch::addLOD(float* heights, unsigned int width, unsigned int height,
  95. unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
  96. float xOffset, float zOffset,
  97. unsigned int step, float verticalSkirtSize)
  98. {
  99. // Allocate vertex data for this patch
  100. unsigned int patchWidth;
  101. unsigned int patchHeight;
  102. if (step == 1)
  103. {
  104. patchWidth = (x2 - x1) + 1;
  105. patchHeight = (z2 - z1) + 1;
  106. }
  107. else
  108. {
  109. patchWidth = (x2 - x1) / step + ((x2 - x1) %step == 0 ? 0 : 1) + 1;
  110. patchHeight = (z2 - z1) / step + ((z2 - z1) % step == 0 ? 0 : 1) + 1;
  111. }
  112. if (patchWidth < 2 || patchHeight < 2)
  113. return; // ignore this level, not enough geometry
  114. if (verticalSkirtSize > 0.0f)
  115. {
  116. patchWidth += 2;
  117. patchHeight += 2;
  118. }
  119. unsigned int vertexCount = patchHeight * patchWidth;
  120. unsigned int vertexElements = _terrain->_normalMap ? 5 : 8; //<x,y,z>[i,j,k]<u,v>
  121. float* vertices = new float[vertexCount * vertexElements];
  122. unsigned int index = 0;
  123. Vector3 min(FLT_MAX, FLT_MAX, FLT_MAX);
  124. Vector3 max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
  125. float stepXScaled = step * _terrain->_localScale.x;
  126. float stepZScaled = step * _terrain->_localScale.z;
  127. bool zskirt = verticalSkirtSize > 0 ? true : false;
  128. for (unsigned int z = z1; ; )
  129. {
  130. bool xskirt = verticalSkirtSize > 0 ? true : false;
  131. for (unsigned int x = x1; ; )
  132. {
  133. GP_ASSERT(index < vertexCount);
  134. float* v = vertices + (index * vertexElements);
  135. index++;
  136. // Compute position - apply the local scale of the terrain into the vertex data
  137. v[0] = (x + xOffset) * _terrain->_localScale.x;
  138. v[1] = computeHeight(heights, width, x, z);
  139. if (xskirt || zskirt)
  140. v[1] -= verticalSkirtSize * _terrain->_localScale.y;
  141. v[2] = (z + zOffset) * _terrain->_localScale.z;
  142. // Update bounding box min/max (don't include vertical skirt vertices in bounding box)
  143. if (!(xskirt || zskirt))
  144. {
  145. if (v[0] < min.x)
  146. min.x = v[0];
  147. if (v[1] < min.y)
  148. min.y = v[1];
  149. if (v[2] < min.z)
  150. min.z = v[2];
  151. if (v[0] > max.x)
  152. max.x = v[0];
  153. if (v[1] > max.y)
  154. max.y = v[1];
  155. if (v[2] > max.z)
  156. max.z = v[2];
  157. }
  158. // Compute normal
  159. if (!_terrain->_normalMap)
  160. {
  161. Vector3 p(v[0], computeHeight(heights, width, x, z), v[2]);
  162. Vector3 w(Vector3(x>=step ? v[0]-stepXScaled : v[0], computeHeight(heights, width, x>=step ? x-step : x, z), v[2]), p);
  163. Vector3 e(Vector3(x<width-step ? v[0]+stepXScaled : v[0], computeHeight(heights, width, x<width-step ? x+step : x, z), v[2]), p);
  164. Vector3 s(Vector3(v[0], computeHeight(heights, width, x, z>=step ? z-step : z), z>=step ? v[2]-stepZScaled : v[2]), p);
  165. Vector3 n(Vector3(v[0], computeHeight(heights, width, x, z<height-step ? z+step : z), z<height-step ? v[2]+stepZScaled : v[2]), p);
  166. Vector3 normals[4];
  167. Vector3::cross(n, w, &normals[0]);
  168. Vector3::cross(w, s, &normals[1]);
  169. Vector3::cross(e, n, &normals[2]);
  170. Vector3::cross(s, e, &normals[3]);
  171. Vector3 normal = -(normals[0] + normals[1] + normals[2] + normals[3]);
  172. normal.normalize();
  173. v[3] = normal.x;
  174. v[4] = normal.y;
  175. v[5] = normal.z;
  176. v += 3;
  177. }
  178. v += 3;
  179. // Compute texture coord
  180. v[0] = (float)x / (width-1);
  181. v[1] = 1.0f - (float)z / (height-1);
  182. if (xskirt)
  183. {
  184. float offset = verticalSkirtSize / width;
  185. v[0] = x == x1 ? v[0]-offset : v[0]+offset;
  186. }
  187. else if (zskirt)
  188. {
  189. float offset = verticalSkirtSize / height;
  190. v[1] = z == z1 ? v[1]-offset : v[1]+offset;
  191. }
  192. if (x == x2)
  193. {
  194. if ((verticalSkirtSize == 0) || xskirt)
  195. break;
  196. else
  197. xskirt = true;
  198. }
  199. else if (xskirt)
  200. {
  201. xskirt = false;
  202. }
  203. else
  204. {
  205. x = std::min(x + step, x2);
  206. }
  207. }
  208. if (z == z2)
  209. {
  210. if ((verticalSkirtSize == 0) || zskirt)
  211. break;
  212. else
  213. zskirt = true;
  214. }
  215. else if (zskirt)
  216. {
  217. zskirt = false;
  218. }
  219. else
  220. {
  221. z = std::min(z + step, z2);
  222. }
  223. }
  224. GP_ASSERT(index == vertexCount);
  225. Vector3 center(min + ((max - min) * 0.5f));
  226. // Create mesh
  227. VertexFormat::Element elements[3];
  228. elements[0] = VertexFormat::Element(VertexFormat::POSITION, 3);
  229. if (_terrain->_normalMap)
  230. {
  231. elements[1] = VertexFormat::Element(VertexFormat::TEXCOORD0, 2);
  232. }
  233. else
  234. {
  235. elements[1] = VertexFormat::Element(VertexFormat::NORMAL, 3);
  236. elements[2] = VertexFormat::Element(VertexFormat::TEXCOORD0, 2);
  237. }
  238. VertexFormat format(elements, _terrain->_normalMap ? 2 : 3);
  239. Mesh* mesh = Mesh::createMesh(format, vertexCount);
  240. mesh->setVertexData(vertices);
  241. mesh->setBoundingBox(BoundingBox(min, max));
  242. mesh->setBoundingSphere(BoundingSphere(center, center.distance(max)));
  243. // Add mesh part for indices
  244. unsigned int indexCount =
  245. (patchWidth * 2) * // # indices per row of tris
  246. (patchHeight - 1) + // # rows of tris
  247. (patchHeight-2) * 2; // # degenerate tris
  248. // Support a maximum number of indices of USHRT_MAX. Any more indices we will require breaking up the
  249. // terrain into smaller patches.
  250. if (indexCount > USHRT_MAX)
  251. {
  252. GP_WARN("Index count of %d for terrain patch exceeds the limit of 65535. Please specifiy a smaller patch size.", indexCount);
  253. GP_ASSERT(indexCount <= USHRT_MAX);
  254. }
  255. MeshPart* part = mesh->addPart(Mesh::TRIANGLE_STRIP, Mesh::INDEX16, indexCount);
  256. unsigned short* indices = new unsigned short[indexCount];
  257. index = 0;
  258. for (unsigned int z = 0; z < patchHeight-1; ++z)
  259. {
  260. unsigned int i1 = z * patchWidth;
  261. unsigned int i2 = (z+1) * patchWidth;
  262. // Move left to right for even rows and right to left for odd rows.
  263. // Note that this results in two degenerate triangles between rows
  264. // for stitching purposes, but actually does not require any extra
  265. // indices to achieve this.
  266. if (z % 2 == 0)
  267. {
  268. if (z > 0)
  269. {
  270. // Add degenerate indices to connect strips
  271. indices[index] = indices[index-1];
  272. ++index;
  273. indices[index++] = i1;
  274. }
  275. // Add row strip
  276. for (unsigned int x = 0; x < patchWidth; ++x)
  277. {
  278. indices[index++] = i1 + x;
  279. indices[index++] = i2 + x;
  280. }
  281. }
  282. else
  283. {
  284. // Add degenerate indices to connect strips
  285. if (z > 0)
  286. {
  287. indices[index] = indices[index-1];
  288. ++index;
  289. indices[index++] = i2 + ((int)patchWidth-1);
  290. }
  291. // Add row strip
  292. for (int x = (int)patchWidth-1; x >= 0; --x)
  293. {
  294. indices[index++] = i2 + x;
  295. indices[index++] = i1 + x;
  296. }
  297. }
  298. }
  299. GP_ASSERT(index == indexCount);
  300. part->setIndexData(indices, 0, indexCount);
  301. SAFE_DELETE_ARRAY(vertices);
  302. SAFE_DELETE_ARRAY(indices);
  303. // Create model
  304. Model* model = Model::create(mesh);
  305. mesh->release();
  306. // Add this level
  307. Level* level = new Level();
  308. level->model = model;
  309. _levels.push_back(level);
  310. }
  311. void TerrainPatch::deleteLayer(Layer* layer)
  312. {
  313. // Release layer samplers
  314. if (layer->textureIndex != -1)
  315. {
  316. if (_samplers[layer->textureIndex]->getRefCount() == 1)
  317. {
  318. SAFE_RELEASE(_samplers[layer->textureIndex]);
  319. }
  320. else
  321. {
  322. _samplers[layer->textureIndex]->release();
  323. }
  324. }
  325. if (layer->blendIndex != -1)
  326. {
  327. if (_samplers[layer->blendIndex]->getRefCount() == 1)
  328. {
  329. SAFE_RELEASE(_samplers[layer->blendIndex]);
  330. }
  331. else
  332. {
  333. _samplers[layer->blendIndex]->release();
  334. }
  335. }
  336. _layers.erase(layer);
  337. SAFE_DELETE(layer);
  338. }
  339. int TerrainPatch::addSampler(const char* path)
  340. {
  341. // TODO: Support shared samplers stored in Terrain class for layers that span all patches
  342. // on the terrain (row == col == -1).
  343. // Load the texture. If this texture is already loaded, it will return
  344. // a pointer to the same one, with its ref count incremented.
  345. Texture* texture = Texture::create(path, true);
  346. if (!texture)
  347. return -1;
  348. // Textures should only be 2D
  349. if (texture->getType() != Texture::TEXTURE_2D)
  350. {
  351. SAFE_RELEASE(texture);
  352. return -1;
  353. }
  354. int firstAvailableIndex = -1;
  355. for (size_t i = 0, count = _samplers.size(); i < count; ++i)
  356. {
  357. Texture::Sampler* sampler = _samplers[i];
  358. if (sampler == NULL && firstAvailableIndex == -1)
  359. {
  360. firstAvailableIndex = (int)i;
  361. }
  362. else if (sampler->getTexture() == texture)
  363. {
  364. // A sampler was already added for this texture.
  365. // Increase the ref count for the sampler to indicate that a new
  366. // layer will be referencing it.
  367. texture->release();
  368. sampler->addRef();
  369. return (int)i;
  370. }
  371. }
  372. // Add a new sampler to the list
  373. Texture::Sampler* sampler = Texture::Sampler::create(texture);
  374. texture->release();
  375. // This may need to be clamp in some cases to prevent edge bleeding? Possibly a
  376. // configuration variable in the future.
  377. sampler->setWrapMode(Texture::REPEAT, Texture::REPEAT);
  378. sampler->setFilterMode(Texture::LINEAR_MIPMAP_LINEAR, Texture::LINEAR);
  379. if (firstAvailableIndex != -1)
  380. {
  381. _samplers[firstAvailableIndex] = sampler;
  382. return firstAvailableIndex;
  383. }
  384. _samplers.push_back(sampler);
  385. return (int)(_samplers.size()-1);
  386. }
  387. bool TerrainPatch::setLayer(int index, const char* texturePath, const Vector2& textureRepeat, const char* blendPath, int blendChannel)
  388. {
  389. // If there is an existing layer at this index, delete it
  390. for (std::set<Layer*, LayerCompare>::iterator itr = _layers.begin(); itr != _layers.end(); ++itr)
  391. {
  392. Layer* layer = *itr;
  393. if (layer->index == index)
  394. {
  395. deleteLayer(layer);
  396. break;
  397. }
  398. }
  399. // Load texture sampler
  400. int textureIndex = addSampler(texturePath);
  401. if (textureIndex == -1)
  402. return false;
  403. // Load blend sampler
  404. int blendIndex = -1;
  405. if (blendPath)
  406. {
  407. blendIndex = addSampler(blendPath);
  408. }
  409. // Create the layer
  410. Layer* layer = new Layer();
  411. layer->index = index;
  412. layer->textureIndex = textureIndex;
  413. layer->textureRepeat = textureRepeat;
  414. layer->blendIndex = blendIndex;
  415. layer->blendChannel = blendChannel;
  416. _layers.insert(layer);
  417. _bits |= TERRAINPATCH_DIRTY_MATERIAL;
  418. return true;
  419. }
  420. std::string TerrainPatch::passCallback(Pass* pass, void* cookie)
  421. {
  422. TerrainPatch* patch = reinterpret_cast<TerrainPatch*>(cookie);
  423. GP_ASSERT(patch);
  424. return patch->passCreated(pass);
  425. }
  426. std::string TerrainPatch::passCreated(Pass* pass)
  427. {
  428. // Build preprocessor string to be passed to the terrain shader.
  429. // NOTE: I make heavy use of preprocessor definitions, rather than passing in arrays and doing
  430. // non-constant array access in the shader. This is due to the fact that non-constant array access
  431. // in GLES is very slow on some hardware.
  432. std::ostringstream defines;
  433. defines << "LAYER_COUNT " << _layers.size();
  434. defines << ";SAMPLER_COUNT " << _samplers.size();
  435. if (_terrain->isFlagSet(Terrain::DEBUG_PATCHES))
  436. {
  437. defines << ";DEBUG_PATCHES";
  438. pass->getParameter("u_row")->setFloat(_row);
  439. pass->getParameter("u_column")->setFloat(_column);
  440. }
  441. if (_terrain->_normalMap)
  442. defines << ";NORMAL_MAP";
  443. // Append texture and blend index constants to preprocessor definition.
  444. // We need to do this since older versions of GLSL only allow sampler arrays
  445. // to be indexed using constant expressions (otherwise we could simply pass an
  446. // array of indices to use for sampler lookup).
  447. //
  448. // Rebuild layer lists while we're at it.
  449. //
  450. int layerIndex = 0;
  451. for (std::set<Layer*, LayerCompare>::iterator itr = _layers.begin(); itr != _layers.end(); ++itr, ++layerIndex)
  452. {
  453. Layer* layer = *itr;
  454. defines << ";TEXTURE_INDEX_" << layerIndex << " " << layer->textureIndex;
  455. defines << ";TEXTURE_REPEAT_" << layerIndex << " vec2(" << layer->textureRepeat.x << "," << layer->textureRepeat.y << ")";
  456. if (layerIndex > 0)
  457. {
  458. defines << ";BLEND_INDEX_" << layerIndex << " " << layer->blendIndex;
  459. defines << ";BLEND_CHANNEL_" << layerIndex << " " << layer->blendChannel;
  460. }
  461. }
  462. return defines.str();
  463. }
  464. bool TerrainPatch::updateMaterial()
  465. {
  466. if (!(_bits & TERRAINPATCH_DIRTY_MATERIAL))
  467. return true;
  468. _bits &= ~TERRAINPATCH_DIRTY_MATERIAL;
  469. __currentPatchIndex = _index;
  470. for (size_t i = 0, count = _levels.size(); i < count; ++i)
  471. {
  472. Material* material = Material::create(_terrain->_materialPath.c_str(), &passCallback, this);
  473. GP_ASSERT(material);
  474. if (!material)
  475. {
  476. GP_WARN("Failed to load material for terrain patch: %s", _terrain->_materialPath.c_str());
  477. __currentPatchIndex = -1;
  478. return false;
  479. }
  480. material->setNodeBinding(_terrain->_node);
  481. // Set material on this lod level
  482. _levels[i]->model->setMaterial(material);
  483. material->release();
  484. }
  485. __currentPatchIndex = -1;
  486. return true;
  487. }
  488. void TerrainPatch::updateNodeBindings()
  489. {
  490. __currentPatchIndex = _index;
  491. for (size_t i = 0, count = _levels.size(); i < count; ++i)
  492. {
  493. _levels[i]->model->getMaterial()->setNodeBinding(_terrain->_node);
  494. }
  495. __currentPatchIndex = -1;
  496. }
  497. unsigned int TerrainPatch::draw(bool wireframe)
  498. {
  499. Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
  500. Camera* camera = scene ? scene->getActiveCamera() : NULL;
  501. if (!camera)
  502. return 0;
  503. // Get our world-space bounding box
  504. BoundingBox bounds = getBoundingBox(true);
  505. // If the box does not intersect the view frustum, cull it
  506. if (_terrain->isFlagSet(Terrain::FRUSTUM_CULLING) && !camera->getFrustum().intersects(bounds))
  507. return 0;
  508. if (!updateMaterial())
  509. return 0;
  510. // Compute the LOD level from the camera's perspective
  511. _level = computeLOD(camera, bounds);
  512. // Draw the model for the current LOD
  513. return _levels[_level]->model->draw(wireframe);
  514. }
  515. const BoundingBox& TerrainPatch::getBoundingBox(bool worldSpace) const
  516. {
  517. if (!worldSpace)
  518. return _boundingBox;
  519. if (!(_bits & TERRAINPATCH_DIRTY_BOUNDS))
  520. return _boundingBoxWorld;
  521. _bits &= ~TERRAINPATCH_DIRTY_BOUNDS;
  522. // Apply a world-space transformation to our bounding box
  523. _boundingBoxWorld.set(_boundingBox);
  524. // Transform the bounding box by the terrain node's world transform.
  525. if (_terrain->_node)
  526. _boundingBoxWorld.transform(_terrain->_node->getWorldMatrix());
  527. return _boundingBoxWorld;
  528. }
  529. void TerrainPatch::cameraChanged(Camera* camera)
  530. {
  531. _bits |= TERRAINPATCH_DIRTY_LEVEL;
  532. }
  533. unsigned int TerrainPatch::computeLOD(Camera* camera, const BoundingBox& worldBounds)
  534. {
  535. if (camera != _camera)
  536. {
  537. if (_camera != NULL)
  538. {
  539. _camera->removeListener(this);
  540. _camera->release();
  541. }
  542. _camera = camera;
  543. _camera->addRef();
  544. _camera->addListener(this);
  545. _bits |= TERRAINPATCH_DIRTY_LEVEL;
  546. }
  547. // base level
  548. if (!_terrain->isFlagSet(Terrain::LEVEL_OF_DETAIL) || _levels.size() == 0)
  549. return 0;
  550. if (!(_bits & TERRAINPATCH_DIRTY_LEVEL))
  551. return _level;
  552. _bits &= ~TERRAINPATCH_DIRTY_LEVEL;
  553. // Compute LOD to use based on very simple distance metric. TODO: Optimize me.
  554. Game* game = Game::getInstance();
  555. Rectangle vp(0, 0, game->getWidth(), game->getHeight());
  556. Vector3 corners[8];
  557. Vector2 min(FLT_MAX, FLT_MAX);
  558. Vector2 max(-FLT_MAX, -FLT_MAX);
  559. worldBounds.getCorners(corners);
  560. for (unsigned int i = 0; i < 8; ++i)
  561. {
  562. const Vector3& corner = corners[i];
  563. float x, y;
  564. camera->project(vp, corners[i], &x, &y);
  565. if (x < min.x)
  566. min.x = x;
  567. if (y < min.y)
  568. min.y = y;
  569. if (x > max.x)
  570. max.x = x;
  571. if (y > max.y)
  572. max.y = y;
  573. }
  574. float area = (max.x - min.x) * (max.y - min.y);
  575. float screenArea = game->getWidth() * game->getHeight() / 10.0f;
  576. float error = screenArea / area;
  577. // Level LOD based on distance from camera
  578. size_t maxLod = _levels.size()-1;
  579. size_t lod = (size_t)error;
  580. lod = std::max(lod, (size_t)0);
  581. lod = std::min(lod, maxLod);
  582. _level = lod;
  583. return _level;
  584. }
  585. const Vector3& TerrainPatch::getAmbientColor() const
  586. {
  587. Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
  588. return scene ? scene->getAmbientColor() : Vector3::zero();
  589. }
  590. void TerrainPatch::setMaterialDirty()
  591. {
  592. _bits |= TERRAINPATCH_DIRTY_MATERIAL;
  593. }
  594. float TerrainPatch::computeHeight(float* heights, unsigned int width, unsigned int x, unsigned int z)
  595. {
  596. return heights[z * width + x] * _terrain->_localScale.y;
  597. }
  598. TerrainPatch::Layer::Layer() :
  599. index(0), row(-1), column(-1), textureIndex(-1), blendIndex(-1)
  600. {
  601. }
  602. TerrainPatch::Layer::~Layer()
  603. {
  604. }
  605. TerrainPatch::Level::Level() : model(NULL)
  606. {
  607. }
  608. bool TerrainPatch::LayerCompare::operator() (const Layer* lhs, const Layer* rhs) const
  609. {
  610. return (lhs->index < rhs->index);
  611. }
  612. bool TerrainAutoBindingResolver::resolveAutoBinding(const char* autoBinding, Node* node, MaterialParameter* parameter)
  613. {
  614. // Local helper functions
  615. struct HelperFunctions
  616. {
  617. static TerrainPatch* getPatch(Node* node)
  618. {
  619. Terrain* terrain = dynamic_cast<Terrain*>(node->getDrawable());
  620. if (terrain)
  621. {
  622. if (__currentPatchIndex >= 0 && __currentPatchIndex < (int)terrain->_patches.size())
  623. {
  624. return terrain->_patches[__currentPatchIndex];
  625. }
  626. }
  627. return NULL;
  628. }
  629. };
  630. if (strcmp(autoBinding, "TERRAIN_LAYER_MAPS") == 0)
  631. {
  632. TerrainPatch* patch = HelperFunctions::getPatch(node);
  633. if (patch && patch->_layers.size() > 0)
  634. parameter->setValue((const Texture::Sampler**)&patch->_samplers[0], (unsigned int)patch->_samplers.size());
  635. return true;
  636. }
  637. else if (strcmp(autoBinding, "TERRAIN_NORMAL_MAP") == 0)
  638. {
  639. Terrain* terrain = dynamic_cast<Terrain*>(node->getDrawable());
  640. if (terrain && terrain->_normalMap)
  641. parameter->setValue(terrain->_normalMap);
  642. return true;
  643. }
  644. else if (strcmp(autoBinding, "TERRAIN_ROW") == 0)
  645. {
  646. TerrainPatch* patch = HelperFunctions::getPatch(node);
  647. if (patch)
  648. parameter->setValue((float)patch->_row);
  649. return true;
  650. }
  651. else if (strcmp(autoBinding, "TERRAIN_COLUMN") == 0)
  652. {
  653. TerrainPatch* patch = HelperFunctions::getPatch(node);
  654. if (patch)
  655. parameter->setValue((float)patch->_column);
  656. return true;
  657. }
  658. return false;
  659. }
  660. }