btRigidBody movement and RayCast

nigul
Posts: 12
Joined: Tue Sep 22, 2009 1:40 pm

btRigidBody movement and RayCast

Post by nigul »

Hello, first post here...

I am currently working on an ogre3D+bullet application (using multitouch input).
I have created a Layout class that handles both a Ogre::SceneNode object and a btRigidBody
I just use simple spheres for the moment : at the very beginning of the program, my sphere is at (0,0,0) position and has a radius of 5, here is how I create the associated btRigidBody (named _body)

Code: Select all

	// set up the ogre scene node
	
	this->ogreSceneNode()->setPosition(pos.x,pos.y,pos.z);
	this->ogreSceneNode()->setOrientation(quat);

       // create the bullet RigidBody
	
	btCollisionShape *shape;
	
	// just a sphere for the moment
	
	shape = new btSphereShape(radius);
	
	btDefaultMotionState *motionState = new btDefaultMotionState(btTransform(btQuaternion(quat.x, quat.y, quat.z, quat.w),btVector3(pos.x,pos.y,pos.z)));

	btScalar mass=1;
	btVector3 inertia;

	shape->calculateLocalInertia(mass, inertia);
	
	btRigidBody::btRigidBodyConstructionInfo cInfo(mass,motionState,shape,inertia);
	
	_body = new btRigidBody(cInfo);
	_body->setUserPointer(this); // this represents the layout object
In order to pick this object in the scene, i use the following :

Code: Select all

					Ray                     _targeting;
					RaySceneQuery           *_rayQuery;
					
					double x,y;
					
					x = _xScreentoOgre(_currentEvent->getx());
					y = _yScreentoOgre(_currentEvent->gety());
					
					_targeting = RenderingManager::sharedManager()->camera()->getCameraToViewportRay(x,y);
					
					// use bullet instead of ogre for rayQuery
			
					btVector3 rayFromWorld;
					btVector3 rayToWorld; 
 
					rayFromWorld.setX(_targeting.getOrigin().x);
 
					rayFromWorld.setY(_targeting.getOrigin().y);
					rayFromWorld.setZ(_targeting.getOrigin().z);

					Vector3 dest;
					
					dest = _targeting.getPoint(1000);
					
					rayToWorld.setX(dest.x);
					rayToWorld.setY(dest.y);
					rayToWorld.setZ(dest.z);
					
					btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld,rayToWorld);
					
					BulletManager::sharedManager()->bulletWorld()->rayTest(rayFromWorld,rayToWorld,rayCallback);
					
					if (rayCallback.hasHit())
					{
						
						btCollisionObject *object = rayCallback.m_collisionObject;
						
						PhysxLayout *_detected = static_cast<PhysxLayout *>(object->getUserPointer());
						
						cout << _detected->name() << endl;
						
						_lastActiveLayout = _detected;
						
					}
this performs well, but then when I move the layout, the rayTest behaves in a strange way (my fault i guess...)

here is how I move the layout, and display new coordinates : probably the problem comes from here

Code: Select all

					double xd,yd;
					// values from the input
					xd = _currentEvent->getXdirection();
					yd = _currentEvent->getYdirection();
					
// move sceneNode and rigidBody by the same amount

					this->ogreSceneNode()->translate(xd/10.0,-yd/10.0,0);
					_body->translate(btVector3(xd/10.0,-yd/10.0,0.0));
									
// add debug stuff to see what's happening
	
					btVector3 _pos = _body->getCenterOfMassPosition();
					Vector3 _snpos = ogreSceneNode()->getPosition();
					
					btVector3 Aabbmin, Aabbmax;
					AxisAlignedBox oAabb;
					
					Vector3 oMin, oMax;
					
					_body->getAabb(Aabbmin,Aabbmax);
					oAabb = ogreSceneNode()->_getWorldAABB();
					oMin = oAabb.getMinimum();
					oMax = oAabb.getMaximum();
					
					
					cout << " btRigidBody after translation :" << _pos.getX() << " : " << _pos.getY() << " : " << _pos.getZ() << endl;
					cout << " SceneNode   after translation :" << _snpos.x << " : " << _snpos.y << " : " << _snpos.z << endl;
					
					cout << " btRigidBody Aabb: min " << Aabbmin.getX() << " : " << Aabbmin.getY() << " : " << Aabbmin.getZ() << endl;
					cout << "                   max " << Aabbmax.getX() << " : " << Aabbmax.getY() << " : " << Aabbmax.getZ() << endl;
					cout << " SceneNode Aabb:   min " << oMin.x << " : " << oMin.y << " : " << oMin.z << endl;
					cout << "                   max " << oMax.x << " : " << oMax.y << " : " << oMax.z << endl;
from this debug stuff I can see that both positions and bounding boxes for the SceneNode and the RigidBody are shifted at the same values.

What happens then is that the rayTest detects only a part of my layout (like a clipping): the part that lies inside the original bounding box centered at (0,0,0). Is there any clipping made by bullet ? Or did I miss something about handling the movement of the btRigidBody ?

Thanks