void CreateTerrainGeomtry(LevelGeometry &lg) { const int PATCH_SIZE = 64; if (!Terrain) return; PxHeightFieldGeometry g = Terrain->GetHFShape(); const float colScale = g.columnScale; const float rowScale = g.rowScale; const float heightScale = g.heightScale; PxHeightField *physHF = g.heightField; PxU32 nbCols = physHF->getNbColumns(); PxU32 nbRows = physHF->getNbRows(); PxU32 patchCols = static_cast<PxU32>(ceilf(nbCols / static_cast<float>(PATCH_SIZE))); PxU32 patchRows = static_cast<PxU32>(ceilf(nbRows / static_cast<float>(PATCH_SIZE))); lg.meshes.Resize(patchCols * patchRows); lg.meshStartObjectsIdx = lg.meshes.Count(); for (PxU32 pi = 0; pi < patchCols; ++pi) { for (PxU32 pj = 0; pj < patchRows; ++pj) { // Fill patch vertices first. LevelGeometry::Mesh &p = lg.meshes[pi * patchRows + pj]; PxU32 startCol = pi * PATCH_SIZE; PxU32 startRow = pj * PATCH_SIZE; PxU32 endCol = (pi + 1) * PATCH_SIZE; PxU32 endRow = (pj + 1) * PATCH_SIZE; PxU32 w = std::min(endCol - startCol + 1, nbCols - startCol); PxU32 h = std::min(endRow - startRow + 1, nbRows - startRow); p.vertices.Resize(w * h); for(PxU32 i = 0; i < w; ++i) { for(PxU32 j = 0; j < h; ++j) { PxReal x = PxReal(i + startCol); PxReal z = PxReal(j + startRow); PxReal y = physHF->getHeight(x, z) * heightScale; PxU32 idx = i * h + j; p.vertices[idx] = r3dVector(x * colScale, y, z * rowScale); } } // Now triangulate patch const PxU32 nbFaces = (w - 1) * (h - 1) * 2; p.indices.Resize(nbFaces * 3); int * indices = &p.indices.GetFirst(); for (PxU32 i = 0; i < (w - 1); ++i) { for (PxU32 j = 0; j < (h - 1); ++j) { // first triangle uint32_t baseIdx = 6 * (i * (h - 1) + j); indices[baseIdx + 0] = (i + 1) * h + j; indices[baseIdx + 1] = i * h + j; indices[baseIdx + 2] = i * h + j + 1; // second triangle indices[baseIdx + 3] = (i + 1) * h + j + 1; indices[baseIdx + 4] = (i + 1) * h + j; indices[baseIdx + 5] = i * h + j + 1; } } // Filter outside triangles uint32_t indicesCount = gConvexRegionsManager.FilterOutsideTriangles(&p.vertices.GetFirst(), &p.indices.GetFirst(), p.indices.Count()); p.indices.Resize(indicesCount); } } }