Commit 74658ced authored by Rogerborg's avatar Rogerborg

https://sourceforge.net/tracker2/index.php?func=detail&aid=2498791&group_id=74339&atid=540678

Extend ITriangleSelector::getTriangles() to allow for returning multiple groups of triangles from individual scene nodes.  By default, the 1.5 behaviour will be preserved, and all triangles from all nodes will be returned, even for IMetaTriangleSelectors.  Regression tests confirm this.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2124 dfc29bdd-3216-0410-991c-e03cc46cb475
parent e7711716
......@@ -16,6 +16,8 @@ namespace irr
namespace scene
{
class ISceneNode;
//! Interface to return triangles with specific properties.
/** Every ISceneNode may have a triangle selector, available with
ISceneNode::getTriangleScelector() or ISceneManager::createTriangleSelector.
......@@ -33,8 +35,13 @@ public:
//! Returns amount of all available triangles in this selector
virtual s32 getTriangleCount() const = 0;
//! Gets all triangles.
/** \param triangles: Array where the resulting triangles will be
//! Gets the triangles for one associated node.
/**
This returns all triangles for one scene node associated with this
selector. If there is more than one scene node associated (e.g. for
an IMetaTriangleSelector) this this function may be called multiple
times to retrieve all triangles.
\param triangles: Array where the resulting triangles will be
written to.
\param arraySize: Size of the target array.
\param outTriangleCount: Amount of triangles which have been written
......@@ -42,13 +49,33 @@ public:
\param transform: Pointer to matrix for transforming the triangles
before they are returned. Useful for example to scale all triangles
down into an ellipsoid space. If this pointer is null, no
transformation will be done. */
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform=0) const = 0;
transformation will be done.
\param node: On input, if this is 0 then all triangles for all nodes
will be returned. If *node is 0, or a node that is not associated
with any of the triangles in this selector, then the selector will return
the triangles for its first (or only) associated node. If you pass in
a node for which the selector holds triangles, then it will return
the triangles for the *next* node. On output, *node will return the node
that is associated with the triangles being returned.
\return false if the triangles and node for the last (or only) node
are being returned. true if there are more nodes and triangles to
return; on true, you may call this method again, passing in the same
node that was just returned in order to retrieve the triangles for the
next node.
*/
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform=0,
const ISceneNode * * node = 0) const = 0;
//! Gets the triangles for one associated node which lie or may lie within a specific bounding box.
/**
This returns all triangles for one scene node associated with this
selector. If there is more than one scene node associated (e.g. for
an IMetaTriangleSelector) this this function may be called multiple
times to retrieve all triangles.
//! Gets all triangles which lie within a specific bounding box.
/** Please note that unoptimized triangle selectors also may return
triangles which are not in the specific box at all.
Please note that unoptimized triangle selectors also may return
triangles which are not in the specified box at all.
\param triangles: Array where the resulting triangles will be written
to.
\param arraySize: Size of the target array.
......@@ -59,13 +86,33 @@ public:
\param transform: Pointer to matrix for transforming the triangles
before they are returned. Useful for example to scale all triangles
down into an ellipsoid space. If this pointer is null, no
transformation will be done. */
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
transformation will be done.
\param node: On input, if this is 0 then all triangles for all nodes
will be returned. If *node is 0, or a node that is not associated
with any of the triangles in this selector, then the selector will return
the triangles for its first (or only) associated node. If you pass in
a node for which the selector holds triangles, then it will return
the triangles for the *next* node. On output, *node will return the node
that is associated with the triangles being returned.
\return false if the triangles and node for the last (or only) node
are being returned. true if there are more nodes and triangles to
return; on true, you may call this method again, passing in the same
node that was just returned in order to retrieve the triangles for the
next node.
*/
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::aabbox3d<f32>& box,
const core::matrix4* transform=0) const = 0;
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const = 0;
//! Gets all triangles which have or may have contact with a 3d line.
/** Please note that unoptimized triangle selectors also may return
//! Gets the triangles for one associated node which have or may have contact with a 3d line.
/**
This returns all triangles for one scene node associated with this
selector. If there is more than one scene node associated (e.g. for
an IMetaTriangleSelector) this this function may be called multiple
times to retrieve all triangles.
Please note that unoptimized triangle selectors also may return
triangles which are not in contact at all with the 3d line.
\param triangles: Array where the resulting triangles will be written
to.
......@@ -77,10 +124,27 @@ public:
\param transform: Pointer to matrix for transforming the triangles
before they are returned. Useful for example to scale all triangles
down into an ellipsoid space. If this pointer is null, no
transformation will be done. */
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
transformation will be done.
\param node: On input, if this is 0 then all triangles for all nodes
will be returned. If *node is 0, or a node that is not associated
with any of the triangles in this selector, then the selector will return
the triangles for its first (or only) associated node. If you pass in
a node for which the selector holds triangles, then it will return
the triangles for the *next* node. On output, *node will return the node
that is associated with the triangles being returned.
\return false if the triangles and node for the last (or only) node
are being returned. true if there are more nodes and triangles to
return; on true, you may call this method again, passing in the same
node that was just returned in order to retrieve the triangles for the
next node.
*/
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform=0) const = 0;
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const = 0;
//! Gets the scene node to which this selector is associated.
virtual const ISceneNode* getSceneNode(void) const = 0;
};
} // end namespace scene
......
......@@ -37,57 +37,163 @@ s32 CMetaTriangleSelector::getTriangleCount() const
//! Gets all triangles.
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform) const
bool CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform,
const ISceneNode * * node) const
{
s32 outWritten = 0;
if(node)
{
if(TriangleSelectors.size() == 0)
{
*node = 0;
return false;
}
u32 selector = 0;
for (u32 i=0; i<TriangleSelectors.size(); ++i)
if(*node == TriangleSelectors[i]->getSceneNode())
{
selector = i;
break;
}
s32 t = 0;
TriangleSelectors[i]->getTriangles(triangles + outWritten, arraySize - outWritten, t, transform);
TriangleSelectors[selector]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
transform);
outWritten += t;
*node = TriangleSelectors[selector]->getSceneNode();
if(selector < TriangleSelectors.size() - 1)
return true;
}
else
{
for (u32 i=0; i<TriangleSelectors.size(); ++i)
{
s32 t = 0;
TriangleSelectors[i]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
transform);
outWritten += t;
}
}
outTriangleCount = outWritten;
return false;
}
//! Gets all triangles which lie within a specific bounding box.
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
bool CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::aabbox3d<f32>& box,
const core::matrix4* transform) const
const core::matrix4* transform,
const ISceneNode * * node) const
{
s32 outWritten = 0;
if(node)
{
if(TriangleSelectors.size() == 0)
{
*node = 0;
return false;
}
u32 selector = 0;
for (u32 i=0; i<TriangleSelectors.size(); ++i)
if(*node == TriangleSelectors[i]->getSceneNode())
{
selector = i;
break;
}
s32 t = 0;
TriangleSelectors[selector]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
box, transform);
outWritten += t;
*node = TriangleSelectors[selector]->getSceneNode();
if(selector < TriangleSelectors.size() - 1)
return true;
}
else
{
for (u32 i=0; i<TriangleSelectors.size(); ++i)
{
s32 t = 0;
TriangleSelectors[i]->getTriangles(triangles + outWritten, arraySize - outWritten, t,
TriangleSelectors[i]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
box, transform);
outWritten += t;
}
}
outTriangleCount = outWritten;
return false;
}
//! Gets all triangles which have or may have contact with a 3d line.
void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
bool CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform) const
const core::matrix4* transform,
const ISceneNode * * node) const
{
s32 outWritten = 0;
if(node)
{
if(TriangleSelectors.size() == 0)
{
*node = 0;
return false;
}
u32 selector = 0;
for (u32 i=0; i<TriangleSelectors.size(); ++i)
if(*node == TriangleSelectors[i]->getSceneNode())
{
selector = i;
break;
}
s32 t = 0;
TriangleSelectors[i]->getTriangles(triangles + outWritten, arraySize - outWritten, t,
TriangleSelectors[selector]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
line, transform);
outWritten += t;
*node = TriangleSelectors[selector]->getSceneNode();
if(selector < TriangleSelectors.size() - 1)
return true;
}
else
{
for (u32 i=0; i<TriangleSelectors.size(); ++i)
{
s32 t = 0;
TriangleSelectors[i]->getTriangles(triangles + outWritten,
arraySize - outWritten, t,
line, transform);
outWritten += t;
}
}
outTriangleCount = outWritten;
return false;
}
......
......@@ -28,18 +28,21 @@ public:
virtual s32 getTriangleCount() const;
//! Gets all triangles.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform=0) const;
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! Gets all triangles which lie within a specific bounding box.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::aabbox3d<f32>& box,
const core::matrix4* transform=0) const;
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! Gets all triangles which have or may have contact with a 3d line.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform=0) const;
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! Adds a triangle selector to the collection of triangle selectors
//! in this metaTriangleSelector.
......@@ -51,6 +54,9 @@ public:
//! Removes all triangle selectors from the collection.
virtual void removeAllTriangleSelectors();
//! *This* selector isn't associated with any specific node
virtual const ISceneNode* getSceneNode(void) const { return 0; }
private:
core::array<ITriangleSelector*> TriangleSelectors;
......
......@@ -109,10 +109,11 @@ void COctTreeTriangleSelector::constructOctTree(SOctTreeNode* node)
//! Gets all triangles which lie within a specific bounding box.
void COctTreeTriangleSelector::getTriangles(core::triangle3df* triangles,
bool COctTreeTriangleSelector::getTriangles(core::triangle3df* triangles,
s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box,
const core::matrix4* transform) const
const core::matrix4* transform,
const ISceneNode * * node) const
{
core::matrix4 mat;
core::aabbox3d<f32> invbox = box;
......@@ -139,6 +140,10 @@ void COctTreeTriangleSelector::getTriangles(core::triangle3df* triangles,
arraySize, invbox, &mat, triangles);
outTriangleCount = trianglesWritten;
if(node)
*node = SceneNode;
return false;
}
......@@ -173,9 +178,10 @@ void COctTreeTriangleSelector::getTrianglesFromOctTree(
//! Gets all triangles which have or may have contact with a 3d line.
void COctTreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
bool COctTreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform) const
const core::matrix4* transform,
const ISceneNode * * node) const
{
core::aabbox3d<f32> box(line.start);
box.addInternalPoint(line.end);
......@@ -183,6 +189,10 @@ void COctTreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 ar
// TODO: Could be optimized for line a little bit more.
COctTreeTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount,
box, transform);
if(node)
*node = SceneNode;
return false;
}
......
......@@ -25,13 +25,15 @@ public:
virtual ~COctTreeTriangleSelector();
//! Gets all triangles which lie within a specific bounding box.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box, const core::matrix4* transform=0) const;
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box, const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! Gets all triangles which have or may have contact with a 3d line.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform=0) const;
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
private:
......
......@@ -75,8 +75,8 @@ void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD)
}
//! Gets all triangles.
void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform ) const
bool CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform, const ISceneNode * * node) const
{
s32 count = TrianglePatches.TotalTriangles;
......@@ -106,13 +106,17 @@ void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32
}
outTriangleCount = tIndex;
if(node)
*node = SceneNode;
return false;
}
//! Gets all triangles which lie within a specific bounding box.
void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize,
bool CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::aabbox3d<f32>& box,
const core::matrix4* transform) const
const core::matrix4* transform, const ISceneNode * * node) const
{
s32 count = TrianglePatches.TotalTriangles;
......@@ -143,12 +147,16 @@ void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32
}
outTriangleCount = tIndex;
if(node)
*node = SceneNode;
return false;
}
//! Gets all triangles which have or may have contact with a 3d line.
void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
bool CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform) const
const core::matrix4* transform, const ISceneNode * * node) const
{
const s32 count = core::min_((s32)TrianglePatches.TotalTriangles, arraySize);
......@@ -178,6 +186,10 @@ void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles, s32 ar
}
outTriangleCount = tIndex;
if(node)
*node = SceneNode;
return false;
}
//! Returns amount of all available triangles in this selector
......
......@@ -37,21 +37,27 @@ public:
virtual void setTriangleData (ITerrainSceneNode* node, s32 LOD);
//! Gets all triangles.
void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::matrix4* transform=0) const;
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! 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) const;
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box, const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! Gets all triangles which have or may have contact with a 3d line.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform=0) const;
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! Returns amount of all available triangles in this selector
virtual s32 getTriangleCount() const;
//! ITerrainSceneNode is an ISceneNode, we just don't know it yet.
virtual const ISceneNode* getSceneNode(void) const { return (ISceneNode*)SceneNode; }
private:
friend class CTerrainSceneNode;
......
......@@ -24,12 +24,13 @@ CTriangleBBSelector::CTriangleBBSelector(const ISceneNode* node)
//! Gets all triangles.
void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
bool CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
s32 arraySize, s32& outTriangleCount,
const core::matrix4* transform) const
const core::matrix4* transform,
const ISceneNode * * node) const
{
if (!SceneNode)
return;
return false;
// construct triangles
const core::aabbox3d<f32>& box = SceneNode->getBoundingBox();
......@@ -56,6 +57,10 @@ void CTriangleBBSelector::getTriangles(core::triangle3df* triangles,
// call parent
CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform);
if(node)
*node = SceneNode;
return false;
}
......
......@@ -21,8 +21,8 @@ public:
CTriangleBBSelector(const ISceneNode* node);
//! Gets all triangles.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::matrix4* transform=0) const;
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::matrix4* transform=0, const ISceneNode * * node = 0) const;
};
} // end namespace scene
......
......@@ -67,9 +67,10 @@ CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, const IScen
//! Gets all triangles.
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
bool CTriangleSelector::getTriangles(core::triangle3df* triangles,
s32 arraySize, s32& outTriangleCount,
const core::matrix4* transform) const
const core::matrix4* transform,
const ISceneNode * * node) const
{
s32 cnt = Triangles.size();
if (cnt > arraySize)
......@@ -92,29 +93,36 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
}
outTriangleCount = cnt;
if(node)
*node = SceneNode;
return false;
}
//! Gets all triangles which lie within a specific bounding box.
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
bool CTriangleSelector::getTriangles(core::triangle3df* triangles,
s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box,
const core::matrix4* transform) const
const core::matrix4* transform,
const ISceneNode * * node) const
{
// return all triangles
getTriangles(triangles, arraySize, outTriangleCount, transform);
return getTriangles(triangles, arraySize, outTriangleCount, transform, node);
}
//! Gets all triangles which have or may have contact with a 3d line.
void CTriangleSelector::getTriangles(core::triangle3df* triangles,
bool CTriangleSelector::getTriangles(core::triangle3df* triangles,
s32 arraySize, s32& outTriangleCount,
const core::line3d<f32>& line,
const core::matrix4* transform) const
const core::matrix4* transform,
const ISceneNode * * node) const
{
// return all triangles
getTriangles(triangles, arraySize, outTriangleCount, transform);
return getTriangles(triangles, arraySize, outTriangleCount, transform, node);
}
......
......@@ -31,21 +31,27 @@ public:
CTriangleSelector(const core::aabbox3d<f32>& box, const ISceneNode* node);
//! Gets all triangles.
void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::matrix4* transform=0) const;
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! 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) const;
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box, const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! Gets all triangles which have or may have contact with a 3d line.
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
virtual bool getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform=0) const;
const core::matrix4* transform=0,
const ISceneNode * * node = 0) const;
//! Returns amount of all available triangles in this selector
virtual s32 getTriangleCount() const;
//! Gets the scene node to which this selector is associated.
virtual const ISceneNode* getSceneNode(void) const { return SceneNode; }
protected:
const ISceneNode* SceneNode;
......
Test suite pass at GMT Thu Jan 22 12:59:05 2009
Test suite pass at GMT Thu Jan 22 14:10:54 2009
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment