Formal request for help
by CdnGater · in Torque Game Engine Advanced · 03/27/2007 (2:18 pm) · 14 replies
I am formally requesting help!
I am very frustrated with TGEA rigid body physics that I am ready to toss TGEA out the window and go someplace else.
The first thing, I do not understand rigid body physics that well. I have been searching the net trying to find examples. The ones I do find, do not translate to TGEA well or at all.
Over the last three weeks, I have been trying to build a spaceship that moves like the ones in Eve-Online. That is, have the ship turn toward the direction before moving forward.
What I have done is taken a copy of FlyingVehicle, removed the gravity and added the AI node navigation. Now I relize that FlyingVehicle combines both rotation and movment together hence flying. So for now, I commented out the code that applies the forward thrust.
The problem I am having is with rotation.
If I understand the following correct, it applies a pitch to the torque.
The following applies a yaw to the torque.
And last but not least, roll.
if I use only the pitch and yaw, my ship will point in the correct direction, though it does have an unexpected roll applied.
If I use pitch, yaw, and roll, the ship wonders all around, never getting to the correct direction.
The examples I see on the web, do not do the pitch, yaw, roll the same way TGEA does, this is why I need your help. I know it can be done, as I have seen other peoples space projects doing it here on GG.
So, please, can someone help me do this. Please!
I am very frustrated with TGEA rigid body physics that I am ready to toss TGEA out the window and go someplace else.
The first thing, I do not understand rigid body physics that well. I have been searching the net trying to find examples. The ones I do find, do not translate to TGEA well or at all.
Over the last three weeks, I have been trying to build a spaceship that moves like the ones in Eve-Online. That is, have the ship turn toward the direction before moving forward.
What I have done is taken a copy of FlyingVehicle, removed the gravity and added the AI node navigation. Now I relize that FlyingVehicle combines both rotation and movment together hence flying. So for now, I commented out the code that applies the forward thrust.
The problem I am having is with rotation.
If I understand the following correct, it applies a pitch to the torque.
torque -= xv * steering.y * mDataBlock->steeringForce;
The following applies a yaw to the torque.
torque -= zv * steering.x * mDataBlock->steeringForce;
And last but not least, roll.
torque += yv * steering.x * mDataBlock->steeringRollForce; // Applies a +roll based on steering angle F32 ar = mDataBlock->autoAngularForce * mDot(xv,Point3F(0,0,1)); // Applies a -roll based on change from vertical ar -= mDataBlock->rollForce * mDot(xv, mRigid.linVelocity); // Not sure what this does, but slows -roll down based on linVelocity torque += yv * ar;
if I use only the pitch and yaw, my ship will point in the correct direction, though it does have an unexpected roll applied.
If I use pitch, yaw, and roll, the ship wonders all around, never getting to the correct direction.
The examples I see on the web, do not do the pitch, yaw, roll the same way TGEA does, this is why I need your help. I know it can be done, as I have seen other peoples space projects doing it here on GG.
So, please, can someone help me do this. Please!
#2
03/28/2007 (9:40 am)
Also, I know that Martin, a colleague of mine, will be releasing something that may help you very soon.
#3
What they do is rotate to the direction they want to go, and then start going in that direction.
When a ship does a turn yaw wise, they roll with the turn, then roll back upright. From what I see in FlyingVehicle, it should do the same thing, but its not.
Now, I know how to get the direction I need to turn and the force to apply.
Examples:
The ship is not player controlled, so no inputs that way. it does internal calculations to face the required direction.
Now, I was talking to a friend over lunch today about it, and he said it sounds like I need to apply the yaw using world coordinates, and pitch and roll by local coordinates. I am not sure how to do that in TGEA even.
As for Martin's flight pack, I am looking forward to tinkering with that. But I have been working on this for a few weeks now trying to create a proof of concept for a customer. If I can't get over this one major hurdle, then I am sunk and possiably loose that customer to someone else, which I realy don't want to do.
So any help is realy appreciated.
03/28/2007 (11:01 am)
Hello Phil,What they do is rotate to the direction they want to go, and then start going in that direction.
When a ship does a turn yaw wise, they roll with the turn, then roll back upright. From what I see in FlyingVehicle, it should do the same thing, but its not.
Now, I know how to get the direction I need to turn and the force to apply.
Examples:
Say I want to turn the ship to face the right. I would apply a +yaw force. If I comment out the roll code. The ship does a flat turn to the correct facing, as expected. If I uncomment the roll code, then the ship starts doing a nose dive as it rolls and never gets to the correct facing.
With the roll code commented out. Now lets say I want to turn to the right and up. So in the end the ship should be pointing up at 45dec angle while facing right. So I apply a +yaw, and a +pitch. The ship manages to face the correct direction, but it also has a roll applied. Though I have the roll code commented out. If I have the roll code uncommented and do the same thing, the ship wonders around the screen and never ends up facing the correct direction.
The ship is not player controlled, so no inputs that way. it does internal calculations to face the required direction.
Now, I was talking to a friend over lunch today about it, and he said it sounds like I need to apply the yaw using world coordinates, and pitch and roll by local coordinates. I am not sure how to do that in TGEA even.
As for Martin's flight pack, I am looking forward to tinkering with that. But I have been working on this for a few weeks now trying to create a proof of concept for a customer. If I can't get over this one major hurdle, then I am sunk and possiably loose that customer to someone else, which I realy don't want to do.
So any help is realy appreciated.
#4
The problem youre seeing is an order of rotation issue. Basically, when you compose rotations, you have to think about what order the rotations are happening in, as you'll see that doing them in different order has different end effects.
To be honest, the notation used in the flyingvehicle code isnt exactly helping any, because its quite obscure. I'd suggest getting rid of that initially and doing the rotations by hard coding them until you understand the rotation order you need.
I'll try and dig up some old code I wrote to test out this (I had a similar issue and wanted to get my head around it).
But to be honest, this isnt a torque thing, you'll have the same issue no matter what engine youre using.
03/28/2007 (12:53 pm)
Hey Simon,The problem youre seeing is an order of rotation issue. Basically, when you compose rotations, you have to think about what order the rotations are happening in, as you'll see that doing them in different order has different end effects.
To be honest, the notation used in the flyingvehicle code isnt exactly helping any, because its quite obscure. I'd suggest getting rid of that initially and doing the rotations by hard coding them until you understand the rotation order you need.
I'll try and dig up some old code I wrote to test out this (I had a similar issue and wanted to get my head around it).
But to be honest, this isnt a torque thing, you'll have the same issue no matter what engine youre using.
#5
03/28/2007 (1:05 pm)
Just so you know, its usually roll, then pitch, then yaw.
#6
03/28/2007 (1:06 pm)
I would strongly suggest against using Rigid Physics for Eve-like physics. It is seriously overkill for that and will only result in pain for you.
#7
http://www.sjbaker.org/steve/omniv/eulers_are_evil.html
03/28/2007 (1:17 pm)
Found an interesting site that has related info :)http://www.sjbaker.org/steve/omniv/eulers_are_evil.html
#8
03/28/2007 (1:19 pm)
Stefan, there's nothing particularly evil about rigid body as a method of handling space physics. Now you could argue that it'd be better to just treat a ship as a sphere, or set of sphere's, but I dont see any particular problem with rigids, other than having a lousy integrator :)
#9
I would take a look at Player physics or something simple like that. It will save you a lot of time, believe me.
03/28/2007 (1:25 pm)
All I am saying is that for the purposes of Eve Online-like physics, rigid body physics is like slapping Aegia PhysX on Pong. Ships do not collide with eachother (as per 2004 when I played it anyway) and there is no response to collisions at all rotation-wise. The ship just stops when it encounters another static object. Very much RTS-like.I would take a look at Player physics or something simple like that. It will save you a lot of time, believe me.
#10
Well, it is a Torque issue as I am trying to understand whats currently implemented to figure out whats wrong and how to fix it. Some of the other engines I know of are far more intuitive with this, but I am trying to do this the TGEA way.
I walked though the code to find updateForces(F32 dt). This function is what does the actual work of calculating the force and torque that will be applied.
If I comment out the following code, then all pitch movement stops.
If I comment out the following code, then all yaw movement stops.
If I comment out the following code, then all roll movement stops.
This torque is sent to Rigid like so
Rigid has a function called Rigid::integrate that does this with the torque
After which Rigid::updateVelocity is called
[/code]
invWorldInertia.mulV(angMomentum,&angVelocity);
[/code]
The next bit of code is back in integrate where it comes together I think with the new changes
After that, there are calls to Vehicle::setPosition( mRigid.linPosition, mRigid.angPosition ) which updates the actual transform for the object.
Everything I find on the web shows pitch being applied to the base matrix, then yaw, and roll last, looking at this code it looks like all three are being applied at the same time.
After reading your post above again, I am thinking maybe I should just gut updateForce and rewrite it and not use rigid at all.
03/28/2007 (1:27 pm)
Thanks for the help Phil,Well, it is a Torque issue as I am trying to understand whats currently implemented to figure out whats wrong and how to fix it. Some of the other engines I know of are far more intuitive with this, but I am trying to do this the TGEA way.
I walked though the code to find updateForces(F32 dt). This function is what does the actual work of calculating the force and torque that will be applied.
If I comment out the following code, then all pitch movement stops.
torque -= xv * steering.y * mDataBlock->steeringForce;
If I comment out the following code, then all yaw movement stops.
torque -= zv * steering.x * mDataBlock->steeringForce;
If I comment out the following code, then all roll movement stops.
torque += yv * steering.x * mDataBlock->steeringRollForce; F32 ar = mDataBlock->autoAngularForce * mDot(xv,Point3F(0,0,1)); ar -= mDataBlock->rollForce * mDot(xv, mRigid.linVelocity); torque += yv * ar;
This torque is sent to Rigid like so
mRigid.torque = torque;
Rigid has a function called Rigid::integrate that does this with the torque
// Update angular momentum angMomentum = angMomentum + torque * delta;
After which Rigid::updateVelocity is called
[/code]
invWorldInertia.mulV(angMomentum,&angVelocity);
[/code]
The next bit of code is back in integrate where it comes together I think with the new changes
QuatF dq;
F32 sinHalfAngle;
mSinCos(angle * delta * -0.5, sinHalfAngle, dq.w);
sinHalfAngle *= 1 / angle;
dq.x = angVelocity.x * sinHalfAngle;
dq.y = angVelocity.y * sinHalfAngle;
dq.z = angVelocity.z * sinHalfAngle;
QuatF tmp = angPosition;
angPosition.mul(tmp, dq);
angPosition.normalize();After that, there are calls to Vehicle::setPosition( mRigid.linPosition, mRigid.angPosition ) which updates the actual transform for the object.
Everything I find on the web shows pitch being applied to the base matrix, then yaw, and roll last, looking at this code it looks like all three are being applied at the same time.
After reading your post above again, I am thinking maybe I should just gut updateForce and rewrite it and not use rigid at all.
#11
Thanks for the thought;
Though I am trying to get my ships to turn and move the same way Eve does, does not mean I am copying Eve in the rest of the movements. The thing I realy hate about Eve's physics, is large ships bounce off smaller ones. That to me is so wrong! Large ships sould not be affected and should just brush smaller ones aside.
@Phil
Humm
not
Ok, will give that a try at least, see what differences I get.
03/28/2007 (1:34 pm)
@StefanThanks for the thought;
Though I am trying to get my ships to turn and move the same way Eve does, does not mean I am copying Eve in the rest of the movements. The thing I realy hate about Eve's physics, is large ships bounce off smaller ones. That to me is so wrong! Large ships sould not be affected and should just brush smaller ones aside.
@Phil
Humm
roll, then pitch, then yaw
not
pitch, yaw, roll
Ok, will give that a try at least, see what differences I get.
#12
That sounds wonky indeed. Back when I played, ships did not trigger collisions at all and just went trough eachother. Guess things change (:
Anyway. I keep to my recommendation. The above does not require a Rigid Body, and is already implemented in the player simulation. We added a seperate class to our game which needed to act like what you describe, but with a few differencies. I tried Flying Vehicle but eventually gave up and went with a modified player class, and I never looked back since.
I know you get stuck on your path sometimes, just keep in mind that there is another way, should you eventually give up like I did. Keep at it, and good luck.
03/28/2007 (1:45 pm)
Quote:
Though I am trying to get my ships to turn and move the same way Eve does, does not mean I am copying Eve in the rest of the movements. The thing I realy hate about Eve's physics, is large ships bounce off smaller ones. That to me is so wrong! Large ships sould not be affected and should just brush smaller ones aside.
That sounds wonky indeed. Back when I played, ships did not trigger collisions at all and just went trough eachother. Guess things change (:
Anyway. I keep to my recommendation. The above does not require a Rigid Body, and is already implemented in the player simulation. We added a seperate class to our game which needed to act like what you describe, but with a few differencies. I tried Flying Vehicle but eventually gave up and went with a modified player class, and I never looked back since.
I know you get stuck on your path sometimes, just keep in mind that there is another way, should you eventually give up like I did. Keep at it, and good luck.
#13
#define PI (3.141592653589793238462643f)
#define TWO_PI (PI * 2.0f)
void SpaceVehicle::updateForces(F32 /*dt*/)
{
MatrixF currPosMat;
mRigid.state.getTransform(&currPosMat);
mRigid.atRest = false;
Point3F massCenter;
currPosMat.mulP(mDataBlock->massCenter,&massCenter);
Point3F xv,yv,zv;
currPosMat.getColumn(0,&xv);
currPosMat.getColumn(1,&yv);
currPosMat.getColumn(2,&zv);
currPosMat = getWorldTransform();
F32 speed = mRigid.state.linVelocity.len();
Point3F force = Point3F(0, 0, 0);
Point3F torque = Point3F(0, 0, 0);
F32 mPower = 10.0f;
sThrust = mThrust;
sSteering = mRigid.state.linVelocity;
//sSteering = mSteering;
// Maneuvering jets
/*
z = up/down
y = forward/back
x = left/right
*/
mCeilingFactor = 1.0f;
// Turbo Jet
//Point3F fwd(0.0f,1000.0f,0.0f);
//mRigid.state.angPosition.mulP(fwd,&force);
torque.set(0,0,0);
// Add in force from physical zones...
//force += mAppliedForce;
// Drag at any speed
//force -= mRigid.state.linVelocity * mDataBlock->minDrag;
torque -= mRigid.state.angMomentum * mDataBlock->rotationalDrag;
// Container buoyancy & drag
//force -= mRigid.state.linVelocity * mDrag;
//torque.set(0,0,0);
//force.set(0,0,0);
mRigid.state.angMomentum.set(0,0,0);
mRigid.state.angVelocity.set(0,0,0);
//mRigid.state.linVelocity.set(0,0,0);
sSteering = mRigid.state.linVelocity;
QuatF qX,qY,qZ,qAdd;
AngAxisF xang,yang,zang;
xang.set(xv,-mThrust.y * 0.01f);
yang.set(yv,mThrust.z * 0.01f);
zang.set(zv,mThrust.x * 0.01f);
qX.set(xang);
qY.set(yang);
qZ.set(zang);
qAdd = qX;
qAdd *= qY;
qAdd *= qZ;
mRigid.state.angPosition *= qAdd;
Point3F thrustForce(0.0f,500.0f,0.0f);
MatrixF rot;
mRigid.state.angPosition.setMatrix(&rot);
rot.mulV(thrustForce);
mRigid.state.linVelocity = thrustForce * 0.1f;
force = thrustForce;
force.set(0,0,0);
sForce = mRigid.state.linVelocity;//force;
sTorque = mRigid.state.linPosition;//torque;
//
mRigid.state.force = force;
mRigid.state.torque = torque;
}
03/28/2007 (2:09 pm)
Here's some old code I just dug up that I must have backed up.. I cut out the updateForces method, it might give you some ideas..#define PI (3.141592653589793238462643f)
#define TWO_PI (PI * 2.0f)
void SpaceVehicle::updateForces(F32 /*dt*/)
{
MatrixF currPosMat;
mRigid.state.getTransform(&currPosMat);
mRigid.atRest = false;
Point3F massCenter;
currPosMat.mulP(mDataBlock->massCenter,&massCenter);
Point3F xv,yv,zv;
currPosMat.getColumn(0,&xv);
currPosMat.getColumn(1,&yv);
currPosMat.getColumn(2,&zv);
currPosMat = getWorldTransform();
F32 speed = mRigid.state.linVelocity.len();
Point3F force = Point3F(0, 0, 0);
Point3F torque = Point3F(0, 0, 0);
F32 mPower = 10.0f;
sThrust = mThrust;
sSteering = mRigid.state.linVelocity;
//sSteering = mSteering;
// Maneuvering jets
/*
z = up/down
y = forward/back
x = left/right
*/
mCeilingFactor = 1.0f;
// Turbo Jet
//Point3F fwd(0.0f,1000.0f,0.0f);
//mRigid.state.angPosition.mulP(fwd,&force);
torque.set(0,0,0);
// Add in force from physical zones...
//force += mAppliedForce;
// Drag at any speed
//force -= mRigid.state.linVelocity * mDataBlock->minDrag;
torque -= mRigid.state.angMomentum * mDataBlock->rotationalDrag;
// Container buoyancy & drag
//force -= mRigid.state.linVelocity * mDrag;
//torque.set(0,0,0);
//force.set(0,0,0);
mRigid.state.angMomentum.set(0,0,0);
mRigid.state.angVelocity.set(0,0,0);
//mRigid.state.linVelocity.set(0,0,0);
sSteering = mRigid.state.linVelocity;
QuatF qX,qY,qZ,qAdd;
AngAxisF xang,yang,zang;
xang.set(xv,-mThrust.y * 0.01f);
yang.set(yv,mThrust.z * 0.01f);
zang.set(zv,mThrust.x * 0.01f);
qX.set(xang);
qY.set(yang);
qZ.set(zang);
qAdd = qX;
qAdd *= qY;
qAdd *= qZ;
mRigid.state.angPosition *= qAdd;
Point3F thrustForce(0.0f,500.0f,0.0f);
MatrixF rot;
mRigid.state.angPosition.setMatrix(&rot);
rot.mulV(thrustForce);
mRigid.state.linVelocity = thrustForce * 0.1f;
force = thrustForce;
force.set(0,0,0);
sForce = mRigid.state.linVelocity;//force;
sTorque = mRigid.state.linPosition;//torque;
//
mRigid.state.force = force;
mRigid.state.torque = torque;
}
#14
03/28/2007 (2:10 pm)
Basically, I used a quarternion to complete the rotation because I wanted to avoid gimbal lock. Of course this wont neccassarily work for you, but I did extend this code to point at a given target. This code basically works in any arbitrary ship orientation, so it didnt need a world "up" as far as I recall.. it was about 4 years ago after all :)
Torque 3D Owner Phil Carlisle
Its actually nothing to do with the rigid body so much as the rotation ordering.
Do the ships in Eve actually behave like real 3d space ships, i.e. they have no notion of "up"??
Or do they always essentially orient themselves in one plane (i.e. the can pitch and yaw, but not roll).