📄 ogreopcodeterraindata.cpp
字号:
#include "OgreOpcodeTerrainData.h"
#include "OgreCollisionManager.h"
namespace OgreOpcode
{
TerrainData::TerrainData(const std::vector<float>& HeightmapData, size_t Width, size_t Depth, Ogre::Vector3 Scale, Ogre::Vector3 Offset) :
mWidth(Width),
mDepth(Depth),
mScale(Scale),
mOffset(Offset)
{
mHeightmapData = &HeightmapData;
mTileShapes.clear();
}
TerrainData::~TerrainData()
{
}
std::vector<OgreOpcode::PtrCollisionShape*>* TerrainData::createTileShapes(unsigned int numTilesX, unsigned int numTilesZ)
{
if(!mTileShapes.empty()) return NULL;
// enforcing number of x and z tiles to be greater than zero, and also a power of 2: 2, 4, 8, 16, etc.
if( (numTilesX <= 0) || !Details::powerOf2(numTilesX) ) return NULL;
if( (numTilesZ <= 0) || !Details::powerOf2(numTilesZ) ) return NULL;
// calculate the number of vertices for each tile,
// for both x direction (in 3d space) verts, and z direction (in 3d space) verts
unsigned int xTileSize = ((mWidth - 1) / numTilesX) + 1;
unsigned int zTileSize = ((mDepth - 1) / numTilesZ) + 1;
//Create indices - ever 3 indices represent a triangle. 6 indices represent a quad.
size_t index_size = (xTileSize - 1) * (zTileSize -1) * 6;
// create buffer to store computed indices
size_t* indices = new unsigned int[index_size*3];
for( size_t x = 0; x < xTileSize - 1; x++)
{
for( size_t y=0; y < zTileSize - 1; y++)
{
// Define/Store indices that are used to create triangles.
// The indices are used along with the list of vertices to define triangles.
// Indices 0, 1, 2, for example, would create a line from vert[0] -> vert[1], vert[1] -> vert[2], vert[2] -> vert[0].
// The example triangle would look like a line. (not your typical triangle)
// xTileSize comes in because each horizontal strip of vertices consists of exactly xTileSize vertices.
// In this way, you can add a z element to the triangle. (actually looks like a triangle in 3 dimensions)
// The idea here is to go across each row and build up each quad. (2 triangles)
// Each quad is a square that gets split into two polygons.
// Below is a diagram of one tile where pX represents a vertex.
//
// p0 --- p1
// . / .
// p2 --- p3
//
// An example of a counter-clockwise polygon would be: p0 -> p1 -> p2
// An example of a clockwise polygon would be: p1 -> p3 -> p2
// Note1: note that I said "An example".
// **** You can use any order, but the indexing needs to match your vert list!!! ****
// Note2: depending on how you define your indices, you can control how the quad looks! (Important)
// p0 --- p1
// . \ .
// p2 --- p3
// triangle1: counter clockwise winding. p3 -> p1 -> p0
indices[(x+y*(xTileSize-1))*6] = (x+1)+(y+1) * xTileSize;
indices[(x+y*(xTileSize-1))*6+1] = (x+1)+y * xTileSize;
indices[(x+y*(xTileSize-1))*6+2] = x+y * xTileSize;
// triangle2: counter clockwise winding. p3 -> p0 -> p2
indices[(x+y*(xTileSize-1))*6+3] = (x+1)+(y+1) * xTileSize;
indices[(x+y*(xTileSize-1))*6+4] = x+y * xTileSize;
indices[(x+y*(xTileSize-1))*6+5] = x+(y+1) * xTileSize;
}
}
int tileCounter = 0;
// Loop through all tiles
for ( unsigned int zIndex = 0; zIndex < numTilesZ; ++zIndex )
{
for ( unsigned int xIndex = 0; xIndex < numTilesX; ++xIndex )
{
int numVertsPerTile = xTileSize * zTileSize;
float* OOData = new float[numVertsPerTile * 3];
int OODataCounter = 0;
int zStart = zIndex * (zTileSize - 1);
int xStart = xIndex * (xTileSize - 1);
for( unsigned int col = zStart; col < (zStart + zTileSize); ++col)
{
for( unsigned int row = xStart; row < (xStart + xTileSize); ++row)
{
Ogre::Vector3 v3(
mOffset.x + (row * mScale.x),
mOffset.y + (at(row,col) * mScale.y),
mOffset.z + (col * mScale.z)
);
OOData[OODataCounter + 0] = v3.x;
OOData[OODataCounter + 1] = v3.y;
OOData[OODataCounter + 2] = v3.z;
OODataCounter += 3;
}
}
OgreOpcode::PtrCollisionShape* tempTerrainShape;
Ogre::String shapeName = "terrainShape" + Ogre::StringConverter::toString(tileCounter++);
tempTerrainShape = CollisionManager::getSingletonPtr()->createPtrCollisionShape(shapeName);
tempTerrainShape->load(numVertsPerTile*3, index_size, OOData, indices);
mTileShapes.push_back(tempTerrainShape);
delete[] OOData;
}
}
delete[] indices;
indices = NULL;
return &mTileShapes;
}
size_t TerrainData::getDepth()
{
return mDepth;
}
Ogre::Vector3 TerrainData::getOffset()
{
return mOffset;
}
Ogre::Vector3 TerrainData::getScale()
{
return mScale;
}
size_t TerrainData::getWidth()
{
return mWidth;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -