[Solved] Vehicle problem

Dirso

06-06-2007 23:30:01

Hi,

I'm using most of the StuntPlayground code for my vehicle class, since it's amazingly complete but I had a problem.
If I don't use m_chassis->setMassMatrix(800, Ogre::Vector3(352.494, 1776.1, 1570.06)) the car floats, but if I use it, it follows to the ground as it's suppose to, but the wheels are not displayed. Do you know what could I be doing wrong?

Here it's part of the code
void CarUSC::_init( OgreNewt::World* world, Ogre::SceneNode* parentnode, Ogre::SceneManager* mgr,
Ogre::String filename, Ogre::Vector3 pos )
{
mTakeOffPos = Ogre::Vector3::ZERO;
Ogre::Vector3 comOffset = Ogre::Vector3::ZERO;
mNumFlips = 0;
mLastY = Ogre::Vector3::ZERO;
mCollisions = 0;

mTireState = TS_ONROAD;

// temp stuff
mFilename = eCGFW::HelperClass::getInstance()->getFileFromResource(filename);

TiXmlDocument doc;

doc.LoadFile( mFilename.c_str() );

// find the vehicle in the file!!
TiXmlElement* vehicle = doc.FirstChildElement( "vehicle" );

// vehicle name...
mName = (Ogre::String)vehicle->Attribute( "name" );

TiXmlElement* elem = vehicle->FirstChildElement( "chassis" );

Ogre::String rigidfile = (Ogre::String)elem->Attribute( "filename" );

// possible offset for center of mass.
elem = elem->FirstChildElement("CenterOfMass");
if (elem)
{
comOffset = Ogre::StringConverter::parseVector3( elem->Attribute( "offset" ) );
}

// make the rigid body!
m_chassis = eCGFW::RBD::getInstance()->createBody(world, mSceneMgr, rigidfile, mName + "Ent");
//m_chassis->setMassMatrix(800, Ogre::Vector3(352.494, 1776.1, 1570.06));
_carNode = (Ogre::SceneNode*)m_chassis->getOgreNode();

// now initialize the vehicle.
init( m_chassis, Ogre::Vector3(0,1,0) );
if (comOffset != Ogre::Vector3::ZERO)
m_chassis->setCenterOfMass( comOffset );

mLookNode = ((Ogre::SceneNode*)m_chassis->getOgreNode())->createChildSceneNode();

// okay, load the torque curve.
elem = vehicle->FirstChildElement( "torque_curve" );

// loop through the points on the curve.
mMinRPM = 15000.0;
mMaxRPM = 0.0;

TiXmlElement* point = elem->FirstChildElement( "point" );
while (point)
{
TorquePoint temp;

temp.rpm = Ogre::StringConverter::parseReal( (Ogre::String)point->Attribute("rpm") );
temp.torque = Ogre::StringConverter::parseReal( (Ogre::String)point->Attribute("torque") );

if (temp.rpm < mMinRPM) { mMinRPM = temp.rpm; }
if (temp.rpm > mMaxRPM) { mMaxRPM = temp.rpm; }

mTorqueCurve.push_back( temp );

// get the next point.
point = point->NextSiblingElement( "point" );
}

mRPMRange = mMaxRPM - mMinRPM;

// time to get the gears.
elem = vehicle->FirstChildElement( "gearbox" );

// loop through the gears
TiXmlElement* gear = elem->FirstChildElement( "gear" );

while (gear)
{
Ogre::Real ratio = Ogre::StringConverter::parseReal( (Ogre::String)gear->Attribute("ratio") );

mGears.push_back( ratio );

//get the next gear.
gear = gear->NextSiblingElement( "gear" );
}

// engine settings
mEngineMass = 100.0;

elem = vehicle->FirstChildElement( "engine" );

mEngineMass = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute("rotating_mass") );
mEngineBaseRPM = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute("base_rpm") );
mEngineScale = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute("scale_factor") );

// shift delay
elem = vehicle->FirstChildElement( "shift" );
mShiftDelay = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "delay" ) );
mShiftTime = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "time" ) );

// differential ratio.
elem = vehicle->FirstChildElement( "differential" );
mDifferentialRatio = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "ratio" ) );

// transmission efficiency
elem = vehicle->FirstChildElement( "transmission" );
mDifferentialRatio = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "efficiency" ) );

// drag coefficient
elem = vehicle->FirstChildElement( "drag" );
mDragCoefficient = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "coefficient" ) );

// brake strength
elem = vehicle->FirstChildElement( "brake" );
mBrakeStrength = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "strength" ) );

// steering settings.
mSteerMaxAngle = Ogre::Radian(0.0);
mSteerSpeed = Ogre::Radian(0.0);
mSteerLossPercent = 0.0;
mSteerFromSpeed = 0.0;
mSteerToSpeed = 0.0;

elem = vehicle->FirstChildElement( "steering" );
mSteerMaxAngle = Ogre::Radian(Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute("angle") ) );
mSteerSpeed = Ogre::Radian(Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute("speed") ) );
mSteerLossPercent = (Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute("percent_drop") ) / 100.0);
mSteerFromSpeed = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute("from_speed") );
mSteerToSpeed = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute("to_speed") );
mSteerSpeedRange = mSteerToSpeed - mSteerFromSpeed;

