Commit 65cfbeb2 authored by hybrid's avatar hybrid

Cleanup and some speed improvements.

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