diff --git a/source/Irrlicht/COctTreeSceneNode.cpp b/source/Irrlicht/COctTreeSceneNode.cpp index 83de52ce..6181049c 100644 --- a/source/Irrlicht/COctTreeSceneNode.cpp +++ b/source/Irrlicht/COctTreeSceneNode.cpp @@ -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; igetMaterialRenderer(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::SIndexData* d = StdOctTree->getIndexData(); + const OctTree::SIndexData* d = StdOctTree->getIndexData(); for (u32 i=0; igetMaterialRenderer(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 &box = frust.getBoundingBox(); - core::array< core::aabbox3d > boxes; + const core::aabbox3df& box = frust.getBoundingBox(); + core::array< const core::aabbox3d* > boxes; video::SMaterial m; m.Lighting = false; driver->setMaterial(m); if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) { - StdOctTree->renderBoundingBoxes(box, boxes); - for (u32 b=0; bdraw3DBox(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::SIndexData* d = LightMapOctTree->getIndexData(); + const OctTree::SIndexData* d = LightMapOctTree->getIndexData(); for (u32 i=0; igetMaterialRenderer(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 &box = frust.getBoundingBox(); - core::array< core::aabbox3d > boxes; + core::array< const core::aabbox3d* > 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; bdraw3DBox(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::SIndexData* d = TangentsOctTree->getIndexData(); + const OctTree::SIndexData* d = TangentsOctTree->getIndexData(); for (u32 i=0; igetMaterialRenderer(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 &box = frust.getBoundingBox(); - core::array< core::aabbox3d > boxes; + core::array< const core::aabbox3d* > 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; bdraw3DBox(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::SMeshChunk chunk; - chunk.MaterialId = Materials.size() - 1; - StdMeshes.push_back(chunk); - OctTree::SMeshChunk &nchunk = StdMeshes[StdMeshes.size()-1]; + StdMeshes.push_back(OctTree::SMeshChunk()); + OctTree::SMeshChunk &nchunk = StdMeshes.getLast(); + nchunk.MaterialId = Materials.size() - 1; u32 v; - + nchunk.Vertices.reallocate(b->getVertexCount()); for (v=0; vgetVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); polyCount += b->getIndexCount(); + nchunk.Indices.reallocate(b->getIndexCount()); for (v=0; vgetIndexCount(); ++v) nchunk.Indices.push_back(b->getIndices()[v]); } } StdOctTree = new OctTree(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::SMeshChunk chunk; - chunk.MaterialId = Materials.size() - 1; - LightMapMeshes.push_back(chunk); - OctTree::SMeshChunk& nchunk = - LightMapMeshes[LightMapMeshes.size()-1]; + LightMapMeshes.push_back(OctTree::SMeshChunk()); + OctTree::SMeshChunk& nchunk = LightMapMeshes.getLast(); + nchunk.MaterialId = Materials.size() - 1; u32 v; - + nchunk.Vertices.reallocate(b->getVertexCount()); for (v=0; vgetVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); polyCount += b->getIndexCount(); - + nchunk.Indices.reallocate(b->getIndexCount()); for (v=0; vgetIndexCount(); ++v) nchunk.Indices.push_back(b->getIndices()[v]); } } LightMapOctTree = new OctTree(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::SMeshChunk chunk; - chunk.MaterialId = Materials.size() - 1; - TangentsMeshes.push_back(chunk); - OctTree::SMeshChunk& nchunk = - TangentsMeshes[TangentsMeshes.size()-1]; + TangentsMeshes.push_back(OctTree::SMeshChunk()); + OctTree::SMeshChunk& nchunk = TangentsMeshes.getLast(); + nchunk.MaterialId = Materials.size() - 1; u32 v; - + nchunk.Vertices.reallocate(b->getVertexCount()); for (v=0; vgetVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); polyCount += b->getIndexCount(); - + nchunk.Indices.reallocate(b->getIndexCount()); for (v=0; vgetIndexCount(); ++v) nchunk.Indices.push_back(b->getIndices()[v]); } } TangentsOctTree = new OctTree(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 + diff --git a/source/Irrlicht/COctTreeSceneNode.h b/source/Irrlicht/COctTreeSceneNode.h index 39c7d984..16feeb00 100644 --- a/source/Irrlicht/COctTreeSceneNode.h +++ b/source/Irrlicht/COctTreeSceneNode.h @@ -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; diff --git a/source/Irrlicht/COctTreeTriangleSelector.h b/source/Irrlicht/COctTreeTriangleSelector.h index 8651b568..1a52e4ca 100644 --- a/source/Irrlicht/COctTreeTriangleSelector.h +++ b/source/Irrlicht/COctTreeTriangleSelector.h @@ -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& box, const core::matrix4* transform, - core::triangle3df* triangles) const; + void getTrianglesFromOctTree(SOctTreeNode* node, s32& trianglesWritten, + s32 maximumSize, const core::aabbox3d& box, + const core::matrix4* transform, + core::triangle3df* triangles) const; SOctTreeNode* Root; s32 NodeCount; diff --git a/source/Irrlicht/OctTree.h b/source/Irrlicht/OctTree.h index 20bdb971..6a186937 100644 --- a/source/Irrlicht/OctTree.h +++ b/source/Irrlicht/OctTree.h @@ -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 OctTree { public: - u32 nodeCount; - struct SMeshChunk { core::array Vertices; @@ -44,45 +42,38 @@ public: }; - - //! constructor - OctTree(const core::array& meshes, s32 minimalPolysPerNode=128) + //! Constructor + OctTree(const core::array& 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* indexChunks = new core::array; - SIndexChunk ic; - - for (u32 i=0; ireallocate(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& box) { - for (u32 i=0; igetPolys(box, IndexData, 0); @@ -92,28 +83,32 @@ public: //! by a view frustum. void calculatePolys(const scene::SViewFrustum& frustum) { - for (u32 i=0; igetPolys(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& box, - core::array< core::aabbox3d >&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& box, + core::array< const core::aabbox3d* >&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 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* cindexChunks = new core::array; - bool added = false; - + core::array* cindexChunks = new core::array; + cindexChunks->reallocate(allmeshdata.size()); for (i=0; ipush_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& 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; igetPolys(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; isize(); + const u32 cnt = IndexData->size(); - for (i=0; igetPolys(frustum, idxdata,parentTest); } - - - void renderBoundingBoxes(const core::aabbox3d& box, - core::array< core::aabbox3d >&outBoxes) + //! for debug purposes only, collects the bounding boxes of the node + void getBoundingBoxes(const core::aabbox3d& box, + core::array< const core::aabbox3d* >&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