From 4486cee370c5ed75d901b2c2dcd1627312ade4cf Mon Sep 17 00:00:00 2001 From: hybrid Date: Wed, 7 Sep 2011 07:31:53 +0000 Subject: [PATCH] Thanks to Auria, this fix makes octree work with mixed lightmap meshes (i.e. meshes which mix meshbuffer types). Most b3d files do this, and now work properly with octree support. The fix is right now not perfect, because of incomplete tangent vertex creation in case this vertex type is also used. But fixing also this issue would mean a huge rework of the octree, which has to wait for now. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3906 dfc29bdd-3216-0410-991c-e03cc46cb475 --- source/Irrlicht/COctreeSceneNode.cpp | 98 +++++++++++++++++++++------- 1 file changed, 76 insertions(+), 22 deletions(-) diff --git a/source/Irrlicht/COctreeSceneNode.cpp b/source/Irrlicht/COctreeSceneNode.cpp index 940c16ae..30072465 100644 --- a/source/Irrlicht/COctreeSceneNode.cpp +++ b/source/Irrlicht/COctreeSceneNode.cpp @@ -289,6 +289,8 @@ const core::aabbox3d& COctreeSceneNode::getBoundingBox() const //! creates the tree +/* This method has a lot of duplication and overhead. Moreover, the tangents mesh conversion does not really work. I think we need a a proper mesh implementation for octrees, which handle all vertex types internally. Converting all structures to just one vertex type is always problematic. +Thanks to Auria for fixing major parts of this method. */ bool COctreeSceneNode::createTree(IMesh* mesh) { if (!mesh) @@ -301,7 +303,7 @@ bool COctreeSceneNode::createTree(IMesh* mesh) Mesh = mesh; - u32 beginTime = os::Timer::getRealTime(); + const u32 beginTime = os::Timer::getRealTime(); u32 nodeCount = 0; u32 polyCount = 0; @@ -311,12 +313,28 @@ bool COctreeSceneNode::createTree(IMesh* mesh) if (mesh->getMeshBufferCount()) { - VertexType = mesh->getMeshBuffer(0)->getVertexType(); + // check for "larger" buffer types + VertexType = video::EVT_STANDARD; + u32 meshReserve = 0; + for (i=0; igetMeshBufferCount(); ++i) + { + const IMeshBuffer* b = mesh->getMeshBuffer(i); + if (b->getVertexCount() && b->getIndexCount()) + { + ++meshReserve; + if (b->getVertexType() == video::EVT_2TCOORDS) + VertexType = video::EVT_2TCOORDS; + else if (b->getVertexType() == video::EVT_TANGENTS) + VertexType = video::EVT_TANGENTS; + } + } + Materials.reallocate(Materials.size()+meshReserve); switch(VertexType) { case video::EVT_STANDARD: { + StdMeshes.reallocate(StdMeshes.size() + meshReserve); for (i=0; igetMeshBufferCount(); ++i) { IMeshBuffer* b = mesh->getMeshBuffer(i); @@ -331,8 +349,21 @@ bool COctreeSceneNode::createTree(IMesh* mesh) u32 v; nchunk.Vertices.reallocate(b->getVertexCount()); - for (v=0; vgetVertexCount(); ++v) - nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); + switch (b->getVertexType()) + { + case video::EVT_STANDARD: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); + break; + case video::EVT_2TCOORDS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); + break; + case video::EVT_TANGENTS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); + break; + } polyCount += b->getIndexCount(); @@ -348,22 +379,11 @@ bool COctreeSceneNode::createTree(IMesh* mesh) break; case video::EVT_2TCOORDS: { - IMeshBuffer* b; - u32 meshReserve = 0; - for ( i=0; i < mesh->getMeshBufferCount(); ++i) - { - b = mesh->getMeshBuffer(i); - if (b->getVertexCount() && b->getIndexCount()) - { - meshReserve += 1; - } - - } - LightMapMeshes.reallocate ( LightMapMeshes.size() + meshReserve ); + LightMapMeshes.reallocate(LightMapMeshes.size() + meshReserve); for ( i=0; i < mesh->getMeshBufferCount(); ++i) { - b = mesh->getMeshBuffer(i); + IMeshBuffer* b = mesh->getMeshBuffer(i); if (b->getVertexCount() && b->getIndexCount()) { @@ -382,8 +402,21 @@ bool COctreeSceneNode::createTree(IMesh* mesh) u32 v; nchunk.Vertices.reallocate(b->getVertexCount()); - for (v=0; vgetVertexCount(); ++v) - nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); + switch (b->getVertexType()) + { + case video::EVT_STANDARD: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); + break; + case video::EVT_2TCOORDS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); + break; + case video::EVT_TANGENTS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); + break; + } polyCount += b->getIndexCount(); nchunk.Indices.reallocate(b->getIndexCount()); @@ -398,6 +431,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh) break; case video::EVT_TANGENTS: { + TangentsMeshes.reallocate(TangentsMeshes.size() + meshReserve); + for (u32 i=0; igetMeshBufferCount(); ++i) { IMeshBuffer* b = mesh->getMeshBuffer(i); @@ -411,8 +446,27 @@ bool COctreeSceneNode::createTree(IMesh* mesh) u32 v; nchunk.Vertices.reallocate(b->getVertexCount()); - for (v=0; vgetVertexCount(); ++v) - nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); + switch (b->getVertexType()) + { + case video::EVT_STANDARD: + for (v=0; vgetVertexCount(); ++v) + { + const video::S3DVertex& tmpV = ((video::S3DVertex*)b->getVertices())[v]; + nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords)); + } + break; + case video::EVT_2TCOORDS: + for (v=0; vgetVertexCount(); ++v) + { + const video::S3DVertex2TCoords& tmpV = ((video::S3DVertex2TCoords*)b->getVertices())[v]; + nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords)); + } + break; + case video::EVT_TANGENTS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); + break; + } polyCount += b->getIndexCount(); nchunk.Indices.reallocate(b->getIndexCount()); @@ -428,7 +482,7 @@ bool COctreeSceneNode::createTree(IMesh* mesh) } } - u32 endTime = os::Timer::getRealTime(); + const u32 endTime = os::Timer::getRealTime(); c8 tmp[255]; sprintf(tmp, "Needed %ums to create Octree SceneNode.(%u nodes, %u polys)", endTime - beginTime, nodeCount, polyCount/3);