TerrainPatchData::TerrainPatchData(TerrainQuadtree* tree) : tree(tree), tessellation(tree->getPlanetarySurface()->getTessellation()), vertices(tessellation + 3, std::vector<Ogre::Vector3>(tessellation + 3)), normals(tessellation + 3, std::vector<Ogre::Vector3>(tessellation + 3)), heights(tessellation + 3, std::vector<Ogre::Real>(tessellation + 3, 0.0)) { int patchSize = tree->getSize(); Ogre::Real halfPatchSize = Ogre::Real(patchSize / 2); Ogre::Real delta = (Ogre::Real)patchSize * (1.0 / (Ogre::Real)tessellation); Ogre::SceneNode* patchSceneNode = tree->getSceneNode(); Ogre::SceneNode* planetarySceneNode = tree->getPlanetarySurface()->getSceneNode(); Ogre::Real planetaryRadius = (Ogre::Real)tree->getPlanetarySurface()->getRadius(); for (int z = -1; z < tessellation + 2; ++z) { for (int x = -1; x < tessellation + 2; ++x) { Ogre::Vector3 position(-halfPatchSize + delta * x, 0.0, -halfPatchSize + delta * z); Ogre::Vector3 planetaryPosition = planetarySceneNode->convertWorldToLocalPosition(patchSceneNode->convertLocalToWorldPosition(position)); planetaryPosition = mapToSphere(planetaryPosition, planetaryRadius); Ogre::Vector3 normal = planetaryPosition.normalisedCopy(); Ogre::Real height = tree->getPlanetarySurface()->getNoiseFunction()->getValue(planetaryPosition); planetaryPosition = planetarySceneNode->convertLocalToWorldPosition(planetaryPosition); position = patchSceneNode->convertWorldToLocalPosition(planetaryPosition); normal = (tree->getRootSceneNode()->getOrientation().Inverse() * normal).normalisedCopy(); vertices[z + 1][x + 1] = position; normals[z + 1][x + 1] = normal; heights[z + 1][x + 1] = height; } } for (int z = 0; z < tessellation + 1; ++z) { for (int x = 0; x < tessellation + 1; ++x) { processedPositions.push_back(getVertex(x, z)); processedNormals.push_back(getVertexNormal(x, z)); processedTextureCoords.push_back(getNormal(x, z)); } } // Add triangles. for (int z = 0; z < tessellation; ++z) { int zOffset = z * (tessellation + 1); for (int x = 0; x < tessellation; ++x) { int indices[4] = { zOffset + x, zOffset + x + 1, zOffset + tessellation + 1 + x, zOffset + tessellation + 1 + x + 1 }; processedIndices.push_back(indices[0]); processedIndices.push_back(indices[2]); processedIndices.push_back(indices[1]); processedIndices.push_back(indices[2]); processedIndices.push_back(indices[3]); processedIndices.push_back(indices[1]); } } }