TerrainPatch.cpp 25 KB

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