[help]Questions about the use of btRaycastVehicle

User avatar
kenshin
Posts: 36
Joined: Fri Oct 31, 2008 5:10 pm

[help]Questions about the use of btRaycastVehicle

Post by kenshin »

I refer to examples of appVehicleDemo
I want to integration Bullet into Ogre
However, I encountered a problem
my wheel can Rotating and wheeling
my chassis can move
but the wheel never attach to the chassis


The following is my code:

Code: Select all

void OgrewithCeguiApp::CreateCar(void)
{
	Entity *Carent;
	Ogre::Vector3 vrre;
	Ogre::Entity* mWheels[4];
	Ogre::SceneNode* mWheelNodes[4];
	Ogre::SceneNode *node;
	Ogre::SceneNode *carnode;
	btCollisionShape* chassisShape;
	btCompoundShape* compound;
	btTransform localTrans;
	btVector3 localInertia(0,0,0);
	CarMotionState *motionstate;
	btRigidBody* body ;
	btRaycastVehicle::btVehicleTuning  mTuning;
	btVehicleRaycaster*	m_vehicleRayCaster;
	btRaycastVehicle*	m_vehicle;
	btVector3 wheelDirectionCS0(0,-1,0);	
	btVector3 wheelAxleCS(-1,0,0);
	float wheelWidth=42.0;
	float connectionHeight=40.0;
	float wheelRadius=63.0;
	float suspensionRestLength=0.6;
	bool isFrontWheel;

	mTuning.m_frictionSlip=10.5;
	mTuning.m_maxSuspensionTravelCm=500.0;
	mTuning.m_suspensionCompression=4.4;
	mTuning.m_suspensionDamping=2.3;
	mTuning.m_suspensionStiffness=20.0;

	Carent = mSceneMgr->createEntity("roof1", "roof1.mesh");
	Carent->setVisible(false);
	node=mSceneMgr->getRootSceneNode()->createChildSceneNode();
	carnode=node->createChildSceneNode("carnode");
	carnode->attachObject(Carent);

	vrre=Carent->getBoundingBox().getHalfSize();


	//419 178 108

	mSceneMgr->getSceneNode("carnode")->setScale(Ogre::Vector3(0.5,0.5,0.5));
	mSceneMgr->getSceneNode("carnode")->setOrientation(-0.5,-0.5,0.5,-0.5);
	mSceneMgr->getSceneNode("carnode")->setPosition(Ogre::Vector3(0,30,0));

	chassisShape = new btBoxShape(btVector3(vrre.y*0.5,vrre.z*0.5,vrre.x*0.5) );
	compound = new btCompoundShape();

	localTrans.setIdentity();
	localTrans.setOrigin(btVector3(0,30,0));
	compound->addChildShape(localTrans,chassisShape);

	chassisShape->calculateLocalInertia(800,localInertia);
	motionstate = new CarMotionState(btTransform(btQuaternion( 0,0,0,1),btVector3(btScalar(0),btScalar(0),btScalar(0))),node);
	btRigidBody::btRigidBodyConstructionInfo cInfo(800,motionstate,compound,localInertia);
	body = new btRigidBody(cInfo);
	static_cast <btDynamicsWorld *> (mWorld)->addRigidBody (body);
	body->setRestitution(0.6);
	body->setFriction(0.6);
	body->setDamping(0.2,0.2);
	mWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(body->getBroadphaseHandle(),mWorld->getDispatcher());

	m_vehicleRayCaster = new btDefaultVehicleRaycaster(static_cast <btDynamicsWorld *> (mWorld));
	m_vehicle = new btRaycastVehicle(mTuning,body,m_vehicleRayCaster);
	body->setActivationState(DISABLE_DEACTIVATION);
	static_cast <btDynamicsWorld *> (mWorld)->addVehicle(m_vehicle);

	int rightIndex = 0;
	int upIndex = 1;
	int forwardIndex = 2;
	m_vehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex);//X?Y?Z

	Ogre::SceneNode* tmpnode;
	for (size_t i = 0; i < 4; i++)
	{
		mWheels[i] = mSceneMgr->createEntity(
			"wheel" + StringConverter::toString(i),
			"Entity91.mesh");
		mWheels[i]->setCastShadows(true);
		mWheelNodes[i] = mSceneMgr->getRootSceneNode ()->createChildSceneNode ();
		tmpnode=mWheelNodes[i]->createChildSceneNode();

		tmpnode->attachObject (mWheels[i]);
		tmpnode->setScale(Ogre::Vector3(0.5,0.5,0.5));
		tmpnode->setOrientation(-0.5,-0.5,0.5,-0.5);

	}



	motionstate->setVehicle(m_vehicle);
	motionstate->setVehicleRaycaster(m_vehicleRayCaster);
	motionstate->setVehicleTuning(mTuning);
	motionstate->setWheelNode(mWheelNodes);




	//wheel1
	isFrontWheel=true;
	btVector3 connectionPointCS0;

	connectionPointCS0=btVector3(178-(0.3*wheelWidth),connectionHeight,419-wheelRadius);
	connectionPointCS0=connectionPointCS0*0.4;
	m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,mTuning,isFrontWheel);


	//wheel2
	connectionPointCS0 = btVector3(-178+(0.3*wheelWidth),connectionHeight,419-wheelRadius);
	connectionPointCS0=connectionPointCS0*0.4;
	m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,mTuning,isFrontWheel);

	//wheel3
	isFrontWheel = false;
	connectionPointCS0 = btVector3(-178+(0.3*wheelWidth),connectionHeight,-419+wheelRadius);
	connectionPointCS0=connectionPointCS0*0.4;
	m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,mTuning,isFrontWheel);

	//wheel4
	connectionPointCS0 = btVector3(178-(0.3*wheelWidth),connectionHeight,-419+wheelRadius);
	connectionPointCS0=connectionPointCS0*0.4;
	
	m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,mTuning,isFrontWheel);
	motionstate->setWheelsAttached();

	m_vehicle->applyEngineForce(30000.0, 0);
	m_vehicle->applyEngineForce(30000.0, 0);
	m_vehicle->setSteeringValue(0.6,0);
	m_vehicle->setSteeringValue(0.6,1);
	body->setLinearVelocity ( btVector3(0,300,0));

}
I make a CarMotionState from btMotionState
when call setWorldTransform ,Update the information of 4 wheels

