LfBulletLargeTerrainModel.h
--------------------------------
#ifndef _H_LFBULLETLARGETERRAIN_MODEL
#define _H_LFBULLETLARGETERRAIN_MODEL
#include "stdafx.h"
#include "Utility.h"
#include <BulletCollision/CollisionShapes/btStridingMeshInterface.h>
#include <BulletCollision/CollisionShapes/btTriangleBuffer.h>
#include <BulletCollision/CollisionShapes/btTriangleMesh.h>
#include <BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h>
#include <BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h>
#include <BulletCollision/CollisionShapes/btTriangleBuffer.h>
#include <lf/Lightfeather.h>
using namespace lf;
class LfBulletLargeTerrainModel : public res::CLargeTerrainModel, res::ITerrainTileLoadListener
{
Utility tk;
btStridingMeshInterface* meshInterface;
btTriangleMesh* physicsTerrain;
btBvhTriangleMeshShape* terrainShape;
btTriangleIndexVertexArray* triArray;
core::vector2d<lf::u16> tile;
core::array<res::CMesh*> tileMeshes;
btVector3 minAabb;
btVector3 maxAabb;
core::aabbox3df bbox;
res::STriangleInfo triInfo;
lf::s32 index;
bool busy;
public:
LfBulletLargeTerrainModel(const core::stringc& name, const c8 *configFileName, scene::CCamera *observer, lf::u16 displayedTiles = 3, lf::f32 recalcDistanceSQ = 100.0f);
~LfBulletLargeTerrainModel();
inline btVector3 GetAabbMin() { return minAabb; }
inline btVector3 GetAabbMax() { return maxAabb; }
inline btBvhTriangleMeshShape* GetTerrainShape() { return terrainShape; }
void tileLoaded(res::CTerrainTileEvent& event);
void tileUnloaded(res::CTerrainTileEvent& event);
void RemoveMeshTriangle( res::CMesh*, const btTriangle& );
};
#endif
LfBulletLargeTerrainModel.cpp
-------------------------------
#include "stdafx.h"
#include "LfBulletLargeTerrainModel.h"
#include <lf/Lightfeather.h>
using namespace lf;
LfBulletLargeTerrainModel::LfBulletLargeTerrainModel(const core::stringc& name, const c8 *configFileName, scene::CCamera *observer, lf::u16 displayedTiles , lf::f32 recalcDistanceSQ )
: res::CLargeTerrainModel(name ,configFileName, observer,displayedTiles, recalcDistanceSQ )
{
tk = Utility();
busy = false;
addTileLoadListener(this);
meshInterface = physicsTerrain = new btTriangleMesh();
triArray = new btTriangleIndexVertexArray();
tileMeshes = core::array<res::CMesh*>();
tileMeshes.reallocate(2 * displayedTiles * displayedTiles);
tileMeshes.set_used(50);
terrainShape = NULL;
}
LfBulletLargeTerrainModel::~LfBulletLargeTerrainModel() { }
void LfBulletLargeTerrainModel::tileLoaded(res::CTerrainTileEvent& e)
{
busy = true;
static int loops = 0;
int numDisplayed = this->getNumDisplayedTiles();
numDisplayed *= numDisplayed;
if(loops < numDisplayed + 1)
{
busy = false;
tileMeshes[loops] = e.getMesh();
loops++;
return; // store up the meshes
}
else
{
loops = 0;
btIndexedMesh iMesh = btIndexedMesh();
res::CVertexFormatDefinition* def = new res::CVertexFormatDefinition(e.getMesh()->getVertexBuffer()->getVertexFormatDefinition() );
res::CVertexBufferI* vertices = new res::CVertexBufferI("terrainVertices",e.getMesh()->getVertexBuffer()->getVertexCount(), def );
res::CIndexBuffer* indices;// = new res::CIndexBuffer();
while(loops < numDisplayed + 1)
{
vertices->copyCommonElements( tileMeshes[loops]->getVertexBuffer() );
indices = tileMeshes[loops]->getIndexBuffer();
iMesh.m_numVertices = vertices->getVertexCount();
iMesh.m_numTriangles = tileMeshes[loops]->getPolygonCount();
iMesh.m_triangleIndexBase = (const unsigned char*) indices->getPointer(true, true);
iMesh.m_triangleIndexStride = sizeof(res::EIDT_16BIT);
iMesh.m_vertexBase = (unsigned char*)vertices->getPointer(res::EVCT_POSITION, 0);
iMesh.m_vertexStride = 0;// vertices->getVertexStride();
triArray->addIndexedMesh(iMesh);
loops++;
} // end while
} // end if
if(terrainShape == NULL) // first run
{
//btTriangleBuffer triBuf = btTriangleBuffer();
meshInterface = triArray;
terrainShape = new btBvhTriangleMeshShape(meshInterface, true, minAabb, maxAabb, false);
//terrainShape->processAllTriangles(&triBuf, btVector3(0, 0, 0), btVector3(1024, 1024, 1024) );
}
}
void LfBulletLargeTerrainModel::tileUnloaded(res::CTerrainTileEvent& event)
{
res::CMesh* tileMesh = event.getMesh();
btTriangleBuffer triBuf;
terrainShape->processAllTriangles(&triBuf,minAabb, maxAabb);
for (int i=0;i<triBuf.getNumTriangles();i++)
{
const btTriangle& tri = triBuf.getTriangle(i);
RemoveMeshTriangle(tileMesh, tri);
}
}
void LfBulletLargeTerrainModel::RemoveMeshTriangle(res::CMesh* mesh, const btTriangle& theTriangle)
{
printf("Tile Unloaded");
}
* A number of variables are there just in case.