diff options
Diffstat (limited to 'source/Irrlicht/COctreeTriangleSelector.cpp')
-rw-r--r-- | source/Irrlicht/COctreeTriangleSelector.cpp | 327 |
1 files changed, 0 insertions, 327 deletions
diff --git a/source/Irrlicht/COctreeTriangleSelector.cpp b/source/Irrlicht/COctreeTriangleSelector.cpp deleted file mode 100644 index a762746..0000000 --- a/source/Irrlicht/COctreeTriangleSelector.cpp +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#include "COctreeTriangleSelector.h"
-#include "ISceneNode.h"
-
-#include "os.h"
-
-namespace irr
-{
-namespace scene
-{
-
-//! constructor
-COctreeTriangleSelector::COctreeTriangleSelector(const IMesh* mesh,
- ISceneNode* node, s32 minimalPolysPerNode)
- : CTriangleSelector(mesh, node, false)
- , 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);
- }
-}
-
-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()
-{
- delete Root;
-}
-
-
-void COctreeTriangleSelector::constructOctree(SOctreeNode* node)
-{
- ++NodeCount;
-
- node->Box.reset(node->Triangles[0].pointA);
-
- // get bounding box
- const u32 cnt = node->Triangles.size();
- for (u32 i=0; i<cnt; ++i)
- {
- node->Box.addInternalPoint(node->Triangles[i].pointA);
- node->Box.addInternalPoint(node->Triangles[i].pointB);
- node->Box.addInternalPoint(node->Triangles[i].pointC);
- }
-
- // calculate children
-
- if (!node->Box.isEmpty() && (s32)node->Triangles.size() > MinimalPolysPerNode)
- {
- const core::vector3df& middle = node->Box.getCenter();
- core::vector3df edges[8];
- node->Box.getEdges(edges);
-
- core::aabbox3d<f32> box;
- core::array<core::triangle3df> keepTriangles(node->Triangles.size()); // reserving enough memory, so we don't get re-allocations per child
-
- for (s32 ch=0; ch<8; ++ch)
- {
- box.reset(middle);
- box.addInternalPoint(edges[ch]);
- node->Child[ch] = new SOctreeNode();
-
- for (s32 i=0; i<(s32)node->Triangles.size(); ++i)
- {
- if (node->Triangles[i].isTotalInsideBox(box))
- {
- node->Child[ch]->Triangles.push_back(node->Triangles[i]);
- //node->Triangles.erase(i);
- //--i;
- }
- else
- {
- keepTriangles.push_back(node->Triangles[i]);
- }
- }
- memcpy(node->Triangles.pointer(), keepTriangles.pointer(),
- sizeof(core::triangle3df)*keepTriangles.size());
-
- node->Triangles.set_used(keepTriangles.size());
- keepTriangles.set_used(0);
- }
- keepTriangles.clear(); // release memory early, for large meshes it can matter.
- node->Triangles.reallocate(node->Triangles.size(), true); // shrink memory to minimum necessary
-
- // Note: We use an extra loop to construct child-nodes instead of doing
- // that in above loop to avoid memory fragmentation which happens if
- // the code has to switch between allocating memory for this node and
- // the child nodes (thanks @Squarefox for noting this).
- for (s32 ch=0; ch<8; ++ch)
- {
- if (node->Child[ch]->Triangles.empty())
- {
- delete node->Child[ch];
- node->Child[ch] = 0;
- }
- else
- constructOctree(node->Child[ch]);
- }
- }
-}
-
-
-//! Gets all triangles which lie within a specific bounding box.
-void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
- s32 arraySize, s32& outTriangleCount,
- const core::aabbox3d<f32>& box,
- const core::matrix4* transform, bool useNodeTransform,
- irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
-{
- core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
- core::aabbox3d<f32> invbox = box;
-
- if (SceneNode && useNodeTransform)
- {
- if ( SceneNode->getAbsoluteTransformation().getInverse(mat) )
- mat.transformBoxEx(invbox);
- else
- // TODO: case not handled well, we can only return all triangles
- return CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform, useNodeTransform, outTriangleInfo);
- }
-
- if (transform)
- mat = *transform;
- else
- mat.makeIdentity();
-
- if (SceneNode && useNodeTransform)
- mat *= SceneNode->getAbsoluteTransformation();
-
- s32 trianglesWritten = 0;
-
- if (Root)
- getTrianglesFromOctree(Root, trianglesWritten,
- arraySize, invbox, &mat, triangles);
-
- if ( outTriangleInfo )
- {
- SCollisionTriangleRange triRange;
- triRange.RangeSize = trianglesWritten;
- triRange.Selector = const_cast<COctreeTriangleSelector*>(this);
- triRange.SceneNode = SceneNode;
- triRange.MeshBuffer = MeshBuffer;
- triRange.MaterialIndex = MaterialIndex;
- outTriangleInfo->push_back(triRange);
- }
-
- outTriangleCount = trianglesWritten;
-}
-
-
-void COctreeTriangleSelector::getTrianglesFromOctree(
- SOctreeNode* node, s32& trianglesWritten,
- s32 maximumSize, const core::aabbox3d<f32>& box,
- const core::matrix4* mat, core::triangle3df* triangles) const
-{
- if (!box.intersectsWithBox(node->Box))
- return;
-
- const u32 cnt = node->Triangles.size();
-
- for (u32 i=0; i<cnt; ++i)
- {
- const core::triangle3df& srcTri = node->Triangles[i];
- // This isn't an accurate test, but it's fast, and the
- // API contract doesn't guarantee complete accuracy.
- if (srcTri.isTotalOutsideBox(box))
- continue;
-
- core::triangle3df& dstTri = triangles[trianglesWritten];
- mat->transformVect(dstTri.pointA, srcTri.pointA );
- mat->transformVect(dstTri.pointB, srcTri.pointB );
- mat->transformVect(dstTri.pointC, srcTri.pointC );
- ++trianglesWritten;
-
- // Halt when the out array is full.
- if (trianglesWritten == maximumSize)
- return;
- }
-
- for (u32 i=0; i<8; ++i)
- if (node->Child[i])
- getTrianglesFromOctree(node->Child[i], trianglesWritten,
- maximumSize, box, mat, triangles);
-}
-
-
-//! Gets all triangles which have or may have contact with a 3d line.
-// new version: from user Piraaate
-void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
- s32& outTriangleCount, const core::line3d<f32>& line,
- const core::matrix4* transform, bool useNodeTransform,
- irr::core::array<SCollisionTriangleRange>* outTriangleInfo) const
-{
-#if 0
- core::aabbox3d<f32> box(line.start);
- box.addInternalPoint(line.end);
-
- // TODO: Could be optimized for line a little bit more.
- COctreeTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount,
- box, transform);
-#else
-
- core::matrix4 mat ( core::matrix4::EM4CONST_NOTHING );
-
- core::vector3df vectStartInv ( line.start ), vectEndInv ( line.end );
- if (SceneNode && useNodeTransform)
- {
- mat = SceneNode->getAbsoluteTransformation();
- mat.makeInverse();
- mat.transformVect(vectStartInv, line.start);
- mat.transformVect(vectEndInv, line.end);
- }
- core::line3d<f32> invline(vectStartInv, vectEndInv);
-
- mat.makeIdentity();
-
- if (transform)
- mat = (*transform);
-
- if (SceneNode && useNodeTransform)
- mat *= SceneNode->getAbsoluteTransformation();
-
- s32 trianglesWritten = 0;
-
- if (Root)
- getTrianglesFromOctree(Root, trianglesWritten, arraySize, invline, &mat, triangles);
-
- if ( outTriangleInfo )
- {
- SCollisionTriangleRange triRange;
- triRange.RangeSize = trianglesWritten;
- triRange.Selector = const_cast<COctreeTriangleSelector*>(this);
- triRange.SceneNode = SceneNode;
- triRange.MeshBuffer = MeshBuffer;
- triRange.MaterialIndex = MaterialIndex;
- outTriangleInfo->push_back(triRange);
- }
-
- outTriangleCount = trianglesWritten;
-#endif
-}
-
-void COctreeTriangleSelector::getTrianglesFromOctree(SOctreeNode* node,
- s32& trianglesWritten, s32 maximumSize, const core::line3d<f32>& line,
- const core::matrix4* transform, core::triangle3df* triangles) const
-{
- if (!node->Box.intersectsWithLine(line))
- return;
-
- s32 cnt = node->Triangles.size();
- if (cnt + trianglesWritten > maximumSize)
- cnt -= cnt + trianglesWritten - maximumSize;
-
- s32 i;
-
- if ( transform->isIdentity() )
- {
- for (i=0; i<cnt; ++i)
- {
- triangles[trianglesWritten] = node->Triangles[i];
- ++trianglesWritten;
- }
- }
- else
- {
- for (i=0; i<cnt; ++i)
- {
- triangles[trianglesWritten] = node->Triangles[i];
- transform->transformVect(triangles[trianglesWritten].pointA);
- transform->transformVect(triangles[trianglesWritten].pointB);
- transform->transformVect(triangles[trianglesWritten].pointC);
- ++trianglesWritten;
- }
- }
-
- for (i=0; i<8; ++i)
- if (node->Child[i])
- getTrianglesFromOctree(node->Child[i], trianglesWritten,
- maximumSize, line, transform, triangles);
-}
-
-
-} // end namespace scene
-} // end namespace irr
|