Commit d4e32d2a authored by hybrid's avatar hybrid

Triangle selector improvements suggested by rogerborg a long time ago. Now...

Triangle selector improvements suggested by rogerborg a long time ago. Now fixed and properly working.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3984 dfc29bdd-3216-0410-991c-e03cc46cb475
parent c2e1206e
...@@ -19,6 +19,21 @@ CTriangleSelector::CTriangleSelector(ISceneNode* node) ...@@ -19,6 +19,21 @@ CTriangleSelector::CTriangleSelector(ISceneNode* node)
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CTriangleSelector"); setDebugName("CTriangleSelector");
#endif #endif
BoundingBox.reset(0.f, 0.f, 0.f);
}
//! constructor
CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node)
: SceneNode(node)
{
#ifdef _DEBUG
setDebugName("CTriangleSelector");
#endif
BoundingBox.reset(0.f, 0.f, 0.f);
// TODO
} }
...@@ -33,6 +48,7 @@ CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node) ...@@ -33,6 +48,7 @@ CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node)
createFromMesh(mesh); createFromMesh(mesh);
} }
CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node) CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node)
: SceneNode(reinterpret_cast<ISceneNode*>(node)), AnimatedNode(node) : SceneNode(reinterpret_cast<ISceneNode*>(node)), AnimatedNode(node)
{ {
...@@ -53,6 +69,7 @@ CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node) ...@@ -53,6 +69,7 @@ CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node)
createFromMesh(mesh); createFromMesh(mesh);
} }
void CTriangleSelector::createFromMesh(const IMesh * mesh) void CTriangleSelector::createFromMesh(const IMesh * mesh)
{ {
const u32 cnt = mesh->getMeshBufferCount(); const u32 cnt = mesh->getMeshBufferCount();
...@@ -61,6 +78,7 @@ void CTriangleSelector::createFromMesh(const IMesh * mesh) ...@@ -61,6 +78,7 @@ void CTriangleSelector::createFromMesh(const IMesh * mesh)
totalFaceCount += mesh->getMeshBuffer(j)->getIndexCount(); totalFaceCount += mesh->getMeshBuffer(j)->getIndexCount();
totalFaceCount /= 3; totalFaceCount /= 3;
Triangles.reallocate(totalFaceCount); Triangles.reallocate(totalFaceCount);
BoundingBox.reset(0.f, 0.f, 0.f);
for (u32 i=0; i<cnt; ++i) for (u32 i=0; i<cnt; ++i)
{ {
...@@ -75,10 +93,15 @@ void CTriangleSelector::createFromMesh(const IMesh * mesh) ...@@ -75,10 +93,15 @@ void CTriangleSelector::createFromMesh(const IMesh * mesh)
buf->getPosition(indices[j+0]), buf->getPosition(indices[j+0]),
buf->getPosition(indices[j+1]), buf->getPosition(indices[j+1]),
buf->getPosition(indices[j+2]))); buf->getPosition(indices[j+2])));
const core::triangle3df& tri = Triangles.getLast();
BoundingBox.addInternalPoint(tri.pointA);
BoundingBox.addInternalPoint(tri.pointB);
BoundingBox.addInternalPoint(tri.pointC);
} }
} }
} }
void CTriangleSelector::updateFromMesh(const IMesh* mesh) const void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
{ {
if (!mesh) if (!mesh)
...@@ -87,68 +110,27 @@ void CTriangleSelector::updateFromMesh(const IMesh* mesh) const ...@@ -87,68 +110,27 @@ void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
u32 meshBuffers = mesh->getMeshBufferCount(); u32 meshBuffers = mesh->getMeshBufferCount();
u32 triangleCount = 0; u32 triangleCount = 0;
BoundingBox.reset(0.f, 0.f, 0.f);
for (u32 i = 0; i < meshBuffers; ++i) for (u32 i = 0; i < meshBuffers; ++i)
{ {
IMeshBuffer* buf = mesh->getMeshBuffer(i); IMeshBuffer* buf = mesh->getMeshBuffer(i);
u32 idxCnt = buf->getIndexCount(); u32 idxCnt = buf->getIndexCount();
const u16* indices = buf->getIndices(); const u16* indices = buf->getIndices();
switch (buf->getVertexType())
{
case video::EVT_STANDARD:
{
video::S3DVertex* vtx = (video::S3DVertex*)buf->getVertices();
for (u32 index = 0; index < idxCnt; index += 3) for (u32 index = 0; index < idxCnt; index += 3)
{ {
core::triangle3df & tri = Triangles[triangleCount++]; core::triangle3df& tri = Triangles[triangleCount++];
tri.pointA = vtx[indices[index + 0]].Pos; tri.pointA = buf->getPosition(indices[index + 0]);
tri.pointB = vtx[indices[index + 1]].Pos; tri.pointB = buf->getPosition(indices[index + 1]);
tri.pointC = vtx[indices[index + 2]].Pos; tri.pointC = buf->getPosition(indices[index + 2]);
BoundingBox.addInternalPoint(tri.pointA);
BoundingBox.addInternalPoint(tri.pointB);
BoundingBox.addInternalPoint(tri.pointC);
} }
} }
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buf->getVertices();
for (u32 index = 0; index < idxCnt; index += 3)
{
core::triangle3df & tri = Triangles[triangleCount++];
tri.pointA = vtx[indices[index + 0]].Pos;
tri.pointB = vtx[indices[index + 1]].Pos;
tri.pointC = vtx[indices[index + 2]].Pos;
}
}
break;
case video::EVT_TANGENTS:
{
video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buf->getVertices();
for (u32 index = 0; index < idxCnt; index += 3)
{
core::triangle3df & tri = Triangles[triangleCount++];
tri.pointA = vtx[indices[index + 0]].Pos;
tri.pointB = vtx[indices[index + 1]].Pos;
tri.pointC = vtx[indices[index + 2]].Pos;
}
}
break;
}
}
}
//! constructor
CTriangleSelector::CTriangleSelector(const core::aabbox3d<f32>& box, ISceneNode* node)
: SceneNode(node)
{
#ifdef _DEBUG
setDebugName("CTriangleSelector");
#endif
// TODO
} }
void CTriangleSelector::update(void) const void CTriangleSelector::update(void) const
{ {
if (!AnimatedNode) if (!AnimatedNode)
...@@ -170,6 +152,7 @@ void CTriangleSelector::update(void) const ...@@ -170,6 +152,7 @@ void CTriangleSelector::update(void) const
} }
} }
//! Gets all triangles. //! Gets all triangles.
void CTriangleSelector::getTriangles(core::triangle3df* triangles, void CTriangleSelector::getTriangles(core::triangle3df* triangles,
s32 arraySize, s32& outTriangleCount, s32 arraySize, s32& outTriangleCount,
...@@ -178,19 +161,17 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles, ...@@ -178,19 +161,17 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
// Update my triangles if necessary // Update my triangles if necessary
update(); update();
s32 cnt = Triangles.size(); u32 cnt = Triangles.size();
if (cnt > arraySize) if (cnt > (u32)arraySize)
cnt = arraySize; cnt = (u32)arraySize;
core::matrix4 mat; core::matrix4 mat;
if (transform) if (transform)
mat = *transform; mat = *transform;
if (SceneNode) if (SceneNode)
mat *= SceneNode->getAbsoluteTransformation(); mat *= SceneNode->getAbsoluteTransformation();
for (s32 i=0; i<cnt; ++i) for (u32 i=0; i<cnt; ++i)
{ {
mat.transformVect( triangles[i].pointA, Triangles[i].pointA ); mat.transformVect( triangles[i].pointA, Triangles[i].pointA );
mat.transformVect( triangles[i].pointB, Triangles[i].pointB ); mat.transformVect( triangles[i].pointB, Triangles[i].pointB );
...@@ -201,15 +182,53 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles, ...@@ -201,15 +182,53 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
} }
//! Gets all triangles which lie within a specific bounding box. //! Gets all triangles which lie within a specific bounding box.
void CTriangleSelector::getTriangles(core::triangle3df* triangles, void CTriangleSelector::getTriangles(core::triangle3df* triangles,
s32 arraySize, s32& outTriangleCount, s32 arraySize, s32& outTriangleCount,
const core::aabbox3d<f32>& box, const core::aabbox3d<f32>& box,
const core::matrix4* transform) const const core::matrix4* transform) const
{ {
// return all triangles core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
return getTriangles(triangles, arraySize, outTriangleCount, transform); core::aabbox3df tBox(box);
if (SceneNode)
{
SceneNode->getAbsoluteTransformation().getInverse(mat);
mat.transformBoxEx(tBox);
}
if (transform)
mat = *transform;
else
mat.makeIdentity();
if (SceneNode)
mat *= SceneNode->getAbsoluteTransformation();
outTriangleCount = 0;
if (!tBox.intersectsWithBox(BoundingBox))
return;
s32 triangleCount = 0;
const u32 cnt = Triangles.size();
for (u32 i=0; i<cnt; ++i)
{
// This isn't an accurate test, but it's fast, and the
// API contract doesn't guarantee complete accuracy.
if (Triangles[i].isTotalOutsideBox(tBox))
continue;
triangles[triangleCount] = Triangles[i];
mat.transformVect(triangles[triangleCount].pointA);
mat.transformVect(triangles[triangleCount].pointB);
mat.transformVect(triangles[triangleCount].pointC);
++triangleCount;
if (triangleCount == arraySize)
break;
}
outTriangleCount = triangleCount;
} }
...@@ -219,8 +238,12 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles, ...@@ -219,8 +238,12 @@ void CTriangleSelector::getTriangles(core::triangle3df* triangles,
const core::line3d<f32>& line, const core::line3d<f32>& line,
const core::matrix4* transform) const const core::matrix4* transform) const
{ {
// return all triangles core::aabbox3d<f32> box(line.start);
return getTriangles(triangles, arraySize, outTriangleCount, transform); box.addInternalPoint(line.end);
// TODO: Could be optimized for line a little bit more.
getTriangles(triangles, arraySize, outTriangleCount,
box, transform);
} }
...@@ -266,4 +289,3 @@ const ITriangleSelector* CTriangleSelector::getSelector(u32 index) const ...@@ -266,4 +289,3 @@ const ITriangleSelector* CTriangleSelector::getSelector(u32 index) const
} // end namespace scene } // end namespace scene
} // end namespace irr } // end namespace irr
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ITriangleSelector.h" #include "ITriangleSelector.h"
#include "IMesh.h" #include "IMesh.h"
#include "irrArray.h" #include "irrArray.h"
#include "aabbox3d.h"
namespace irr namespace irr
{ {
...@@ -77,6 +78,7 @@ protected: ...@@ -77,6 +78,7 @@ protected:
ISceneNode* SceneNode; ISceneNode* SceneNode;
mutable core::array<core::triangle3df> Triangles; // (mutable for CTriangleBBSelector) mutable core::array<core::triangle3df> Triangles; // (mutable for CTriangleBBSelector)
mutable core::aabbox3df BoundingBox; // Allows for trivial rejection
IAnimatedMeshSceneNode* AnimatedNode; IAnimatedMeshSceneNode* AnimatedNode;
mutable s32 LastMeshFrame; mutable s32 LastMeshFrame;
......
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