Files
bullet3/Extras/BulletOdeCollide/BVHTrimeshShape.cpp
2006-05-25 19:18:29 +00:00

148 lines
3.9 KiB
C++

#include "BVHTrimeshShape.h"
#define TRIMESH_INTERNAL //requires OPCODE for the AABB tree
#include <../ode/src/collision_trimesh_internal.h>
//Thanks AndrewONeil for the TrimeshBridge fix
BVHTrimeshShape::BVHTrimeshShape(dxTriMesh* trimesh)
: TriangleMeshShape(new TrimeshBridge(trimesh))
, m_triangleBridge( static_cast<TrimeshBridge*>(m_meshInterface))
{
}
BVHTrimeshShape::~BVHTrimeshShape ()
{
delete m_triangleBridge;
}
TrimeshBridge::TrimeshBridge(dxTriMesh* trimesh)
:m_trimesh(trimesh)
{
}
void TrimeshBridge::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const
{
numverts = m_trimesh->Data->Mesh.GetNbVertices();
(*vertexbase) = (unsigned char *)m_trimesh->Data->Mesh.GetVerts();
type = PHY_FLOAT;
stride = m_trimesh->Data->Mesh.GetVertexStride();
numfaces = m_trimesh->Data->Mesh.GetNbTriangles();
(*indexbase) = (unsigned char *)m_trimesh->Data->Mesh.GetTris();
indexstride = m_trimesh->Data->Mesh.GetTriStride();
indicestype = PHY_INTEGER;
}
void TrimeshBridge::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart)
{
numverts = m_trimesh->Data->Mesh.GetNbVertices();
(*vertexbase) = (unsigned char *)m_trimesh->Data->Mesh.GetVerts();
type = PHY_FLOAT;
stride = m_trimesh->Data->Mesh.GetVertexStride();
numfaces = m_trimesh->Data->Mesh.GetNbTriangles();
(*indexbase) = (unsigned char *)m_trimesh->Data->Mesh.GetTris();
indexstride = m_trimesh->Data->Mesh.GetTriStride();
indicestype = PHY_INTEGER;
}
#ifdef USE_AABB_TREE
//ProcessAllTriangles first gets the overlapping triangles using BVH culling
//and passes them on to the TriangleCallback
void BVHTrimeshShape::ProcessAllTriangles(TriangleCallback* callback,const SimdVector3& aabbMin,const SimdVector3& aabbMax) const
{
dxTriMesh* TriMesh = m_triangleBridge->m_trimesh;
// Init
const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh);
const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh);
SphereCollider& Collider = TriMesh->_SphereCollider;
SimdVector3 he = (aabbMax-aabbMin)*0.5f;
SimdVector3 cen = (aabbMax+aabbMin)*0.5f;
dVector3 aabbHalfExtents;
aabbHalfExtents[0] = he.x();
aabbHalfExtents[1] = he.y();
aabbHalfExtents[2] = he.z();
dVector3 Position;
Position[0]=cen.x();
Position[1]=cen.y();
Position[2]=cen.z();
dReal Radius = he.length();
// Bounding Sphere (from aabb)
Sphere Sphere;
Sphere.mCenter.x = Position[0];
Sphere.mCenter.y = Position[1];
Sphere.mCenter.z = Position[2];
Sphere.mRadius = Radius;
Matrix4x4 trimeshTransform;
MakeMatrix(TLPosition, TLRotation, trimeshTransform);
// bvhTraversal.getOverlappingPrimitiveIndices(
// indicesCache,
// Sphere,
// TriMesh->Data->BVTree,
// &trimeshTransform);
Collider.SetTemporalCoherence(false);
Collider.SetPrimitiveTests(false);
Collider.Collide(dxTriMesh::defaultSphereCache, Sphere, TriMesh->Data->BVTree, null,
&trimeshTransform);
// get results
int TriCount = Collider.GetNbTouchedPrimitives();
const int* Triangles = (const int*)Collider.GetTouchedPrimitives();
if (TriCount != 0){
int OutTriCount = 0;
for (int i = 0; i < TriCount; i++){
//what was this
//if (OutTriCount == (Flags & 0xffff)){
// break;
//}
const int& TriIndex = Triangles[i];
dVector3 dv[3];
FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv);
SimdVector3 vts[3] =
{ SimdVector3(dv[0][0],dv[0][1],dv[0][2]),
SimdVector3 (dv[1][0],dv[1][1],dv[1][2]),
SimdVector3 (dv[2][0],dv[2][1],dv[2][2])
};
callback->ProcessTriangle(&vts[0]);
OutTriCount++;
}
if (OutTriCount)
{
}
}
}
#endif //USE_AABB_TREE