Ray casting

severin

11-09-2007 17:07:54

I'm wondering if anyone of you, ever realized that the ray casting, as build into OgreBullet doesn't really work.
I looked into it, and found out, the reason for that is, that in OgreBulletCollisions::CollisionClosestRayResultCallback the bullet internal object btCollisionWorld::ClosestRayResultCallback is initialized by the origin and the direction of the given Ogre Ray, but it should actually be the origin and the endpoint of the ray in the scene.
So I modified the code, to take the Ogre Ray and the maximal distance the ray is cast into the scene. Now I can get the endpoint by calling
mRay.getPoint(max_distance)
and pass it to the constructor of btCollisionWorld::ClosestRayResultCallback.
The same thing must be done in OgreBulletCollisions::CollisionsWorld when the ray is launched.

I've made a patch (which, however was made on the linux version of OgreBullet, posted by libolt on this forum (http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=4840) ) so there is no guarantee it will work on the Windows version, but you can get an idea on how I did the change):


--- ogrebullet/Collisions/include/OgreBulletCollisionsObject.h 2007-07-28 08:07:42.000000000 +0200
+++ ogrebullet/Collisions/include/OgreBulletCollisionsObject.h 2007-09-11 12:36:19.000000000 +0200
@@ -92,6 +92,8 @@
const Ogre::Quaternion &quat);
void showDebugShape(bool show);

+ Ogre::SceneNode *getRootNode() { return mRootNode; }
+
protected:

Ogre::SceneNode* mRootNode;
--- ogrebullet/Collisions/include/OgreBulletCollisionsRay.h 2007-07-28 08:07:42.000000000 +0200
+++ ogrebullet/Collisions/include/OgreBulletCollisionsRay.h 2007-09-11 14:54:00.000000000 +0200
@@ -37,7 +37,7 @@
class CollisionRayResultCallback
{
public:
- CollisionRayResultCallback(const Ogre::Ray &ray, CollisionsWorld *world, bool init = true);
+ CollisionRayResultCallback(const Ogre::Ray &ray, Ogre::Real max_distance, CollisionsWorld *world, bool init = true);
virtual ~CollisionRayResultCallback();

btCollisionWorld::RayResultCallback *getBulletRay() const {return mRayResultCallback;}
@@ -46,11 +46,15 @@

inline const Ogre::Ray &getRay() const;

+ inline Ogre::Vector3 getRayStartPoint() const;
+ inline Ogre::Vector3 getRayEndPoint() const;
+
protected:

btCollisionWorld::RayResultCallback *mRayResultCallback;
CollisionsWorld *mWorld;
Ogre::Ray mRay;
+ Ogre::Real mMaxDistance;

};
// -------------------------------------------------------------------------
@@ -64,7 +68,7 @@
class CollisionClosestRayResultCallback : public CollisionRayResultCallback
{
public:
- CollisionClosestRayResultCallback(const Ogre::Ray &ray, CollisionsWorld *world);
+ CollisionClosestRayResultCallback(const Ogre::Ray &ray, Ogre::Real max_distance, CollisionsWorld *world);
virtual ~CollisionClosestRayResultCallback(){};

Object *getCollidedObject() const;
--- ogrebullet/Collisions/src/OgreBulletCollisionsRay.cpp 2007-07-28 08:07:43.000000000 +0200
+++ ogrebullet/Collisions/src/OgreBulletCollisionsRay.cpp 2007-09-11 14:57:08.000000000 +0200
@@ -39,10 +39,11 @@
namespace OgreBulletCollisions
{
// -------------------------------------------------------------------------
- CollisionRayResultCallback::CollisionRayResultCallback(const Ogre::Ray &ray, CollisionsWorld *world, bool init):
- mRayResultCallback(0),
- mWorld(world),
- mRay (ray)
+ CollisionRayResultCallback::CollisionRayResultCallback(
+ const Ogre::Ray &ray, Ogre::Real max_distance,
+ CollisionsWorld *world, bool init) :
+ mRayResultCallback(0), mWorld(world), mRay(ray),
+ mMaxDistance(max_distance)
{
if (init)
{
@@ -66,17 +67,29 @@
return mRayResultCallback->HasHit();
}
// -------------------------------------------------------------------------
+ Ogre::Vector3 CollisionRayResultCallback::getRayStartPoint() const
+ {
+ return mRay.getOrigin();
+ }
+ // -------------------------------------------------------------------------
+ Ogre::Vector3 CollisionRayResultCallback::getRayEndPoint() const
+ {
+ return mRay.getPoint(mMaxDistance);
+ }
+ // -------------------------------------------------------------------------
Object *CollisionClosestRayResultCallback::getCollidedObject () const
{
return mWorld->findObject(static_cast<btCollisionWorld::ClosestRayResultCallback *> (mRayResultCallback)->m_collisionObject);
}
// -------------------------------------------------------------------------
- CollisionClosestRayResultCallback::CollisionClosestRayResultCallback(const Ogre::Ray &ray, CollisionsWorld *world) :
- CollisionRayResultCallback(ray, world, false)
+ CollisionClosestRayResultCallback::CollisionClosestRayResultCallback(
+ const Ogre::Ray &ray, Ogre::Real max_distance,
+ CollisionsWorld *world) :
+ CollisionRayResultCallback(ray, max_distance, world, false)
{
mRayResultCallback = new btCollisionWorld::ClosestRayResultCallback (
- OgreBtConverter::to(ray.getOrigin ()),
- OgreBtConverter::to(ray.getDirection ()));
+ OgreBtConverter::to(getRayStartPoint()),
+ OgreBtConverter::to(getRayEndPoint()));
}
// -------------------------------------------------------------------------
Vector3 CollisionClosestRayResultCallback::getCollisionPoint() const
--- ogrebullet/Collisions/src/OgreBulletCollisionsWorld.cpp 2007-07-28 08:07:43.000000000 +0200
+++ ogrebullet/Collisions/src/OgreBulletCollisionsWorld.cpp 2007-09-11 14:58:02.000000000 +0200
@@ -141,7 +141,8 @@
std::deque<Object *>::const_iterator it = mObjects.begin();
while (it != mObjects.end())
{
- if ((*it)->getParentNode() == node)
+ //if ((*it)->getParentSceneNode() == node)
+ if((*it)->getRootNode() == node)
return (*it);
++it;
}
@@ -203,8 +204,8 @@
void CollisionsWorld::launchRay(CollisionRayResultCallback &rayresult)
{
mWorld->rayTest(
- OgreBtConverter::to(rayresult.getRay().getOrigin()),
- OgreBtConverter::to(rayresult.getRay().getDirection()),
+ OgreBtConverter::to(rayresult.getRayStartPoint()),
+ OgreBtConverter::to(rayresult.getRayEndPoint()),
*rayresult.getBulletRay ());
}
}


Maybe someone can make use of it.
cu, Severin