Ode & movement


#1

Hi,

I just want try to use ODE, and it is the first time, I use a physical engine.

For the moment, I had a ship at first person view. I load a model into a node, and when I push Q button, I change the hpr of my node to go left, and so on.

By now, I had a body and a geom to my ship. It seems I have to add force to my body to move it.

My questions are:
Do I have to change HPR to my odeBody?
If yes, have I just to add force from the back to the forward (something like that? odeBody.addForce( Vec3(0,0,1000) ) )?
If no, how to move my ship in the right direction?

Thank you


#2

For my character I use body.setLinearVel(vec3), I find it easier to control than with addForce. For rotation I rotate the model (heading) and then do body.setQuaternion(model.getQuat()). This seems to work good for a character, but maybe not for a ship if you want it to respond realistically.


#3

Can you tell how to use setlinearVel?
Which vec3 you give to setlinearvel? in which case?

Thank you


#4

For example, body.setLinearVel(Vec3(2, 0, 0)) will make the body move at a speed of 2 meters per second in the positive X axis. The movement is relative to the rotation of the body if I remember correctly, but I could be wrong on that.
If you have friction in your simulation you need to apply this after each physics step to prevent it slowing down. So you could keep calling setLinearVel as long as the user holds down a button, then stop calling it when they let go.


#5

I will test that.

Thank you for information anyway…


#6

Just a think I have…
If you put the hpr to the node through model, when you collide, how do you manage the new hpr given by by ode, if you override it always by hpr of the model?

Indeed, when you collide with another surface/mesh, your model will change of direction, to simulate physical!


#7

I do this only for my character which is a sphere, so the rotation does not really matter.
You might look at coppertop’s ODE solution as well: [url]ODE Middleware]


#8

You said that what you’re trying to control is a ship, right? Might be a spaceship (moving in 3D) or a regular ship (moving in 2D).

In either case, the most important question is, do you want this ship to behave like a physical object (with inertia) or like a kinematic object (no inertia, every move is 100% scripted).

Both solutions have their pros and cons, but I guess you’d be better off with a physical object in this case (since you’re going into ODE anyway). It would give you an object controlled by forces simulating any kind of a steering mechanism. The good news is that setting it up is relatively easy (in this case, it’s different for human characters). The bad news is that tweaking it so it works correctly can be a nightmare.

If you want to make it a physical body, then you should try to not touch the position or rotation by hand. Instead, you should rely 100% on ODE’s body mechanics – adding forces (to center or to point) to move and adding torque to turn. You can also set the linear velocity directly (if you want the ship to move at particular speed then it’s easier than forces).

Hope this helps.


#9

Yes it helps.
It is some 3D ships, like eve online.

I will use only ODE mechanisms, because I want benefit of this engine.

Ok, by now, I got only one problem, how to simulate rotation (as hpr in standard panda node)?

Can you try to provide a simple exemple, if you go down, or left for example?

Thank you


#10

You will use one of these methods:

OdeBody.addTorque(torque) # torque is Vec3
OdeBody.addForceAtPos(force, pos) # force and pos are Vec3, pos is in *render* space
OdeBody.addForceAtRelPos(force, relPos) # force and pos are Vec3, pos is in *ship's* space

The first one, obviously, adds torque to your body. The other two add forces, applying them to specific points in World Space (that’s the second one) or in Ship’s space (that’s the third one).

With addForceAtRelPos you could, for instance, accurately simulate the space shuttle’s OMS.

I haven’t tried doing what you’ll doing, so I don’t know which methods will work best. I guess some will work in some cases, and others in other cases. You’ll have to experiment :wink:.

You’ll find the global addForceAtPos method probably more useful for reacting to damage (recoil on explosions or bullet hits) than steering.


#11

For the future generation here my code to turn, and accelerate :

To turn with Q,S,D,Z:

	if self.keysDown.has_key('q'):
			if self.keysDown['q']!=0:
				self.odeBody.addTorque((0,0,1))
				self.currentTorqueZ+=1
		if self.keysDown.has_key('d'):
			if (self.keysDown['d']!=0):
				self.odeBody.addTorque((0,0,-1))
				self.currentTorqueZ+=-1
		if self.keysDown.has_key('z'):
			if (self.keysDown['z']!=0):
				self.odeBody.addTorque((1,0,0))
				self.currentTorqueX+=1
		if self.keysDown.has_key('s'):
			if (self.keysDown['s']!=0):
				self.odeBody.addTorque((-1,0,0))
				self.currentTorqueZ+=-1

To move forward:

	forwardVec=Quat(self.odeBody.getQuaternion()).getForward()
		self.odeBody.setLinearVel(forwardVec.getX()*self.speed,forwardVec.getY()*self.speed,forwardVec.getZ()*self.speed)

and of course, apply the new coordinate to the model:

self.shipModel.setPos( self.odeBody.getPosition() ) 
		self.shipModel.setQuat( Quat(self.odeBody.getQuaternion()) )