// finally, go through the tires.
TiXmlElement* tire_elem = vehicle->FirstChildElement( "tire" );

int tirecount = 0;

// loop through the tires
while (tire_elem)
{
Ogre::Quaternion orient;
Ogre::Vector3 rot, pos, pin;
Ogre::Real rad, height, mass;
Ogre::Real damp, spring, length;
Ogre::Real grip;
int steer, drive;

// get visual mesh.
elem = tire_elem->FirstChildElement( "visual" );

CarUSC::MyTire* tire;

// setup the mesh...
Ogre::String meshfile = (Ogre::String)elem->Attribute( "mesh" );

Ogre::Entity* ent = mSceneMgr->createEntity( mName+"_Tire"+Ogre::StringConverter::toString(tirecount++), meshfile );
ent->setNormaliseNormals( true );

// set defaults in case data is missing
orient = Ogre::Quaternion::IDENTITY;
rot = pos = pin = Ogre::Vector3::ZERO;
rad = height = mass = 1.0;
damp = spring = length = 1.0;
grip = 1.0;
steer = drive = 0;

// position, rotation, pin
elem = tire_elem->FirstChildElement( "location" );
rot = Ogre::StringConverter::parseVector3( (Ogre::String)elem->Attribute( "orient" ) );
Ogre::Matrix3 mat;
mat.FromEulerAnglesXYZ( Ogre::Degree(rot.x), Ogre::Degree(rot.y), Ogre::Degree(rot.z) );
orient.FromRotationMatrix( mat );
pos = Ogre::StringConverter::parseVector3( (Ogre::String)elem->Attribute( "pos" ) );
pin = Ogre::StringConverter::parseVector3( (Ogre::String)elem->Attribute( "pin" ) );

// size
elem = tire_elem->FirstChildElement( "size" );
rad = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "radius" ) );
height = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "height" ) );
mass = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "mass" ) );

// suspension
elem = tire_elem->FirstChildElement( "suspension" );
damp = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "damp" ) );
spring = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "spring" ) );
length = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "length" ) );

// settings
elem = tire_elem->FirstChildElement( "settings" );
grip = Ogre::StringConverter::parseReal( (Ogre::String)elem->Attribute( "grip" ) );
steer = Ogre::StringConverter::parseInt( (Ogre::String)elem->Attribute( "steer" ) );
drive = Ogre::StringConverter::parseInt( (Ogre::String)elem->Attribute( "drive" ) );

// make the tire!
//tire = new CarUSC::MyTire( mSceneMgr, node, this, orient, pos, pin, mass, height, rad, damp, spring, length, eCGFW::CT_TIRE );
tire = new CarUSC::MyTire( mSceneMgr, _carNode, this, orient, pos, pin, mass, height, rad, damp, spring, length, eCGFW::CT_TIRE );

tire->setDrive( drive );
tire->setSteer( steer );
tire->setGrip( grip );

tire->getOgreNode()->attachObject( ent );
// get the next tire.
tire_elem = tire_elem->NextSiblingElement( "tire" );
}


mLastOmega = 0.0;
mBrakesOn = false;
mSteering = mThrottle = 0.0f;

mCurrentGear = 1;

m_chassis->setPositionOrientation(pos, Ogre::Quaternion::IDENTITY);
}


void CarUSC::setup()
{
// setup the chassis a bit.
m_chassis->setUserData( this );
m_chassis->setType( eCGFW::BT_CAR );
m_chassis->setStandardForceCallback();
m_chassis->setCustomTransformCallback( CarUSC::Transform );
m_chassis->setAutoFreeze( 0 );
m_chassis->setLinearDamping( 0.001f );
}

OgreNewt::Body* RBD::createBody(OgreNewt::World *world, Ogre::SceneManager *mgr, Ogre::String mesh,
Ogre::String entName, Ogre::Real mass, Ogre::SceneNode *parent,
Ogre::Vector3 pos, Ogre::Quaternion or)
{
Ogre::Entity *ent = mgr->createEntity(entName, mesh);
Ogre::SceneNode *node;
if(parent)
node = parent->createChildSceneNode(pos, or);
else
node = mgr->getRootSceneNode()->createChildSceneNode(pos, or);
node->attachObject(ent);
OgreNewt::CollisionPrimitives::Box *box;
box = new OgreNewt::CollisionPrimitives::Box(world, ent->getBoundingBox().getSize());
OgreNewt::Body* res = new OgreNewt::Body(world, box);
res->attachToNode(node);
if(mass > 0.0f)
{
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcBoxSolid(mass, ent->getBoundingBox().getSize());
res->setMassMatrix(mass, inertia);
}
res->setPositionOrientation(pos, or);
delete box;
return res;
}


Thanks you very much,
Dirso.

walaber

07-06-2007 00:59:41

where did you get those values for the mass and inertia matrix?

Dirso

07-06-2007 01:03:02

From your gt.car and gt.rb files.

