Cleanup and some speed improvements.
git-svn-id: http://svn.code.sf.net/p/irrlicht/code/trunk@1440 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
parent
5078125dcc
commit
986a233dbf
@ -24,7 +24,6 @@ COctTreeSceneNode::COctTreeSceneNode(ISceneNode* parent, ISceneManager* mgr,
|
||||
s32 id, s32 minimalPolysPerNode)
|
||||
: ISceneNode(parent, mgr, id), StdOctTree(0), LightMapOctTree(0), TangentsOctTree(0),
|
||||
MinimalPolysPerNode(minimalPolysPerNode)
|
||||
//,Mesh(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("COctTreeSceneNode");
|
||||
@ -34,18 +33,13 @@ COctTreeSceneNode::COctTreeSceneNode(ISceneNode* parent, ISceneManager* mgr,
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! destructor
|
||||
COctTreeSceneNode::~COctTreeSceneNode()
|
||||
{
|
||||
//if (Mesh)
|
||||
// Mesh->drop();
|
||||
|
||||
deleteTree();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void COctTreeSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
if (IsVisible)
|
||||
@ -58,13 +52,13 @@ void COctTreeSceneNode::OnRegisterSceneNode()
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
|
||||
PassCount = 0;
|
||||
int transparentCount = 0;
|
||||
int solidCount = 0;
|
||||
u32 transparentCount = 0;
|
||||
u32 solidCount = 0;
|
||||
|
||||
// count transparent and solid materials in this scene node
|
||||
for (u32 i=0; i<Materials.size(); ++i)
|
||||
{
|
||||
video::IMaterialRenderer* rnd =
|
||||
const video::IMaterialRenderer* const rnd =
|
||||
driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
|
||||
if (rnd && rnd->isTransparent())
|
||||
@ -89,7 +83,6 @@ void COctTreeSceneNode::OnRegisterSceneNode()
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! renders the node.
|
||||
void COctTreeSceneNode::render()
|
||||
{
|
||||
@ -127,15 +120,15 @@ void COctTreeSceneNode::render()
|
||||
//StdOctTree->calculatePolys(box);
|
||||
StdOctTree->calculatePolys(frust);
|
||||
|
||||
OctTree<video::S3DVertex>::SIndexData* d = StdOctTree->getIndexData();
|
||||
const OctTree<video::S3DVertex>::SIndexData* d = StdOctTree->getIndexData();
|
||||
|
||||
for (u32 i=0; i<Materials.size(); ++i)
|
||||
{
|
||||
if ( 0 == d[i].CurrentSize )
|
||||
continue;
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
const bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
@ -149,40 +142,39 @@ void COctTreeSceneNode::render()
|
||||
}
|
||||
|
||||
// for debug purposes only
|
||||
if ( DebugDataVisible && !Materials.empty() && PassCount==1)
|
||||
if (DebugDataVisible && !Materials.empty() && PassCount==1)
|
||||
{
|
||||
const core::aabbox3d<float> &box = frust.getBoundingBox();
|
||||
core::array< core::aabbox3d<f32> > boxes;
|
||||
const core::aabbox3df& box = frust.getBoundingBox();
|
||||
core::array< const core::aabbox3d<f32>* > boxes;
|
||||
video::SMaterial m;
|
||||
m.Lighting = false;
|
||||
driver->setMaterial(m);
|
||||
if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
|
||||
{
|
||||
StdOctTree->renderBoundingBoxes(box, boxes);
|
||||
for (u32 b=0; b<boxes.size(); ++b)
|
||||
driver->draw3DBox(boxes[b], video::SColor(0,255,255,255));
|
||||
StdOctTree->getBoundingBoxes(box, boxes);
|
||||
for (u32 b=0; b!=boxes.size(); ++b)
|
||||
driver->draw3DBox(*boxes[b]);
|
||||
}
|
||||
|
||||
if ( DebugDataVisible & scene::EDS_BBOX )
|
||||
driver->draw3DBox(Box,video::SColor(0,255,0,0));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
{
|
||||
//LightMapOctTree->calculatePolys(box);
|
||||
LightMapOctTree->calculatePolys(frust);
|
||||
|
||||
OctTree<video::S3DVertex2TCoords>::SIndexData* d = LightMapOctTree->getIndexData();
|
||||
const OctTree<video::S3DVertex2TCoords>::SIndexData* d = LightMapOctTree->getIndexData();
|
||||
|
||||
for (u32 i=0; i<Materials.size(); ++i)
|
||||
{
|
||||
if ( 0 == d[i].CurrentSize )
|
||||
continue;
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
const bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
@ -199,15 +191,15 @@ void COctTreeSceneNode::render()
|
||||
if (DebugDataVisible && !Materials.empty() && PassCount==1)
|
||||
{
|
||||
const core::aabbox3d<float> &box = frust.getBoundingBox();
|
||||
core::array< core::aabbox3d<f32> > boxes;
|
||||
core::array< const core::aabbox3d<f32>* > boxes;
|
||||
video::SMaterial m;
|
||||
m.Lighting = false;
|
||||
driver->setMaterial(m);
|
||||
if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
|
||||
{
|
||||
LightMapOctTree->renderBoundingBoxes(box, boxes);
|
||||
LightMapOctTree->getBoundingBoxes(box, boxes);
|
||||
for (u32 b=0; b<boxes.size(); ++b)
|
||||
driver->draw3DBox(boxes[b], video::SColor(0,255,255,255));
|
||||
driver->draw3DBox(*boxes[b]);
|
||||
}
|
||||
|
||||
if ( DebugDataVisible & scene::EDS_BBOX )
|
||||
@ -220,15 +212,15 @@ void COctTreeSceneNode::render()
|
||||
//TangentsOctTree->calculatePolys(box);
|
||||
TangentsOctTree->calculatePolys(frust);
|
||||
|
||||
OctTree<video::S3DVertexTangents>::SIndexData* d = TangentsOctTree->getIndexData();
|
||||
const OctTree<video::S3DVertexTangents>::SIndexData* d = TangentsOctTree->getIndexData();
|
||||
|
||||
for (u32 i=0; i<Materials.size(); ++i)
|
||||
{
|
||||
if ( 0 == d[i].CurrentSize )
|
||||
continue;
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
const bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
@ -245,15 +237,15 @@ void COctTreeSceneNode::render()
|
||||
if (DebugDataVisible && !Materials.empty() && PassCount==1)
|
||||
{
|
||||
const core::aabbox3d<float> &box = frust.getBoundingBox();
|
||||
core::array< core::aabbox3d<f32> > boxes;
|
||||
core::array< const core::aabbox3d<f32>* > boxes;
|
||||
video::SMaterial m;
|
||||
m.Lighting = false;
|
||||
driver->setMaterial(m);
|
||||
if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
|
||||
{
|
||||
TangentsOctTree->renderBoundingBoxes(box, boxes);
|
||||
TangentsOctTree->getBoundingBoxes(box, boxes);
|
||||
for (u32 b=0; b<boxes.size(); ++b)
|
||||
driver->draw3DBox(boxes[b], video::SColor(0,255,255,255));
|
||||
driver->draw3DBox(*boxes[b]);
|
||||
}
|
||||
|
||||
if ( DebugDataVisible & scene::EDS_BBOX )
|
||||
@ -278,12 +270,7 @@ bool COctTreeSceneNode::createTree(IMesh* mesh)
|
||||
if (!mesh)
|
||||
return false;
|
||||
|
||||
//if (Mesh)
|
||||
// Mesh->drop();
|
||||
|
||||
MeshName = SceneManager->getMeshCache()->getMeshFilename( mesh );
|
||||
// Mesh = mesh;
|
||||
// Mesh->grab();
|
||||
|
||||
deleteTree();
|
||||
|
||||
@ -309,25 +296,25 @@ bool COctTreeSceneNode::createTree(IMesh* mesh)
|
||||
{
|
||||
Materials.push_back(b->getMaterial());
|
||||
|
||||
OctTree<video::S3DVertex>::SMeshChunk chunk;
|
||||
chunk.MaterialId = Materials.size() - 1;
|
||||
StdMeshes.push_back(chunk);
|
||||
OctTree<video::S3DVertex>::SMeshChunk &nchunk = StdMeshes[StdMeshes.size()-1];
|
||||
StdMeshes.push_back(OctTree<video::S3DVertex>::SMeshChunk());
|
||||
OctTree<video::S3DVertex>::SMeshChunk &nchunk = StdMeshes.getLast();
|
||||
nchunk.MaterialId = Materials.size() - 1;
|
||||
|
||||
u32 v;
|
||||
|
||||
nchunk.Vertices.reallocate(b->getVertexCount());
|
||||
for (v=0; v<b->getVertexCount(); ++v)
|
||||
nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]);
|
||||
|
||||
polyCount += b->getIndexCount();
|
||||
|
||||
nchunk.Indices.reallocate(b->getIndexCount());
|
||||
for (v=0; v<b->getIndexCount(); ++v)
|
||||
nchunk.Indices.push_back(b->getIndices()[v]);
|
||||
}
|
||||
}
|
||||
|
||||
StdOctTree = new OctTree<video::S3DVertex>(StdMeshes, MinimalPolysPerNode);
|
||||
nodeCount = StdOctTree->nodeCount;
|
||||
nodeCount = StdOctTree->getNodeCount();
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
@ -339,27 +326,24 @@ bool COctTreeSceneNode::createTree(IMesh* mesh)
|
||||
if (b->getVertexCount() && b->getIndexCount())
|
||||
{
|
||||
Materials.push_back(b->getMaterial());
|
||||
|
||||
OctTree<video::S3DVertex2TCoords>::SMeshChunk chunk;
|
||||
chunk.MaterialId = Materials.size() - 1;
|
||||
LightMapMeshes.push_back(chunk);
|
||||
OctTree<video::S3DVertex2TCoords>::SMeshChunk& nchunk =
|
||||
LightMapMeshes[LightMapMeshes.size()-1];
|
||||
LightMapMeshes.push_back(OctTree<video::S3DVertex2TCoords>::SMeshChunk());
|
||||
OctTree<video::S3DVertex2TCoords>::SMeshChunk& nchunk = LightMapMeshes.getLast();
|
||||
nchunk.MaterialId = Materials.size() - 1;
|
||||
|
||||
u32 v;
|
||||
|
||||
nchunk.Vertices.reallocate(b->getVertexCount());
|
||||
for (v=0; v<b->getVertexCount(); ++v)
|
||||
nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]);
|
||||
|
||||
polyCount += b->getIndexCount();
|
||||
|
||||
nchunk.Indices.reallocate(b->getIndexCount());
|
||||
for (v=0; v<b->getIndexCount(); ++v)
|
||||
nchunk.Indices.push_back(b->getIndices()[v]);
|
||||
}
|
||||
}
|
||||
|
||||
LightMapOctTree = new OctTree<video::S3DVertex2TCoords>(LightMapMeshes, MinimalPolysPerNode);
|
||||
nodeCount = LightMapOctTree->nodeCount;
|
||||
nodeCount = LightMapOctTree->getNodeCount();
|
||||
}
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
@ -371,27 +355,24 @@ bool COctTreeSceneNode::createTree(IMesh* mesh)
|
||||
if (b->getVertexCount() && b->getIndexCount())
|
||||
{
|
||||
Materials.push_back(b->getMaterial());
|
||||
|
||||
OctTree<video::S3DVertexTangents>::SMeshChunk chunk;
|
||||
chunk.MaterialId = Materials.size() - 1;
|
||||
TangentsMeshes.push_back(chunk);
|
||||
OctTree<video::S3DVertexTangents>::SMeshChunk& nchunk =
|
||||
TangentsMeshes[TangentsMeshes.size()-1];
|
||||
TangentsMeshes.push_back(OctTree<video::S3DVertexTangents>::SMeshChunk());
|
||||
OctTree<video::S3DVertexTangents>::SMeshChunk& nchunk = TangentsMeshes.getLast();
|
||||
nchunk.MaterialId = Materials.size() - 1;
|
||||
|
||||
u32 v;
|
||||
|
||||
nchunk.Vertices.reallocate(b->getVertexCount());
|
||||
for (v=0; v<b->getVertexCount(); ++v)
|
||||
nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
|
||||
|
||||
polyCount += b->getIndexCount();
|
||||
|
||||
nchunk.Indices.reallocate(b->getIndexCount());
|
||||
for (v=0; v<b->getIndexCount(); ++v)
|
||||
nchunk.Indices.push_back(b->getIndices()[v]);
|
||||
}
|
||||
}
|
||||
|
||||
TangentsOctTree = new OctTree<video::S3DVertexTangents>(TangentsMeshes, MinimalPolysPerNode);
|
||||
nodeCount = TangentsOctTree->nodeCount;
|
||||
nodeCount = TangentsOctTree->getNodeCount();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -420,6 +401,7 @@ video::SMaterial& COctTreeSceneNode::getMaterial(u32 i)
|
||||
return Materials[i];
|
||||
}
|
||||
|
||||
|
||||
//! returns amount of materials used by this scene node.
|
||||
u32 COctTreeSceneNode::getMaterialCount() const
|
||||
{
|
||||
@ -432,50 +414,33 @@ void COctTreeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttribute
|
||||
{
|
||||
ISceneNode::serializeAttributes(out, options);
|
||||
|
||||
out->addInt ("MinimalPolysPerNode", MinimalPolysPerNode);
|
||||
//out->addString("Mesh", SceneManager->getMeshCache()->getMeshFilename(Mesh));
|
||||
out->addInt("MinimalPolysPerNode", MinimalPolysPerNode);
|
||||
out->addString("Mesh", MeshName.c_str());
|
||||
}
|
||||
|
||||
|
||||
//! Reads attributes of the scene node.
|
||||
void COctTreeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
|
||||
{
|
||||
int oldMinimal = MinimalPolysPerNode;
|
||||
//core::stringc oldMeshStr = SceneManager->getMeshCache()->getMeshFilename(Mesh);
|
||||
core::stringc oldMeshStr = MeshName;
|
||||
const s32 oldMinimal = MinimalPolysPerNode;
|
||||
|
||||
MinimalPolysPerNode = in->getAttributeAsInt("MinimalPolysPerNode");
|
||||
core::stringc newMeshStr = in->getAttributeAsString("Mesh");
|
||||
|
||||
bool loadedNewMesh = false;
|
||||
|
||||
IMesh* newMesh = 0;
|
||||
|
||||
if (newMeshStr != "" && oldMeshStr != newMeshStr)
|
||||
{
|
||||
IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());
|
||||
if (newMeshStr == "")
|
||||
newMeshStr = MeshName;
|
||||
|
||||
if (newAnimatedMesh)
|
||||
newMesh = newAnimatedMesh->getMesh(0);
|
||||
IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());
|
||||
|
||||
if (newMesh)
|
||||
{
|
||||
// if (Mesh)
|
||||
// Mesh->drop();
|
||||
if (newAnimatedMesh)
|
||||
newMesh = newAnimatedMesh->getMesh(0);
|
||||
|
||||
// Mesh = newMesh;
|
||||
// Mesh->grab();
|
||||
|
||||
loadedNewMesh = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadedNewMesh || MinimalPolysPerNode != oldMinimal)
|
||||
if (newMesh && ((MeshName != newMeshStr) || (MinimalPolysPerNode != oldMinimal)))
|
||||
{
|
||||
// recalculate tree
|
||||
//createTree(Mesh);
|
||||
createTree ( newMesh );
|
||||
// newMesh->drop ();
|
||||
createTree(newMesh);
|
||||
}
|
||||
|
||||
ISceneNode::deserializeAttributes(in, options);
|
||||
@ -501,3 +466,4 @@ void COctTreeSceneNode::deleteTree()
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace scene
|
||||
|
||||
//! constructor
|
||||
COctTreeSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
|
||||
s32 minimalPolysPerNode=128);
|
||||
s32 minimalPolysPerNode=512);
|
||||
|
||||
//! destructor
|
||||
virtual ~COctTreeSceneNode();
|
||||
@ -73,7 +73,6 @@ namespace scene
|
||||
video::E_VERTEX_TYPE vertexType;
|
||||
core::array< video::SMaterial > Materials;
|
||||
|
||||
//IMesh* Mesh;
|
||||
core::stringc MeshName;
|
||||
s32 MinimalPolysPerNode;
|
||||
s32 PassCount;
|
||||
|
@ -39,13 +39,13 @@ private:
|
||||
{
|
||||
SOctTreeNode()
|
||||
{
|
||||
for (s32 i=0; i<8; ++i)
|
||||
for (u32 i=0; i!=8; ++i)
|
||||
Child[i] = 0;
|
||||
}
|
||||
|
||||
~SOctTreeNode()
|
||||
{
|
||||
for (s32 i=0; i<8; ++i)
|
||||
for (u32 i=0; i!=8; ++i)
|
||||
delete Child[i];
|
||||
}
|
||||
|
||||
@ -57,9 +57,10 @@ private:
|
||||
|
||||
void constructOctTree(SOctTreeNode* node);
|
||||
void deleteEmptyNodes(SOctTreeNode* node);
|
||||
void getTrianglesFromOctTree(SOctTreeNode* node, s32& trianglesWritten, s32 maximumSize,
|
||||
const core::aabbox3d<f32>& box, const core::matrix4* transform,
|
||||
core::triangle3df* triangles) const;
|
||||
void getTrianglesFromOctTree(SOctTreeNode* node, s32& trianglesWritten,
|
||||
s32 maximumSize, const core::aabbox3d<f32>& box,
|
||||
const core::matrix4* transform,
|
||||
core::triangle3df* triangles) const;
|
||||
|
||||
SOctTreeNode* Root;
|
||||
s32 NodeCount;
|
||||
|
@ -9,20 +9,18 @@
|
||||
#include "S3DVertex.h"
|
||||
#include "aabbox3d.h"
|
||||
#include "irrArray.h"
|
||||
#include "irrString.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
//! template octtree. T must be a vertex type which has a member
|
||||
//! called .Pos, which is a core::vertex3df position.
|
||||
//! template octtree.
|
||||
/** T must be a vertex type which has a member
|
||||
called .Pos, which is a core::vertex3df position. */
|
||||
template <class T>
|
||||
class OctTree
|
||||
{
|
||||
public:
|
||||
|
||||
u32 nodeCount;
|
||||
|
||||
struct SMeshChunk
|
||||
{
|
||||
core::array<T> Vertices;
|
||||
@ -44,45 +42,38 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
//! constructor
|
||||
OctTree(const core::array<SMeshChunk>& meshes, s32 minimalPolysPerNode=128)
|
||||
//! Constructor
|
||||
OctTree(const core::array<SMeshChunk>& meshes, s32 minimalPolysPerNode=128) :
|
||||
IndexData(0), IndexDataCount(meshes.size()), NodeCount(0)
|
||||
{
|
||||
nodeCount = 0;
|
||||
|
||||
IndexDataCount = meshes.size();
|
||||
IndexData = new SIndexData[IndexDataCount];
|
||||
|
||||
// construct array of all indices
|
||||
|
||||
core::array<SIndexChunk>* indexChunks = new core::array<SIndexChunk>;
|
||||
SIndexChunk ic;
|
||||
|
||||
for (u32 i=0; i<meshes.size(); ++i)
|
||||
indexChunks->reallocate(meshes.size());
|
||||
for (u32 i=0; i!=meshes.size(); ++i)
|
||||
{
|
||||
IndexData[i].CurrentSize = 0;
|
||||
IndexData[i].MaxSize = meshes[i].Indices.size();
|
||||
IndexData[i].Indices = new u16[IndexData[i].MaxSize];
|
||||
|
||||
ic.MaterialId = meshes[i].MaterialId;
|
||||
indexChunks->push_back(ic);
|
||||
indexChunks->push_back(SIndexChunk());
|
||||
SIndexChunk& tic = indexChunks->getLast();
|
||||
|
||||
SIndexChunk& tic = (*indexChunks)[i];
|
||||
|
||||
for (u32 t=0; t<meshes[i].Indices.size(); ++t)
|
||||
tic.Indices.push_back(meshes[i].Indices[t]);
|
||||
tic.MaterialId = meshes[i].MaterialId;
|
||||
tic.Indices = meshes[i].Indices;
|
||||
}
|
||||
|
||||
// create tree
|
||||
|
||||
Root = new OctTreeNode(nodeCount, 0, meshes, indexChunks, minimalPolysPerNode);
|
||||
Root = new OctTreeNode(NodeCount, 0, meshes, indexChunks, minimalPolysPerNode);
|
||||
}
|
||||
|
||||
//! returns all ids of polygons partially or fully enclosed
|
||||
//! by this bounding box.
|
||||
void calculatePolys(const core::aabbox3d<f32>& box)
|
||||
{
|
||||
for (u32 i=0; i<IndexDataCount; ++i)
|
||||
for (u32 i=0; i!=IndexDataCount; ++i)
|
||||
IndexData[i].CurrentSize = 0;
|
||||
|
||||
Root->getPolys(box, IndexData, 0);
|
||||
@ -92,28 +83,32 @@ public:
|
||||
//! by a view frustum.
|
||||
void calculatePolys(const scene::SViewFrustum& frustum)
|
||||
{
|
||||
for (u32 i=0; i<IndexDataCount; ++i)
|
||||
for (u32 i=0; i!=IndexDataCount; ++i)
|
||||
IndexData[i].CurrentSize = 0;
|
||||
|
||||
Root->getPolys(frustum, IndexData, 0);
|
||||
}
|
||||
|
||||
|
||||
SIndexData* getIndexData()
|
||||
const SIndexData* getIndexData() const
|
||||
{
|
||||
return IndexData;
|
||||
}
|
||||
|
||||
u32 getIndexDataCount()
|
||||
u32 getIndexDataCount() const
|
||||
{
|
||||
return IndexDataCount;
|
||||
}
|
||||
|
||||
// for debug purposes only, renders the bounding boxes of the tree
|
||||
void renderBoundingBoxes(const core::aabbox3d<f32>& box,
|
||||
core::array< core::aabbox3d<f32> >&outBoxes)
|
||||
u32 getNodeCount() const
|
||||
{
|
||||
Root->renderBoundingBoxes(box, outBoxes);
|
||||
return NodeCount;
|
||||
}
|
||||
|
||||
//! for debug purposes only, collects the bounding boxes of the tree
|
||||
void getBoundingBoxes(const core::aabbox3d<f32>& box,
|
||||
core::array< const core::aabbox3d<f32>* >&outBoxes) const
|
||||
{
|
||||
Root->getBoundingBoxes(box, outBoxes);
|
||||
}
|
||||
|
||||
//! destructor
|
||||
@ -127,7 +122,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// private inner class
|
||||
class OctTreeNode
|
||||
{
|
||||
@ -144,7 +138,7 @@ private:
|
||||
|
||||
u32 i; // new ISO for scoping problem with different compilers
|
||||
|
||||
for (i=0; i<8; ++i)
|
||||
for (i=0; i!=8; ++i)
|
||||
Children[i] = 0;
|
||||
|
||||
if (indices->empty())
|
||||
@ -192,23 +186,20 @@ private:
|
||||
core::array<u16> keepIndices;
|
||||
|
||||
if (totalPrimitives > minimalPolysPerNode && !Box.isEmpty())
|
||||
for (s32 ch=0; ch<8; ++ch)
|
||||
for (u32 ch=0; ch!=8; ++ch)
|
||||
{
|
||||
box.reset(middle);
|
||||
box.addInternalPoint(edges[ch]);
|
||||
|
||||
// create indices for child
|
||||
core::array<SIndexChunk>* cindexChunks = new core::array<SIndexChunk>;
|
||||
|
||||
bool added = false;
|
||||
|
||||
core::array<SIndexChunk>* cindexChunks = new core::array<SIndexChunk>;
|
||||
cindexChunks->reallocate(allmeshdata.size());
|
||||
for (i=0; i<allmeshdata.size(); ++i)
|
||||
{
|
||||
SIndexChunk ic;
|
||||
ic.MaterialId = allmeshdata[i].MaterialId;
|
||||
cindexChunks->push_back(ic);
|
||||
|
||||
SIndexChunk& tic = (*cindexChunks)[i];
|
||||
cindexChunks->push_back(SIndexChunk());
|
||||
SIndexChunk& tic = cindexChunks->getLast();
|
||||
tic.MaterialId = allmeshdata[i].MaterialId;
|
||||
|
||||
for (u32 t=0; t<(*indices)[i].Indices.size(); t+=3)
|
||||
{
|
||||
@ -246,8 +237,6 @@ private:
|
||||
IndexData = indices;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// destructor
|
||||
~OctTreeNode()
|
||||
{
|
||||
@ -257,8 +246,6 @@ private:
|
||||
delete Children[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// returns all ids of polygons partially or full enclosed
|
||||
// by this bounding box.
|
||||
void getPolys(const core::aabbox3d<f32>& box, SIndexData* idxdata, u32 parentTest ) const
|
||||
@ -267,22 +254,21 @@ private:
|
||||
if ( parentTest != 2 )
|
||||
{
|
||||
// partially inside ?
|
||||
parentTest = (u32) Box.intersectsWithBox(box);
|
||||
if ( 0 == parentTest )
|
||||
if (!Box.intersectsWithBox(box))
|
||||
return;
|
||||
|
||||
// fully inside ?
|
||||
parentTest+= Box.isFullInside(box);
|
||||
parentTest = Box.isFullInside(box)?2:1;
|
||||
}
|
||||
|
||||
//if (Box.intersectsWithBox(box))
|
||||
{
|
||||
u32 cnt = IndexData->size();
|
||||
const u32 cnt = IndexData->size();
|
||||
u32 i; // new ISO for scoping problem in some compilers
|
||||
|
||||
for (i=0; i<cnt; ++i)
|
||||
{
|
||||
s32 idxcnt = (*IndexData)[i].Indices.size();
|
||||
const s32 idxcnt = (*IndexData)[i].Indices.size();
|
||||
|
||||
if (idxcnt)
|
||||
{
|
||||
@ -292,19 +278,17 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<8; ++i)
|
||||
for (i=0; i!=8; ++i)
|
||||
if (Children[i])
|
||||
Children[i]->getPolys(box, idxdata,parentTest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// returns all ids of polygons partially or full enclosed
|
||||
// by the view frustum.
|
||||
void getPolys(const scene::SViewFrustum& frustum, SIndexData* idxdata,u32 parentTest) const
|
||||
{
|
||||
s32 i; // new ISO for scoping problem in some compilers
|
||||
u32 i; // new ISO for scoping problem in some compilers
|
||||
|
||||
// not fully inside
|
||||
//if ( parentTest != 2 )
|
||||
@ -312,25 +296,27 @@ private:
|
||||
core::vector3df edges[8];
|
||||
Box.getEdges(edges);
|
||||
|
||||
for (i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i)
|
||||
for (i=0; i!=scene::SViewFrustum::VF_PLANE_COUNT; ++i)
|
||||
{
|
||||
bool boxInFrustum=false;
|
||||
|
||||
for (int j=0; j<8; ++j)
|
||||
for (u32 j=0; j!=8; ++j)
|
||||
{
|
||||
if (frustum.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
|
||||
{
|
||||
boxInFrustum=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!boxInFrustum) // all edges outside
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
s32 cnt = IndexData->size();
|
||||
const u32 cnt = IndexData->size();
|
||||
|
||||
for (i=0; i<cnt; ++i)
|
||||
for (i=0; i!=cnt; ++i)
|
||||
{
|
||||
s32 idxcnt = (*IndexData)[i].Indices.size();
|
||||
|
||||
@ -342,23 +328,22 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<8; ++i)
|
||||
for (i=0; i!=8; ++i)
|
||||
if (Children[i])
|
||||
Children[i]->getPolys(frustum, idxdata,parentTest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void renderBoundingBoxes(const core::aabbox3d<f32>& box,
|
||||
core::array< core::aabbox3d<f32> >&outBoxes)
|
||||
//! for debug purposes only, collects the bounding boxes of the node
|
||||
void getBoundingBoxes(const core::aabbox3d<f32>& box,
|
||||
core::array< const core::aabbox3d<f32>* >&outBoxes) const
|
||||
{
|
||||
if (Box.intersectsWithBox(box))
|
||||
{
|
||||
outBoxes.push_back(Box);
|
||||
outBoxes.push_back(&Box);
|
||||
|
||||
for (u32 i=0; i<8; ++i)
|
||||
for (u32 i=0; i!=8; ++i)
|
||||
if (Children[i])
|
||||
Children[i]->renderBoundingBoxes(box, outBoxes);
|
||||
Children[i]->getBoundingBoxes(box, outBoxes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,6 +358,7 @@ private:
|
||||
OctTreeNode* Root;
|
||||
SIndexData* IndexData;
|
||||
u32 IndexDataCount;
|
||||
u32 NodeCount;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user