Code: Select all

class CarMotionState :
	public btMotionState
{
protected:

	Ogre::Node *mCarNode;
	btTransform mCarPos;
	btRaycastVehicle*	mVehicle;
	btVehicleRaycaster*	mVehicleRayCaster;
	Ogre::SceneNode* mWheelNodes[4];
	btRaycastVehicle::btVehicleTuning mTuning;
public:
	CarMotionState(const btTransform &initialpos, Ogre::Node *node):
	  mCarNode(node),
	  mCarPos(initialpos)
	  {
	  }
	  ~CarMotionState(void)
	  {
	  }


	  void setNode(Ogre::SceneNode *node) 
	  {
		  mCarNode = node;
	  }

	  virtual void getWorldTransform(btTransform &worldTrans) const 
	  {
		  worldTrans =  mCarPos;
	  }

	  virtual void setWorldTransform(const btTransform &worldTrans) 
	  {
		  if(NULL == mCarNode) return; // silently return before we set a node
		  btQuaternion rot = worldTrans.getRotation();
		  btVector3 pos = worldTrans.getOrigin();
		  mCarNode->setOrientation(rot.w(), rot.x(), rot.y(), rot.z());
		  mCarNode->setPosition(pos.x(), pos.y(), pos.z());

		  for (int i=0;i<mVehicle->getNumWheels();i++)
		  {
			    //synchronize the wheels with the (interpolated) chassis world transform
            mVehicle->updateWheelTransform(i, true);
            //draw wheels (cylinders)
            btTransform &w = mVehicle->getWheelInfo(i).m_worldTransform;

	        mWheelNodes[i]->setPosition (w.getOrigin().getX(), w.getOrigin().getY(), w.getOrigin().getZ());
            mWheelNodes[i]->setOrientation (w.getRotation().getW(), w.getRotation().getX(), w.getRotation().getY(), w.getRotation().getZ());

			
		  }
	  }

	  void setVehicle(btRaycastVehicle *v)
	  {
		  mVehicle = v;
	  }
	  void setVehicleRaycaster(btVehicleRaycaster*	vrc)
	  {
		  mVehicleRayCaster=vrc;

	  }
	  void setWheelNode(Ogre::SceneNode** wheelnodes)
	  {
		  for(int i=0;i<4;i++)
		  {
			  this->mWheelNodes[i]=wheelnodes[i];
		  }

	  }

	  void setVehicleTuning(btRaycastVehicle::btVehicleTuning tuning)
	  {
		  this->mTuning=tuning;

	  }
	  void setWheelsAttached()
	  {

		    btRaycastVehicle *v = this->mVehicle ;
        for (int i=0; i < v->getNumWheels(); i++)
        {
            btWheelInfo& wheel = v->getWheelInfo(i);

            wheel.m_suspensionStiffness = this->mTuning.m_suspensionStiffness;
            wheel.m_wheelsDampingRelaxation = this->mTuning.m_suspensionDamping;
            wheel.m_wheelsDampingCompression = this->mTuning.m_suspensionCompression;

            wheel.m_frictionSlip = 1e30;
            wheel.m_rollInfluence = 0.1;
        }
	  }

};