walaber

07-06-2007 01:05:22

what is the starting position of the vehicle in your application?

Dirso

07-06-2007 01:12:47

0,70,0.

If I set the mass the car falls OK, but the wheels are not there.

Thanks,
Dirso.

walaber

07-06-2007 01:28:32

what mass are you using for the tires?

Dirso

07-06-2007 02:06:43

10

Dirso

07-06-2007 02:25:56

Here it's the file I'm using:

<?xml version="1.0" ?>
<!--Stunt Playground vehicle file-->
<vehicle name="GT">
<chassis filename="gt.mesh" />
<torque_curve>
<point rpm="500" torque="400" />
<point rpm="5000" torque="1100" />
<point rpm="5500" torque="1300" />
<point rpm="6500" torque="1800" />
<point rpm="7500" torque="1600" />
<point rpm="9000" torque="0" />
</torque_curve>
<gearbox>
<gear ratio="-4.25" />
<gear ratio="3.2" />
<gear ratio="2.24" />
<gear ratio="1.57" />
<gear ratio="1.23" />
<gear ratio="1.065" />
</gearbox>
<engine rotating_mass="250" sound="RaceEngine" base_rpm="1500" scale_factor="4"/>
<shift delay="0.1" time="0.11" />
<differential ratio="2.1" />
<transmission efficiency="0.75" />
<drag coefficient="0.8" />
<brake strength="3000" />
<steering angle="0.75" speed="4.0" percent_drop="75" from_speed="18" to_speed="70" />
<tire>
<visual mesh="gt_wheel.mesh" />
<location orient="0 0 0" pos="0.99 -0.1 0.85" pin="0 0 1" />
<size radius="0.372" height="0.315" mass="10" />
<suspension damp="60.0" spring="700.0" length="0.25" />
<settings grip="2" steer="0" drive="1" />
</tire>
<tire>
<visual mesh="gt_wheel.mesh" />
<location orient="0 180 0" pos="0.99 -0.1 -0.85" pin="0 0 -1" />
<size radius="0.372" height="0.315" mass="10" />
<suspension damp="60.0" spring="700.0" length="0.25" />
<settings grip="2" steer="0" drive="1" />
</tire>
<tire>
<visual mesh="gt_wheel.mesh" />
<location orient="0 0 0" pos="-1.88 -0.1 0.85" pin="0 0 1" />
<size radius="0.334" height="0.235" mass="10" />
<suspension damp="60.0" spring="700.0" length="0.25" />
<settings grip="2" steer="-1" drive="0" />
</tire>
<tire>
<visual mesh="gt_wheel.mesh" />
<location orient="0 180 0" pos="-1.88 -0.1 -0.85" pin="0 0 -1" />
<size radius="0.334" height="0.235" mass="10" />
<suspension damp="60.0" spring="700.0" length="0.25" />
<settings grip="2" steer="-1" drive="0" />
</tire>
</vehicle>

walaber

07-06-2007 04:33:13

okay, final question... how are you updating the OgreNewt::World?

Dirso

07-06-2007 14:23:47

bool GS_Newton::frameStarted(GameManager* game, const FrameEvent& evt)
{
if(isKeyDown(OIS::KC_ESCAPE))
requestExitGame();

m_World->update(evt.timeSinceLastFrame);

return true;
}

walaber

07-06-2007 18:25:17

just as a test, try updating with a fixed, small timestep... like (1.0f/300.0f) or so. see if that changes anything.

Dirso

07-06-2007 19:09:24

The car just falls slowly. The interesting is that if I start the car at 0,0,0 I can see the wheels, I just noticed that, but look what happens.



Am I missing to attach anything?

Thanks
Dirso

walaber

07-06-2007 19:48:58

something is very wrong with the suspension settings then... try lowering the spring settings first, until you get the wheels stable, and work backward from there.

Dirso

07-06-2007 20:59:02

Strange... I just setted to 0 and I still have the same problem. I'm now working with you simpleVehicle and it looks like ok, so I'll start working from there. If you have any more ideas, I'd be very thankful. It's a wonderful class and it would make my development too easier!!!

Thanks,
Dirso

Dirso

09-06-2007 21:01:32

I'm now using you simple vehicle class. I had two diferent situations. If I use your default parameters of the wheels positions, it works, if I change the position of the wheels, the doenst move anymore.
I took a couple of screenshots with the debug lines on. Is the position of the debug lines of the body of the car the issue?
{working}


{NOT working}


Thanks,
Dirso

Dirso

10-06-2007 04:47:45

I made all my meshes center aligned and it worked!!!

Hogarth

11-07-2007 00:09:30

I have had a similar problem to this, with the wheels not showing correctly. The bounding representations appear in the correct place, but the images were no-where to be found. I have managed to correct this by changing my derived vehicle::userCallback() to use my own node adjustment, instead of calling tire::updateNode().

The reason I did this is because the tire::getPositionOrientation() is in world coords, while the node->setPosition is relative to parent ... so I felt some modification was in order to mate the two calls up ... i.e. converting the world coords to parent relative.

This seemed to work for me :)