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
This commit is contained in:
hybrid 2011-09-07 07:31:53 +00:00
parent 5ba7ae5afd
commit 4486cee370

View File

@ -289,6 +289,8 @@ const core::aabbox3d<f32>& 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; i<mesh->getMeshBufferCount(); ++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; i<mesh->getMeshBufferCount(); ++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; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]);
switch (b->getVertexType())
{
case video::EVT_STANDARD:
for (v=0; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]);
break;
case video::EVT_2TCOORDS:
for (v=0; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]);
break;
case video::EVT_TANGENTS:
for (v=0; v<b->getVertexCount(); ++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; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]);
switch (b->getVertexType())
{
case video::EVT_STANDARD:
for (v=0; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]);
break;
case video::EVT_2TCOORDS:
for (v=0; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]);
break;
case video::EVT_TANGENTS:
for (v=0; v<b->getVertexCount(); ++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; i<mesh->getMeshBufferCount(); ++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; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
switch (b->getVertexType())
{
case video::EVT_STANDARD:
for (v=0; v<b->getVertexCount(); ++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; v<b->getVertexCount(); ++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; v<b->getVertexCount(); ++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);