thanks! It works!
I use simply ray test to check if a ray intersects with btBvhTriangleMeshShape scenes.
Code: Select all
/* raycast.h */
#ifndef RAYCAST_H_
#define RAYCAST_H_
#include "btBulletDynamicsCommon.h"
class RayCast {
public:
btDiscreteDynamicsWorld* m_dynamicsWorld;
btDefaultCollisionConfiguration* m_collisionConfiguration;
btCollisionDispatcher* m_dispatcher;
btBroadphaseInterface* m_overlappingPairCache;
btConstraintSolver* m_constraintSolver;
struct RayCastClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
{
int m_shapePart;
int m_triangleIndex;
RayCastClosestRayResultCallback (const btVector3 & rayFrom, const btVector3 & rayTo)
: btCollisionWorld::ClosestRayResultCallback(rayFrom, rayTo),
m_shapePart(-1),
m_triangleIndex(-1)
{
}
virtual ~RayCastClosestRayResultCallback()
{
}
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult & rayResult, bool normalInWorldSpace)
{
btScalar result = ClosestRayResultCallback::addSingleResult(rayResult,normalInWorldSpace);
if (rayResult.m_localShapeInfo)
{
m_shapePart = rayResult.m_localShapeInfo->m_shapePart;
m_triangleIndex = rayResult.m_localShapeInfo->m_triangleIndex;
}
return result;
}
};
RayCast()
{
m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_overlappingPairCache = new btDbvtBroadphase();
m_constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,
m_overlappingPairCache,
m_constraintSolver,
m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0,0,0)); // static scene
}
~RayCast()
{
for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject( obj );
delete obj;
}
delete m_dynamicsWorld;
delete m_constraintSolver;
delete m_overlappingPairCache;
delete m_dispatcher;
delete m_collisionConfiguration;
}
void addScene(btBvhTriangleMeshShape *scene)
{
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0, 0, 0)); // no translation
btScalar mass(0.);
btVector3 localInertia(0,0,0);
btDefaultMotionState* myMotionState = new btDefaultMotionState(tr);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, scene, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
//add the body to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
void rayTest(RayCastClosestRayResultCallback & rayCallback)
{
m_dynamicsWorld->rayTest(rayCallback.m_rayFromWorld, rayCallback.m_rayToWorld, rayCallback);
if (rayCallback.hasHit())
{
btRigidBody * body = btRigidBody::upcast(rayCallback.m_collisionObject);
if (body)
{
cout << "hit coord " << rayCallback.m_hitPointWorld.x() << " " << rayCallback.m_hitPointWorld.y() << " " << rayCallback.m_hitPointWorld.z() << endl;
cout << "hit triangle index " << rayCallback.m_triangleIndex << endl;
cout << "hit triangle shape part " << rayCallback.m_shapePart << endl;
cout << "hit shape " << rayCallback.m_collisionObject->getCollisionShape()->getName() << endl;
// get triangle vertices position with "process_triangle()"
}
}
}
};
#endif /* RAYCAST_H_ */
the test code...
Code: Select all
/* demo.cpp */
#include "raycast.h"
int main() {
RayCast ray_cast;
btBvhTriangleMeshShape * scene;
btVector3 * m_scene_vertices;
int * m_scene_triangle_indices;
btTriangleIndexVertexArray * m_scene_vertex_array;
{ // scene
const int vertStride = sizeof(btVector3);
const int triangleIndexStride = 3*sizeof(int);
const int totalVerts = 12;
const int totalTriangles = 4;
m_scene_vertices = new btVector3[totalVerts];
m_scene_triangle_indices = new int[totalTriangles*3];
m_scene_vertices[0].setValue(-5, 5, 15);
m_scene_vertices[1].setValue( 0, -5, 15);
m_scene_vertices[2].setValue( 5, 5, 15);
m_scene_vertices[3].setValue(-5, 5, 5);
m_scene_vertices[4].setValue( 0, -5, 5);
m_scene_vertices[5].setValue( 5, 5, 5);
m_scene_vertices[6].setValue(-5, 5, -15);
m_scene_vertices[7].setValue( 0, -5, -15);
m_scene_vertices[8].setValue( 5, 5, -15);
m_scene_vertices[9].setValue(-5, 5, -6);
m_scene_vertices[10].setValue( 0, -5, -6);
m_scene_vertices[11].setValue( 5, 5, -6);
m_scene_triangle_indices[0] = 0;
m_scene_triangle_indices[1] = 1;
m_scene_triangle_indices[2] = 2;
m_scene_triangle_indices[3] = 3;
m_scene_triangle_indices[4] = 4;
m_scene_triangle_indices[5] = 5;
m_scene_triangle_indices[6] = 6;
m_scene_triangle_indices[7] = 7;
m_scene_triangle_indices[8] = 8;
m_scene_triangle_indices[9] = 9;
m_scene_triangle_indices[10] = 10;
m_scene_triangle_indices[11] = 11;
m_scene_vertex_array = new btTriangleIndexVertexArray(totalTriangles,
m_scene_triangle_indices,
triangleIndexStride,
totalVerts,
(btScalar*) &m_scene_vertices[0].x(),
vertStride);
bool useQuantizedAabbCompression = true;
scene = new btBvhTriangleMeshShape(m_scene_vertex_array,useQuantizedAabbCompression);
}
ray_cast.addScene(scene);
btVector3 rayFrom(0,0,0), rayTo(0,0,-10);
RayCast::RayCastClosestRayResultCallback rayCallback(rayFrom, rayTo);
ray_cast.rayTest(rayCallback);
btVector3 rayTo1(0,0,10);
RayCast::RayCastClosestRayResultCallback rayCallback1(rayFrom, rayTo1);
ray_cast.rayTest(rayCallback1);
delete scene;
delete m_scene_vertices;
delete[] m_scene_triangle_indices;
delete m_scene_vertex_array;
return 0;
}
However I still have some small questions.
1. what does 'm_shapePart' from LocalShapeInfo means? a sub part of a mesh? (while m_triangleIndex clearly indicates the index information in triangle index array)
2. can I get Barycentric coordinate instead computing it again? (i.e. how is the intersection point within the triangle face)
3. is there any simple way to get the intersected triangle (vertex position of a face) rather than using btStridingMeshInterface like "process_triangle" from your example? Since I build up objects with btTriangleIndexVertexArray, I should easily get triangle faces with the "hit triangle index" given in ClosestRayResultCallback. But how can I associate the "hit triangle index" to the right rigid/collision objects? is there an index, id, or something that I can define a rigid/collision object and get it in ClosestRayResultCallback.addSingleResult?
thanks again
