Hovercraft physics in NxOgre

AnonymousTipster

21-01-2007 15:40:27

Hi, I'm working on a project which involves futuristic hovering vehicles made popular by games such as Wipeout and Fzero, and I'm currently trying to simulate this type of craft in NxOgre.
I've tried using 4 wheel shapes, but it feels quite linear and too much like a car. I'm currently experimenting with just one wheel shape to keep the object afloat.

My question is this: how would you solve this sort of problem to give a craft that feels like it isn't touching the ground whilst maintaining a tight feel?

betajaen

21-01-2007 16:04:02

Yep, the levitator class. Just basically makes a body hover x metres of the ground.

The class is floating in the NxOgre source and include directory under the name nxOgre_levitator.cpp / .h

AnonymousTipster

21-01-2007 16:50:50

What a handy class, thanks! :D

AnonymousTipster

21-01-2007 18:32:39

Update:
I have a cube-shaped levitator in my scene, and I'm trying to control it using
m->mBody->addLocalForce(Ogre::Vector3(0,0,-9000 * _time));For acceleration, andm->mBody->addTorque(Ogre::Vector3(0 ,-10,0)); for steering.
Although it floats above the floor nicely, after some turning or a light collision with another object, the levitator spins around. I increased the angular damping to 30, which helped somewhat, but it still tilts to one side, rather than applying forces to equalise the rotation. Any further damping nullifies my steering torque.
I think this code:// Keep upright.

Ogre::Quaternion upright = Ogre::Quaternion(1,0,0,0);//mRayCaster->mHitBody->getGlobalOrientation();
Ogre::Quaternion torque = upright - mBody->getGlobalOrientation();

Ogre::Vector3 a(
torque.getRoll().valueRadians(),
torque.getYaw().valueRadians(),
torque.getPitch().valueRadians()
);
Should keep the levitator upright, but it doesn't seem to be strong enough, and multiplying the torque values doesn't seem to help either.

Any clues?

betajaen

21-01-2007 18:37:42

Thats how far I got trying to get it to keep it up right. You can cheat and just limit the angle of rotation, but then it'd look a little weird.

I believe the math is slighty wrong in there, it probably just requires some more fiddling.

AnonymousTipster

23-01-2007 16:14:45

Turns out there's a slerp function built into Ogre, which I tried using for this, and it works well as follows:
Quaternion v0 = mBody->getGlobalOrientation();
v0.normalise();
Quaternion v1 = Quaternion(1,0,0,0);
v1.normalise();
Quaternion v2;
v2 = Quaternion::Slerp(0.01,v0,v1,true);
mBody->setGlobalOrientation(v2);

Which resets the object's rotation at a decreasing rate. There are two main problems with this method:
A. It uses setOrientation rather than applyTorque, which means that the rotation doesn't look very hovercraft-like.
B. It corrects rotation on all axes, but I want to allow rotation on the object's y-axis to allow turning.

betajaen

23-01-2007 16:56:53

Couldn't you do something like this:

torque = (currentOrientation) - (targetOrientation) / deltaTime
...
for deltaTime:
apply torque


Or something to that effect?

AnonymousTipster

23-01-2007 17:04:04

Wouldn't that be the same as the original levitator code?

betajaen

23-01-2007 17:21:49

Pretty much, I was just hoping you'd implement it better ;)

AnonymousTipster

23-01-2007 19:30:52

The big problem is retaining the y-rotation. The methods i've come up with so far work fine in the x-axis and z-axis, but if the y-axis is changed, the correction doesn't work. It is equally puzzling for me to think of a way of slerping whilst leaving the y-rotation unchanged. It would probably require a good deal of knowledge on quaternions (which I unfortunately do not have).

I may end up opting for a wheel shape based option instead.

Wyszo

24-06-2007 13:06:25

:/

I just wanted to read the code of the levitator class, but it seems that it was removed from NxOgre after Release Candidate 1 (which afaik is not available to download any more). Why did you removed this class, betajaen?

betajaen

24-06-2007 13:21:08

I took out the prefabs because they were making the library too big and enforcing class onto people that people may not of wanted. We use "Helpers" now which are basically half of a prefab. You create the physically implementation yourself, and the helper binds it together with NxOgre and makes it go.

Back to the class though, although I don't have it on me handy. It's just a force that counteracts gravity:


float displacement = 5.0f; // How high of the ground (In metres)
actor->addForce(Vector3(0, 9.80665 * actor->getMass() * displacement,0), NX_SMOOTH_IMPULSE);

Wyszo

24-06-2007 13:44:09

O_o

That won't help me much. I thought it would be a good hovercraft physics example, but I was far from the truth. It can only pretend to be hovercraft when ground is completely flat :P Then I am not surpriced that this class was deleted.

Pottej

27-06-2007 12:04:26

Hi, I'm working on a project which involves futuristic hovering vehicles made popular by games such as Wipeout and Fzero, and I'm currently trying to simulate this type of craft in NxOgre.
I've tried using 4 wheel shapes, but it feels quite linear and too much like a car. I'm currently experimenting with just one wheel shape to keep the object afloat.


Are you in a 'DTBD' team? If you don't know what that means then just ignore me :)

squishleheimer

03-03-2008 03:59:12

I also have rudimentary knowledge of Quaternions and have been wrestling with this issue. I ended up just going with the "zeroing the angular velocity" approach.

{
Vector3 g = MyApp::getSingletonPtr()->getCurrentWorld()->getNxScene()->getGravity();
double mass = m_pBody->getMass();

if (m_pBody->getGlobalPosition().y < m_height)
{
m_pBody->addForce(-g*mass*m_height);
}

Quaternion o(Radian(getAngle()), Vector3::NEGATIVE_UNIT_Y);

m_pBody->setAngularVelocity(Vector3::ZERO);
m_pBody->setGlobalOrientation(o);
m_pBody->setLinearVelocity(Vector3(m_velocity.x,0,m_velocity.y));
m_position = m_pBody->getGlobalPosition();
}


getAngle() is a private method to the Agent that returns the angle of the current heading vector (a Vector2D).

m_position and m_velocity are decoupled from the physics and are part of my steering bejavier framework.

This makes my little hovering agents rigid and tough like mini-juggernaughts but they hover nicely at m_height and don't get buffeted about by collisions.

It would be preferable to have them pitch and roll a tad when they collide and then self-correct using forces but I can't seem to get my head around it.