Fix CMetaTriangleSelector and allow creating octrees for single meshbuffers.
CMetaTriangleSelector had been (even more) broken after last check-in,sorry. Now fixed again. Making octrees triangle selector return meshbuffer information would be possible, but not without some cost or larger rewrite. So instead I've added another workaround - it's now possible to create octress for single meshbuffers. If that makes sense for speed is something users have to check per scene (slower than using a single octree obviously), but at least it's now possible in case someone needs it. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5352 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
543e70dc34
commit
1073bff853
|
@ -1,6 +1,7 @@
|
|||
--------------------------
|
||||
Changes in 1.9 (not yet released)
|
||||
|
||||
- ITriangleSelector now can also return meshbuffer collision information.
|
||||
- core::string::split now adds delimiter to token before delimiter when keepSeparators is true. That way we never end up with 2 tokens for an original string with a single character.
|
||||
- Bugfix: SMesh::recalculateBoundingBox() does now ignore empty boundingboxes of meshbuffers instead of adding them.
|
||||
- IIrrXMLReader::getAttributeValueAsInt and IIrrXMLReader::getAttributeValueAsFloat can now return a custom default-value when the attribute is not found.
|
||||
|
|
|
@ -93,8 +93,33 @@ int main()
|
|||
{
|
||||
q3node->setPosition(core::vector3df(-1350,-130,-1400));
|
||||
|
||||
selector = smgr->createOctreeTriangleSelector(
|
||||
q3node->getMesh(), q3node, 128);
|
||||
/*
|
||||
There is currently no way to split an octree by material.
|
||||
So if we need that we have to create an octrees per meshbuffer
|
||||
and put them together in a MetaTriangleSelector.
|
||||
|
||||
*/
|
||||
if ( separateMeshBuffers && q3node->getMesh()->getMeshBufferCount() > 1)
|
||||
{
|
||||
scene::IMetaTriangleSelector * metaSelector = smgr->createMetaTriangleSelector();
|
||||
for ( irr::u32 m=0; m < q3node->getMesh()->getMeshBufferCount(); ++m )
|
||||
{
|
||||
scene::ITriangleSelector*
|
||||
bufferSelector = smgr->createOctreeTriangleSelector(
|
||||
q3node->getMesh()->getMeshBuffer(m), m, q3node);
|
||||
if ( bufferSelector )
|
||||
{
|
||||
metaSelector->addTriangleSelector( bufferSelector );
|
||||
bufferSelector->drop();
|
||||
}
|
||||
}
|
||||
selector = metaSelector;
|
||||
}
|
||||
else
|
||||
{
|
||||
selector = smgr->createOctreeTriangleSelector(
|
||||
q3node->getMesh(), q3node, 128);
|
||||
}
|
||||
q3node->setTriangleSelector(selector);
|
||||
// We're not done with this selector yet, so don't drop it.
|
||||
}
|
||||
|
|
|
@ -1334,6 +1334,33 @@ namespace scene
|
|||
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
|
||||
ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
|
||||
|
||||
//! Creates a Triangle Selector for a single meshbuffer, optimized by an octree.
|
||||
/** Triangle selectors
|
||||
can be used for doing collision detection. This triangle selector is
|
||||
optimized for huge amounts of triangle, it organizes them in an octree.
|
||||
Please note that the created triangle selector is not automatically attached
|
||||
to the scene node. You will have to call ISceneNode::setTriangleSelector()
|
||||
for this. To create and attach a triangle selector is done like this:
|
||||
\code
|
||||
ITriangleSelector* s = sceneManager->createOctreeTriangleSelector(yourMesh,
|
||||
yourSceneNode);
|
||||
yourSceneNode->setTriangleSelector(s);
|
||||
s->drop();
|
||||
\endcode
|
||||
For more information and examples on this, take a look at the collision
|
||||
tutorial in the SDK.
|
||||
\param meshBuffer: Meshbuffer of which the triangles are taken.
|
||||
\param materialIndex: Setting this value allows the triangle selector to return the material index
|
||||
\param node: Scene node of which visibility and transformation is used.
|
||||
\param minimalPolysPerNode: Specifies the minimal polygons contained a octree node.
|
||||
If a node gets less polys than this value, it will not be split into
|
||||
smaller nodes.
|
||||
\return The selector, or null if not successful.
|
||||
If you no longer need the selector, you should call ITriangleSelector::drop().
|
||||
See IReferenceCounted::drop() for more information. */
|
||||
virtual ITriangleSelector* createOctreeTriangleSelector(IMeshBuffer* meshBuffer, irr::u32 materialIndex,
|
||||
ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
|
||||
|
||||
//! //! Creates a Triangle Selector, optimized by an octree.
|
||||
/** \deprecated Use createOctreeTriangleSelector instead. This method may be removed by Irrlicht 1.9. */
|
||||
_IRR_DEPRECATED_ ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh,
|
||||
|
|
|
@ -42,11 +42,23 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
|
|||
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||
{
|
||||
s32 outWritten = 0;
|
||||
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||
{
|
||||
s32 t = 0;
|
||||
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
||||
arraySize - outWritten, t, transform, useNodeTransform, outTriangleInfo);
|
||||
|
||||
if ( outTriangleInfo )
|
||||
{
|
||||
irr::u32 newTriangleInfoSize = outTriangleInfo->size();
|
||||
for ( u32 ti=outTriangleInfoSize; ti<newTriangleInfoSize; ++ti )
|
||||
{
|
||||
(*outTriangleInfo)[ti].RangeStart += outWritten;
|
||||
}
|
||||
outTriangleInfoSize = newTriangleInfoSize;
|
||||
}
|
||||
|
||||
outWritten += t;
|
||||
if (outWritten==arraySize)
|
||||
break;
|
||||
|
@ -63,11 +75,23 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
|
|||
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||
{
|
||||
s32 outWritten = 0;
|
||||
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||
{
|
||||
s32 t = 0;
|
||||
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
||||
arraySize - outWritten, t, box, transform, useNodeTransform, outTriangleInfo);
|
||||
|
||||
if ( outTriangleInfo )
|
||||
{
|
||||
irr::u32 newTriangleInfoSize = outTriangleInfo->size();
|
||||
for ( u32 ti=outTriangleInfoSize; ti<newTriangleInfoSize; ++ti )
|
||||
{
|
||||
(*outTriangleInfo)[ti].RangeStart += outWritten;
|
||||
}
|
||||
outTriangleInfoSize = newTriangleInfoSize;
|
||||
}
|
||||
|
||||
outWritten += t;
|
||||
if (outWritten==arraySize)
|
||||
break;
|
||||
|
@ -84,11 +108,23 @@ void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 array
|
|||
irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
|
||||
{
|
||||
s32 outWritten = 0;
|
||||
irr::u32 outTriangleInfoSize = outTriangleInfo ? outTriangleInfo->size() : 0;
|
||||
for (u32 i=0; i<TriangleSelectors.size(); ++i)
|
||||
{
|
||||
s32 t = 0;
|
||||
TriangleSelectors[i]->getTriangles(triangles + outWritten,
|
||||
arraySize - outWritten, t, line, transform, useNodeTransform, outTriangleInfo);
|
||||
|
||||
if ( outTriangleInfo )
|
||||
{
|
||||
irr::u32 newTriangleInfoSize = outTriangleInfo->size();
|
||||
for ( u32 ti=outTriangleInfoSize; ti<newTriangleInfoSize; ++ti )
|
||||
{
|
||||
(*outTriangleInfo)[ti].RangeStart += outWritten;
|
||||
}
|
||||
outTriangleInfoSize = newTriangleInfoSize;
|
||||
}
|
||||
|
||||
outWritten += t;
|
||||
if (outWritten==arraySize)
|
||||
break;
|
||||
|
|
|
@ -15,8 +15,9 @@ namespace scene
|
|||
//! constructor
|
||||
COctreeTriangleSelector::COctreeTriangleSelector(const IMesh* mesh,
|
||||
ISceneNode* node, s32 minimalPolysPerNode)
|
||||
: CTriangleSelector(mesh, node, false), Root(0), NodeCount(0),
|
||||
MinimalPolysPerNode(minimalPolysPerNode)
|
||||
: CTriangleSelector(mesh, node, false)
|
||||
, Root(0), NodeCount(0)
|
||||
, MinimalPolysPerNode(minimalPolysPerNode)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("COctreeTriangleSelector");
|
||||
|
@ -38,6 +39,30 @@ COctreeTriangleSelector::COctreeTriangleSelector(const IMesh* mesh,
|
|||
}
|
||||
}
|
||||
|
||||
COctreeTriangleSelector::COctreeTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node, s32 minimalPolysPerNode)
|
||||
: CTriangleSelector(meshBuffer, materialIndex, node)
|
||||
, Root(0), NodeCount(0)
|
||||
, MinimalPolysPerNode(minimalPolysPerNode)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("COctreeTriangleSelector");
|
||||
#endif
|
||||
|
||||
if (!Triangles.empty())
|
||||
{
|
||||
const u32 start = os::Timer::getRealTime();
|
||||
|
||||
// create the triangle octree
|
||||
Root = new SOctreeNode();
|
||||
Root->Triangles = Triangles;
|
||||
constructOctree(Root);
|
||||
|
||||
c8 tmp[256];
|
||||
sprintf(tmp, "Needed %ums to create OctreeTriangleSelector.(%d nodes, %u polys)",
|
||||
os::Timer::getRealTime() - start, NodeCount, Triangles.size());
|
||||
os::Printer::log(tmp, ELL_INFORMATION);
|
||||
}
|
||||
}
|
||||
|
||||
//! destructor
|
||||
COctreeTriangleSelector::~COctreeTriangleSelector()
|
||||
|
@ -146,6 +171,8 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
|
|||
triRange.RangeSize = trianglesWritten;
|
||||
triRange.Selector = const_cast<COctreeTriangleSelector*>(this);
|
||||
triRange.SceneNode = SceneNode;
|
||||
triRange.MeshBuffer = MeshBuffer;
|
||||
triRange.MaterialIndex = MaterialIndex;
|
||||
outTriangleInfo->push_back(triRange);
|
||||
}
|
||||
|
||||
|
@ -236,6 +263,8 @@ void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arr
|
|||
triRange.RangeSize = trianglesWritten;
|
||||
triRange.Selector = const_cast<COctreeTriangleSelector*>(this);
|
||||
triRange.SceneNode = SceneNode;
|
||||
triRange.MeshBuffer = MeshBuffer;
|
||||
triRange.MaterialIndex = MaterialIndex;
|
||||
outTriangleInfo->push_back(triRange);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@ public:
|
|||
//! Constructs a selector based on a mesh
|
||||
COctreeTriangleSelector(const IMesh* mesh, ISceneNode* node, s32 minimalPolysPerNode);
|
||||
|
||||
//! Constructs a selector based on a meshbuffer
|
||||
COctreeTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node, s32 minimalPolysPerNode);
|
||||
|
||||
virtual ~COctreeTriangleSelector();
|
||||
|
||||
//! Gets all triangles which lie within a specific bounding box.
|
||||
|
|
|
@ -1893,6 +1893,14 @@ ITriangleSelector* CSceneManager::createOctreeTriangleSelector(IMesh* mesh,
|
|||
return new COctreeTriangleSelector(mesh, node, minimalPolysPerNode);
|
||||
}
|
||||
|
||||
ITriangleSelector* CSceneManager::createOctreeTriangleSelector(IMeshBuffer* meshBuffer, irr::u32 materialIndex,
|
||||
ISceneNode* node, s32 minimalPolysPerNode)
|
||||
{
|
||||
if ( !meshBuffer)
|
||||
return 0;
|
||||
|
||||
return new COctreeTriangleSelector(meshBuffer, materialIndex, node, minimalPolysPerNode);
|
||||
}
|
||||
|
||||
//! Creates a meta triangle selector.
|
||||
IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector()
|
||||
|
|
|
@ -359,6 +359,10 @@ namespace scene
|
|||
virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh,
|
||||
ISceneNode* node, s32 minimalPolysPerNode) _IRR_OVERRIDE_;
|
||||
|
||||
//! Creates a simple ITriangleSelector, based on a meshbuffer.
|
||||
virtual ITriangleSelector* createOctreeTriangleSelector(IMeshBuffer* meshBuffer, irr::u32 materialIndex,
|
||||
ISceneNode* node, s32 minimalPolysPerNode=32) _IRR_OVERRIDE_;
|
||||
|
||||
//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
|
||||
virtual ITriangleSelector* createTriangleSelectorFromBoundingBox(
|
||||
ISceneNode* node) _IRR_OVERRIDE_;
|
||||
|
|
Loading…
Reference in New Issue