Hi there,
I have a very big 3d studio model representing a museum to load in my application...of course i use an OctTreeSceneNode to represent it, but the model is so big that actually creating the octree takes up to 15 seconds and creating the triangle selector takes an amazing 5 minutes...
Probably the best idea would be to split the model into separate rooms and use a scene node for each, but i'm a poop at using 3d studio and don't have anyone who could do it.
I searched the forum to find a way to serialize the octree object into a file to avoid the mesh splitting calculations every time i load the mesh, the idea would be to have a standalone program that stores all the octree and triangleselector data in a file and a method that loads this data in my application, but it seems that this issue hasn't been addressed yet...any hints about someone that had this same problem and found a solution?
Thanx in advance
Octree serialization to avoid huge loading time
Creating an COctTreeTriangleSelector for OctTreeSceneNode's was also too slow for me. But the OctTreeSceneNode has certainly already an octree, so i wrote a selector which does use that octree and which get's created after the octree generation of the OctTreeSceneNode. I have still the problem that it returns to many triangles sometimes, but it doesn't seem to be a problem of my selector, as i have exactly the same problem with the original COctTreeTriangleSelector.
The header (called "COctTreeSceneNodeTriangleSelector.h"):
The sourcefile (called "COctTreeSceneNodeTriangleSelector.cpp"):
in COctTreeSceneNode i added COctTreeSceneNodeTriangleSelector as friend in the public section:
COctTreeSceneNode.cpp needs to add the following include:
and in bool COctTreeSceneNode::createTree(IMesh* mesh) i add the selector at the end of the function:
edit: Ups, found some minor bugs after posting, fixed those
The header (called "COctTreeSceneNodeTriangleSelector.h"):
Code: Select all
#ifndef __C_OCT_TREE_SCENE_NODETRIANGLE_SELECTOR_H_INCLUDED__
#define __C_OCT_TREE_SCENE_NODETRIANGLE_SELECTOR_H_INCLUDED__
#include "ITriangleSelector.h"
namespace irr
{
namespace scene
{
class COctTreeSceneNode;
//! triangle selector which does use the OctTree already available for a COctTreeSceneNode
class COctTreeSceneNodeTriangleSelector : public ITriangleSelector
{
public:
//! Constructs a selector based on a mesh
COctTreeSceneNodeTriangleSelector(COctTreeSceneNode* node);
~COctTreeSceneNodeTriangleSelector();
//! Returns amount of all available triangles in this selector
virtual s32 getTriangleCount() const;
//! Gets all triangles.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform=0);
//! Gets all triangles which lie within a specific bounding box.
void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box, const core::matrix4* transform=0);
//! Gets all triangles which have or may have contact with a 3d line.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform=0);
private:
COctTreeSceneNode * SceneNode;
};
} // end namespace scene
} // end namespace irr
#endif // __C_OCT_TREE_SCENE_NODETRIANGLE_SELECTOR_H_INCLUDED__
Code: Select all
#include "COctTreeSceneNodeTriangleSelector.h"
#include "COctTreeSceneNode.h"
#include "OctTree.h"
using namespace irr;
using namespace scene;
COctTreeSceneNodeTriangleSelector::COctTreeSceneNodeTriangleSelector(COctTreeSceneNode* node)
: SceneNode(node)
{
}
COctTreeSceneNodeTriangleSelector::~COctTreeSceneNodeTriangleSelector()
{
}
s32 COctTreeSceneNodeTriangleSelector::getTriangleCount() const
{
int triangleCount = 0;
switch (SceneNode->vertexType)
{
case video::EVT_STANDARD:
{
for ( int i=0; i < SceneNode->StdMeshes.size(); ++i )
{
triangleCount += SceneNode->StdMeshes[i].Indices.size();
}
triangleCount /= 3;
break;
}
case video::EVT_2TCOORDS:
{
for ( int i=0; i < SceneNode->LightMapMeshes.size(); ++i )
{
triangleCount += SceneNode->LightMapMeshes[i].Indices.size();
}
triangleCount /= 3;
break;
}
}
return triangleCount;
}
void COctTreeSceneNodeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform)
{
outTriangleCount = 0;
if ( !arraySize )
return;
core::matrix4 mat;
if (transform)
mat = (*transform);
if (SceneNode)
mat *= SceneNode->getAbsoluteTransformation();
switch (SceneNode->vertexType)
{
case video::EVT_STANDARD:
{
for ( int i=0; i < SceneNode->StdMeshes.size(); ++i )
{
OctTree<video::S3DVertex>::SMeshChunk &mesh = SceneNode->StdMeshes[i];
for ( int t=0; t<mesh.Indices.size(); t+=3 )
{
triangles[outTriangleCount].pointA = mesh.Vertices[ mesh.Indices[t] ].Pos;
triangles[outTriangleCount].pointB = mesh.Vertices[ mesh.Indices[t+1] ].Pos;
triangles[outTriangleCount].pointC = mesh.Vertices[ mesh.Indices[t+2] ].Pos;
mat.transformVect(triangles[outTriangleCount].pointA);
mat.transformVect(triangles[outTriangleCount].pointB);
mat.transformVect(triangles[outTriangleCount].pointC);
if ( ++outTriangleCount >= arraySize )
return;
}
}
break;
}
case video::EVT_2TCOORDS:
{
for ( int i=0; i < SceneNode->LightMapMeshes.size(); ++i )
{
OctTree<video::S3DVertex2TCoords>::SMeshChunk &mesh = SceneNode->LightMapMeshes[i];
for ( int t=0; t<mesh.Indices.size(); t+=3 )
{
triangles[outTriangleCount].pointA = mesh.Vertices[ mesh.Indices[t] ].Pos;
triangles[outTriangleCount].pointB = mesh.Vertices[ mesh.Indices[t+1] ].Pos;
triangles[outTriangleCount].pointC = mesh.Vertices[ mesh.Indices[t+2] ].Pos;
mat.transformVect(triangles[outTriangleCount].pointA);
mat.transformVect(triangles[outTriangleCount].pointB);
mat.transformVect(triangles[outTriangleCount].pointC);
if ( ++outTriangleCount >= arraySize )
return;
}
}
break;
}
}
}
void COctTreeSceneNodeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box, const core::matrix4* transform)
{
outTriangleCount = 0;
if ( !arraySize )
return;
core::matrix4 mat;
if (SceneNode)
mat = SceneNode->getAbsoluteTransformation();
mat.makeInverse();
core::aabbox3d<f32> invbox = box;
mat.transformBox(invbox);
mat.makeIdentity();
if (transform)
mat = (*transform);
if (SceneNode)
mat *= SceneNode->getAbsoluteTransformation();
switch(SceneNode->vertexType)
{
case video::EVT_STANDARD:
{
SceneNode->StdOctTree->calculatePolys(invbox);
OctTree<video::S3DVertex>::SIndexData* d = SceneNode->StdOctTree->getIndexData();
for ( int i=0; i < SceneNode->StdMeshes.size(); ++i )
{
OctTree<video::S3DVertex>::SMeshChunk &mesh = SceneNode->StdMeshes[i];
for ( int t=0; t<d[i].CurrentSize; t+=3 )
{
triangles[outTriangleCount].pointA = mesh.Vertices[ d[i].Indices[t] ].Pos;
triangles[outTriangleCount].pointB = mesh.Vertices[ d[i].Indices[t+1] ].Pos;
triangles[outTriangleCount].pointC = mesh.Vertices[ d[i].Indices[t+2] ].Pos;
mat.transformVect(triangles[outTriangleCount].pointA);
mat.transformVect(triangles[outTriangleCount].pointB);
mat.transformVect(triangles[outTriangleCount].pointC);
if ( ++outTriangleCount >= arraySize )
return;
}
}
break;
}
case video::EVT_2TCOORDS:
{
SceneNode->LightMapOctTree->calculatePolys(invbox);
OctTree<video::S3DVertex2TCoords>::SIndexData* d = SceneNode->LightMapOctTree->getIndexData();
for ( int i=0; i < SceneNode->LightMapMeshes.size(); ++i )
{
OctTree<video::S3DVertex2TCoords>::SMeshChunk &mesh = SceneNode->LightMapMeshes[i];
for ( int t=0; t<d[i].CurrentSize; t+=3 )
{
triangles[outTriangleCount].pointA = mesh.Vertices[ d[i].Indices[t] ].Pos;
triangles[outTriangleCount].pointB = mesh.Vertices[ d[i].Indices[t+1] ].Pos;
triangles[outTriangleCount].pointC = mesh.Vertices[ d[i].Indices[t+2] ].Pos;
mat.transformVect(triangles[outTriangleCount].pointA);
mat.transformVect(triangles[outTriangleCount].pointB);
mat.transformVect(triangles[outTriangleCount].pointC);
if ( ++outTriangleCount >= arraySize )
return;
}
}
break;
}
}
}
void COctTreeSceneNodeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line, const core::matrix4* transform)
{
core::aabbox3d<f32> box(line.start);
box.addInternalPoint(line.end);
// TODO: Could be optimized for line a little bit more.
COctTreeSceneNodeTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, box, transform);
}
Code: Select all
friend class COctTreeSceneNodeTriangleSelector;
Code: Select all
#include "COctTreeSceneNodeTriangleSelector.h"
Code: Select all
ITriangleSelector* selector = new COctTreeSceneNodeTriangleSelector(this);
setTriangleSelector(selector);
edit: Ups, found some minor bugs after posting, fixed those