CTriangleSelector can now be created for a single meshbuffer.

It can still update with a node transformation, but it won't update when the mesh changes (so only useful for static meshes, not for animated ones).

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5351 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2016-12-06 17:10:57 +00:00
parent a20f01131a
commit 543e70dc34
7 changed files with 98 additions and 9 deletions

View File

@ -36,7 +36,7 @@ namespace scene
ISceneNode* Node;
//! Meshbuffer which contained the triangle (is 0 when the selector doesn't have that information, only works when selectors are created per meshbuffer)
IMeshBuffer* MeshBuffer;
const IMeshBuffer* MeshBuffer;
//! Index of selected material of the triangle in the SceneNode. Usually only valid when MeshBuffer is also set, otherwise always 0
irr::u32 MaterialIndex;

View File

@ -1271,7 +1271,7 @@ namespace scene
s->drop();
\endcode
\param mesh: Mesh of which the triangles are taken.
\param node: Scene node of which visibility and transformation is used.
\param node: Scene node of which transformation is used.
\param separateMeshbuffers: When true it's possible to get information which meshbuffer
got hit in collision tests. But has a slight speed cost.
\return The selector, or null if not successful.
@ -1279,6 +1279,15 @@ namespace scene
See IReferenceCounted::drop() for more information. */
virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node, bool separateMeshbuffers=false) = 0;
//! Creates a simple ITriangleSelector, based on a meshbuffer.
/**
This is a static selector which won't update when the mesh changes.
\param meshBuffer Triangles of that meshbuffer are used
\param materialIndex If you pass a material index that index can be returned by the triangle selector.
\para node: Scene node of which transformation is used.
*/
virtual ITriangleSelector* createTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node) = 0;
//! Creates a simple ITriangleSelector, based on an animated mesh scene node.
/** Details of the mesh associated with the node will be extracted internally.
\param node The animated mesh scene node from which to build the selector

View File

@ -56,7 +56,7 @@ struct SCollisionTriangleRange
//! Meshbuffer from which the triangles are from
//! Is 0 when the ITriangleSelector doesn't support meshbuffer selection
IMeshBuffer* MeshBuffer;
const IMeshBuffer* MeshBuffer;
//! Index of selected material in the SceneNode. Usually only valid when MeshBuffer is also set, otherwise always 0
irr::u32 MaterialIndex;

View File

@ -1855,6 +1855,13 @@ ITriangleSelector* CSceneManager::createTriangleSelector(IMesh* mesh, ISceneNode
return new CTriangleSelector(mesh, node, separateMeshbuffers);
}
ITriangleSelector* CSceneManager::createTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node)
{
if ( !meshBuffer)
return 0;
return new CTriangleSelector(meshBuffer, materialIndex, node);
}
//! Creates a ITriangleSelector, based on a the mesh owned by an animated scene node
ITriangleSelector* CSceneManager::createTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers)

View File

@ -345,6 +345,9 @@ namespace scene
//! Creates a simple ITriangleSelector, based on a mesh.
virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node, bool separateMeshbuffers) _IRR_OVERRIDE_;
//! Creates a simple ITriangleSelector, based on a meshbuffer.
virtual ITriangleSelector* createTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node) _IRR_OVERRIDE_;
//! Creates a simple ITriangleSelector, based on an animated mesh scene node.
//! Details of the mesh associated with the node will be extracted internally.
//! Call ITriangleSelector::update() to have the triangle selector updated based

View File

@ -15,7 +15,7 @@ namespace scene
//! constructor
CTriangleSelector::CTriangleSelector(ISceneNode* node)
: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
: SceneNode(node), MeshBuffer(0), MaterialIndex(0), AnimatedNode(0), LastMeshFrame(0)
{
#ifdef _DEBUG
setDebugName("CTriangleSelector");
@ -27,7 +27,7 @@ CTriangleSelector::CTriangleSelector(ISceneNode* node)
//! constructor
CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node)
: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
: SceneNode(node), MeshBuffer(0), MaterialIndex(0), AnimatedNode(0), LastMeshFrame(0)
{
#ifdef _DEBUG
setDebugName("CTriangleSelector");
@ -40,7 +40,7 @@ CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode*
//! constructor
CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node, bool separateMeshbuffers)
: SceneNode(node), AnimatedNode(0), LastMeshFrame(0)
: SceneNode(node), MeshBuffer(0), MaterialIndex(0), AnimatedNode(0), LastMeshFrame(0)
{
#ifdef _DEBUG
setDebugName("CTriangleSelector");
@ -49,6 +49,15 @@ CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node, bool s
createFromMesh(mesh, separateMeshbuffers);
}
CTriangleSelector::CTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node)
: SceneNode(node), MeshBuffer(meshBuffer), MaterialIndex(materialIndex), AnimatedNode(0), LastMeshFrame(0)
{
#ifdef _DEBUG
setDebugName("CTriangleSelector");
#endif
createFromMeshBuffer(meshBuffer);
}
CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers)
: SceneNode(node), AnimatedNode(node), LastMeshFrame(0)
@ -100,6 +109,19 @@ void CTriangleSelector::createFromMesh(const IMesh* mesh, bool createBufferRange
updateFromMesh(mesh);
}
void CTriangleSelector::createFromMeshBuffer(const IMeshBuffer* meshBuffer)
{
BufferRanges.clear();
Triangles.clear();
if ( meshBuffer )
{
Triangles.set_used(meshBuffer->getIndexCount() / 3);
}
updateFromMeshBuffer(meshBuffer);
}
template <typename TIndex>
static void updateTriangles(u32& triangleCount, core::array<core::triangle3df>& triangles, u32 idxCnt, const TIndex* indices, const u8* vertices, u32 vertexPitch, const core::matrix4* bufferTransform)
{
@ -167,10 +189,41 @@ void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
}
// Update bounding box
if ( triangleCount )
updateBoundingBox();
}
void CTriangleSelector::updateFromMeshBuffer(const IMeshBuffer* meshBuffer) const
{
if ( !meshBuffer )
return;
u32 idxCnt = meshBuffer->getIndexCount();
u32 vertexPitch = getVertexPitchFromType(meshBuffer->getVertexType());
u8* vertices = (u8*)meshBuffer->getVertices();
u32 triangleCount = 0;
switch ( meshBuffer->getIndexType() )
{
case video::EIT_16BIT:
{
const u16* indices = meshBuffer->getIndices();
updateTriangles(triangleCount, Triangles, idxCnt, indices, vertices, vertexPitch, 0);
}
break;
case video::EIT_32BIT:
{
const u32* indices = (u32*)meshBuffer->getIndices();
updateTriangles(triangleCount, Triangles, idxCnt, indices, vertices, vertexPitch, 0);
}
break;
}
}
void CTriangleSelector::updateBoundingBox() const
{
if ( !Triangles.empty() )
{
BoundingBox.reset( Triangles[0].pointA );
for (u32 i=0; i < triangleCount; ++i)
for (u32 i=0; i < Triangles.size(); ++i)
{
const core::triangle3df& tri = Triangles[i];
BoundingBox.addInternalPoint(tri.pointA);
@ -184,7 +237,6 @@ void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
}
}
void CTriangleSelector::update(void) const
{
if (!AnimatedNode)
@ -243,6 +295,8 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
triRange.RangeSize = cnt;
triRange.Selector = const_cast<CTriangleSelector*>(this);
triRange.SceneNode = SceneNode;
triRange.MeshBuffer = MeshBuffer;
triRange.MaterialIndex = MaterialIndex;
outTriangleInfo->push_back(triRange);
}
else
@ -381,6 +435,8 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
triRange.RangeSize = triangleCount;
triRange.Selector = const_cast<CTriangleSelector*>(this);
triRange.SceneNode = SceneNode;
triRange.MeshBuffer = MeshBuffer;
triRange.MaterialIndex = MaterialIndex;
outTriangleInfo->push_back(triRange);
}
}

View File

@ -29,6 +29,9 @@ public:
//! Constructs a selector based on a mesh
CTriangleSelector(const IMesh* mesh, ISceneNode* node, bool separateMeshbuffers);
//! Constructs a selector based on a meshbuffer
CTriangleSelector(const IMeshBuffer* meshBuffer, irr::u32 materialIndex, ISceneNode* node);
//! Constructs a selector based on an animated mesh scene node
//!\param node An animated mesh scene node, which must have a valid mesh
CTriangleSelector(IAnimatedMeshSceneNode* node, bool separateMeshbuffers);
@ -71,9 +74,18 @@ protected:
//! Create from a mesh
virtual void createFromMesh(const IMesh* mesh, bool createBufferRanges);
//! Create from a meshbuffer
virtual void createFromMeshBuffer(const IMeshBuffer* meshBuffer);
//! Update when the mesh has changed
virtual void updateFromMesh(const IMesh* mesh) const;
//! Update when the meshbuffer has changed
virtual void updateFromMeshBuffer(const IMeshBuffer* meshBuffer) const;
//! Update bounding box from triangles
void updateBoundingBox() const;
//! Update the triangle selector, which will only have an effect if it
//! was built from an animated mesh and that mesh's frame has changed
//! since the last time it was updated.
@ -85,6 +97,8 @@ protected:
mutable core::array<core::triangle3df> Triangles; // (mutable for CTriangleBBSelector)
mutable core::aabbox3df BoundingBox; // Allows for trivial rejection
const IMeshBuffer* MeshBuffer; // non-zero when the selector is for a single meshbuffer
irr::u32 MaterialIndex; // Only set when MeshBuffer is non-zero
IAnimatedMeshSceneNode* AnimatedNode;
mutable u32 LastMeshFrame;
};