Image

Who can tell me why?
I will be very grateful ,for even a little bit of tips
This problem has troubled me for a week
Sincerely look forward to your reply ,thank you
:)
User avatar
kenshin
Posts: 36
Joined: Fri Oct 31, 2008 5:10 pm

Re: [help]Questions about the use of btRaycastVehicle

Post by kenshin »

the white line is Wireframe
DebugDrawModes choose 1
User avatar
kenshin
Posts: 36
Joined: Fri Oct 31, 2008 5:10 pm

Re: [help]Questions about the use of btRaycastVehicle

Post by kenshin »

help~~~
User avatar
kenshin
Posts: 36
Joined: Fri Oct 31, 2008 5:10 pm

Re: [help]Questions about the use of btRaycastVehicle

Post by kenshin »

Top
User avatar
kenshin
Posts: 36
Joined: Fri Oct 31, 2008 5:10 pm

Re: [help]Questions about the use of btRaycastVehicle

Post by kenshin »

help~
User avatar
kenshin
Posts: 36
Joined: Fri Oct 31, 2008 5:10 pm

Re: [help]Questions about the use of btRaycastVehicle

Post by kenshin »

btTransform w =mVehicle->getWheelTransformWS(i);

I am sure that xyz value in bullet system does not change.
mcan
Posts: 15
Joined: Tue Feb 03, 2009 10:04 am

Re: [help]Questions about the use of btRaycastVehicle

Post by mcan »

I'm doing almost the same thing but I'm using OSG instead of Orge. My code looks like this:

Code: Select all

	const btTransform *xform;

	// Update wheel transformations
	for (int i=0;i<m_vehicle->getNumWheels();i++)
	{
		xform = &(m_vehicle->getWheelTransformWS(i));

		osgWheelPAT[i]->setPosition(osg::Vec3d(
			xform->getOrigin()[0],
			xform->getOrigin()[1],
			xform->getOrigin()[2]));

		osgWheelPAT[i]->setAttitude(osg::Quat(
			xform->getRotation()[0],
			xform->getRotation()[1],
			xform->getRotation()[2],
			xform->getRotation()[3]));
	}
Where m_vehicle is my vehicle (btRaycastVehicle), and the osgWheelPAT is a PositionAttitudeTransform (which would probably correspond to your mWheelNodes).

I had problems while copying the values from the xform to my osgWheelPAT, i did solve it somehow but don't really know how... Also, the quick watch in MSVC 2008 Express didn't show the correct values! (or at least when I did a printf of the values it didn't match the watch values)
User avatar
kenshin
Posts: 36
Joined: Fri Oct 31, 2008 5:10 pm

Re: [help]Questions about the use of btRaycastVehicle

Post by kenshin »

mcan wrote:I'm doing almost the same thing but I'm using OSG instead of Orge. My code looks like this:

Code: Select all

	const btTransform *xform;

	// Update wheel transformations
	for (int i=0;i<m_vehicle->getNumWheels();i++)
	{
		xform = &(m_vehicle->getWheelTransformWS(i));

		osgWheelPAT[i]->setPosition(osg::Vec3d(
			xform->getOrigin()[0],
			xform->getOrigin()[1],
			xform->getOrigin()[2]));

		osgWheelPAT[i]->setAttitude(osg::Quat(
			xform->getRotation()[0],
			xform->getRotation()[1],
			xform->getRotation()[2],
			xform->getRotation()[3]));
	}
Where m_vehicle is my vehicle (btRaycastVehicle), and the osgWheelPAT is a PositionAttitudeTransform (which would probably correspond to your mWheelNodes).

I had problems while copying the values from the xform to my osgWheelPAT, i did solve it somehow but don't really know how... Also, the quick watch in MSVC 2008 Express didn't show the correct values! (or at least when I did a printf of the values it didn't match the watch values)


Thank you,mcan.
I encountered the same problem like you.
the the quick watch in MSVC 2008 Express didn't show the correct values.
because your application ?may be a debug version?quote a Realese version Bullet System.
so the quick watch can not show the value of portion variable.
User avatar
kenshin
Posts: 36
Joined: Fri Oct 31, 2008 5:10 pm

Re: [help]Questions about the use of btRaycastVehicle

Post by kenshin »

mVehicle->updateWheelTransform(i,false);

when i change the second parameter to false.
the wheel follow with the chassis.
but the white line still the same .