setVelocity not setting :-S

RichTufty

06-03-2007 18:19:33

OK, I have a SceneNode attached to a Body (elipsoid) and have the camera attached to the SceneNode. I want to apply velocity to the Body so that the camera moves with the Body, and so that the body can have collision detection.

I am setting the correct velocity to the Body, i know this because i can see the values in debug.

I have set the size of the world to be very large.

I thought maybe that the world wasn't updating, but when i turn gravity on, the camera falls to the ground, which is great, but my other forces aren't working.

Am i completely missing something?!

I am using Mogre + MogreNewt.

Here's some of my code:



newtonWorld = new World();
newtonWorld.setWorldSize(new Mogre.Vector3(-10000, -10000, -10000), new Mogre.Vector3(10000, 10000, 10000));

Mogre.Vector3 cameraSize = new Mogre.Vector3(1f, 1f, 1f);

Collision cameraCollision = new MogreNewt.CollisionPrimitives.Ellipsoid(newtonWorld, cameraSize);
cameraBody = new Body(newtonWorld, cameraCollision);
cameraCollision.Dispose();

cameraBody.setMassMatrix(10.0f, MomentOfInertia.CalcEllipsoidSolid(10.0f, cameraSize));
cameraBody.attachToNode(cameraNode);


I call this every frame:



newtonWorld.update(elapsedTime);


This bit of code is based on another thread in the forum





if (keyState[DXI.Key.RightArrow]) {
direction = get_body_orientation(cameraBody) * Mogre.Vector3.NEGATIVE_UNIT_X;
update = true;
}

velocity = cameraBody.getVelocity() * new Mogre.Vector3(0, 1f, 0) + direction * 30f * fps_speed;

cameraBody.setVelocity(velocity);



Am i missing anything?! Any help would be much appreciated!

Cheers,
Tufty

Scorch

06-03-2007 22:41:57

I think SetVelocity only works in a "setCustomForceAndTorqueCallback" callback.

You need to register a force and torque callback, then save the value you are going to apply before calling update, and then when you call update your callback will be called, and you can set the velocity there.

walaber

07-03-2007 04:41:36

you can call setVelocity anywhere, so your problem must be elsewhere...

Scorch

07-03-2007 05:36:46

Oh, sorry walaber,
looking at the documenation, only the force and torque methods say


this function is only valid inside a ForceCallback function


My bad thinking it applied to velocity and omega too.

RichTufty

07-03-2007 15:41:33

After more playing about, the velocity works only when i have Gravity set to true! But i don't want gravity! Is this right? Can i turn gravity off?

RichTufty

07-03-2007 16:11:10

OK... so the velocity only works when the body is falling because of gravity, when the body hits the ground and stationary, the velocity doesn't kick in, have i completly misunderstood how velocities work, etc... ? help! :-(

Scorch

07-03-2007 16:30:42

just guessing.

but is your velocity pointing tward the ground? if so you will just push up agianst it untill your velocity changes the other direction.

Also you might check into freeze/unfreeze. I don't think that is it, but it might be related?? not sure.

RichTufty

07-03-2007 16:40:27

I have different keys to set the velocity in different directions, bit loose at the mo, but just wanna get the thing working then can tighten up the code:


if (keyState[DXI.Key.UpArrow]) {
direction = get_body_orientation(cameraBody) * Mogre.Vector3.UNIT_Z;
update = true;
}
if (keyState[DXI.Key.DownArrow]) {
direction = get_body_orientation(cameraBody) * Mogre.Vector3.NEGATIVE_UNIT_Z;
update = true;
}
if (keyState[DXI.Key.LeftArrow]) {
direction = get_body_orientation(cameraBody) * Mogre.Vector3.UNIT_X;
update = true;
}
if (keyState[DXI.Key.RightArrow]) {
direction = get_body_orientation(cameraBody) * Mogre.Vector3.NEGATIVE_UNIT_X;
update = true;
}

if (update)
velocity = cameraBody.getVelocity() * new Mogre.Vector3(0, 1f, 0) + direction * 30f * fps_speed;

cameraBody.setVelocity(velocity);

Scorch

08-03-2007 01:39:55

Unrelated comment on your code:
you may want to clear out direction at the begining then use "direction +=" instead of "direction =" so you can move both forward or and left at the same time.

As for why you are stopping, could it be

if (update)
velocity = cameraBody.getVelocity() * new Mogre.Vector3(0, 1f, 0) + direction * 30f * fps_speed;


are you sure you want to add the velocity to the existing velocity and not just use the new velocity? Just thinking that if you are running into a wall really really fast, and then pull back. move fast forward + move back = move forward still.

You may also try printing the final velocity to a debug out or to a log.


On mine, I start with an empty direction vector, then if the forward key is pressed I add 1 to the z field, if the left is pressed I subtract 1 from the x field and so forth. then to keep my velocity a consitant magnatude I do :

finalVelocity = direction.normalizeCopy() * movementSpeed;

(where movementSpeed is a float ).

Works well for me, but everyone has their own way.

walaber

08-03-2007 05:40:21

it stops working because the body falls "asleep", and is removed from the active body list.

if you add unfreeze() before you call setVelocity(), it will work perfectly.

RichTufty

09-03-2007 11:38:15

walaber - THANK YOU! Works great now!! I didn't realise that all bodies were frozen straight away, i probably missed that somewhere!