PDA

View Full Version : 2d Overhead + Newton



Colin
07-07-2009, 03:12 PM
hi, i've been having alot of problems trying to get Newton to work full stop, not to mension i'd like it to be used for 2d physics....

i guess i am doing something wrong. hope someone can help.

on engine load.


var
min,max : Single;
begin
NewtonWorld := NewtonCreate(nil, nil);

min := -25000;
max := 25000;
NewtonSetWorldSize(NewtonWorld, @min, @max); //temp until i finish the map loader.
NewtonSetSolverModel(NewtonWorld, 0);



i then load x amount of `civilians`


New(civ);
civ.Initialise(NewtonWorld, @SpriteEngine);


which is as follows:


procedure TAICivilian.Initialise(newtonW: PNewtonWorld; se: PCoSpriteEngine);
var
Inertia : TCoVector3;
Value : TCoVector3;
Force : TCoVector3;

Collision: PNewtonCollision;
begin
Sprite := se.NewSprite('.\aiciv.PNG', 512, 64);
Sprite.X := 512;
Sprite.Y := 360;
Mass := 1;

Collision := NewtonCreateBox(newtonW, 64, 64, 64, nil); //temp
Sprite.NewtonBody := NewtonCreateBody(newtonW, Collision);
NewtonReleaseCollision(newtonW, Collision);

//all temp values until i get newton working.
Inertia.x := Mass * (64 * 64 + 64 * 64) / 12;
Inertia.y := Mass * (64 * 64 + 64 * 64) / 12;
Inertia.z := Mass * (64 * 64 + 64 * 64) / 12;
NewtonBodySetMassMatrix(Sprite.NewtonBody, Mass, Inertia.x, Inertia.y, Inertia.z);

F_Matrix[3,0] := Sprite.X;
F_Matrix[3,1] := Sprite.Y;
F_Matrix[3,2] := 0;
NewtonBodySetMatrix(Sprite.NewtonBody, @F_Matrix[0,0]);
NewtonBodySetForceAndTorqueCallback(Sprite.NewtonB ody, ForceAndTorqueCallback);
end;



on each frame i call to move the civilians


procedure TAICivilian.Move(delta: Double);
var
matWorld: TCoMatrix;
begin
NewtonBodyGetMatrix(Sprite.NewtonBody, @matWorld[0,0]);
Sprite.X := matWorld[3,0];
Sprite.Y := matWorld[3,1];


after move is called they are then drawn


procedure TCoSprite.Draw(Dev: IDirect3DDevice9);
var
rcSource: TRect;
vPosition: TD3DXVector2;
begin
rcSource.Left := (F_CurFrame * F_Width)-64;
rcSource.Right := F_CurFrame * F_Width;

rcSource.Top := F_TextureY;
rcSource.Bottom := F_Height;

with vPosition do begin
x := F_X;
y := F_Y;
end;

F_Sprite._Begin(D3DXSPRITE_ALPHABLEND);
F_Sprite.Draw( F_Texture, @rcSource, nil, @vPosition, $f0f0f0f0 );
F_Sprite._End;
end;


and finally, at the end of frame NewtonUpdate is called... and so... nothing happens, sprites do not move at all. and i've been trying alsorts of things to get it to work.


-Colin

chronozphere
07-07-2009, 03:50 PM
What do you expect? I see nothing in your code that should make your civilians move. ???

I'm just learning Newton myself, and I see that you have correctly setup the world and added collision and body's. Then, you register a few callbacks and wait for something to happen. Nothing happens by itsself though. You need to apply forces on objects to make them move. :)

Colin
07-07-2009, 03:57 PM
yes i apply forces via the ForceAndTorque callback, in my case the characters should fall somewhere.... (as a test)


procedure ForceAndTorqueCallback(const body : PNewtonBody); cdecl;
var
Mass : Single;
Inertia : TCoVector3;
Force : TCoVector3;
begin
NewtonBodyGetMassMatrix(Body, @Mass, @Inertia.x, @Inertia.y, @Inertia.z);
with Force do begin
X := -6;
Y := -6 * Mass;
Z := -6;
end;
NewtonBodySetForce(Body, @Force.x);
end;

NecroDOME
07-07-2009, 05:44 PM
try this:
- NewtonWorldUnfreezeBody
if that doesn't work try these:
- NewtonBodySetFreezeTreshold
- NewtonBodySetAutoFreeze

(reference: http://www.newtondynamics.com/wiki/index.php5?title=List_of_all_newton_functions_in_1 .35)

Colin
07-07-2009, 07:09 PM
hi NecroDOME thanks but unfortunatly these neither work.

chronozphere
07-07-2009, 07:39 PM
Have you been playing with any newton samples? did they work?

Try to find the differences between your code and any sample code. That should lead you to the sollution. :) It might also be a good idea to keep toying around with those numbers. Maybe your masses are too big or your forces too small.

Colin
07-07-2009, 08:44 PM
yes i have been doing that :P

i have solved my problem finally... it just happens that the sample i was using as a reference did not work neither lol the world size were as singles, after spending a while looking through the Newton Wiki (good resource)......


with min do begin
x := -500;
y := -500;
z := -500;
end;
with max do begin
x := 500;
y := 500;
z := 500;
end;

NewtonSetWorldSize(NewtonWorld, @min, @max);


my problem was (stupid), thanks for your replies.

my only problem now is keeping the characters on a 2d plane, i have no idea how todo that with Newton, i've been searching google for the past hour.

-Colin

NecroDOME
08-07-2009, 06:54 AM
yeah well, since newton is a 3D collision solver you have to do some manual steps.

I never done it, but here are some suggestions:
- Make 2 huge invisible wall's (cubes would do the trick) and put them to the side of your game so nothing can fall off.
- Every move-frame set the Z to zero.

User137
08-07-2009, 07:56 AM
You just quoted min/max use before, can you set Z to 0 for both min and max there?

NecroDOME
08-07-2009, 07:58 AM
If a body goes outside of the newton boundary, it just stops. So that's not gonna work.

JernejL
09-07-2009, 11:02 PM
- Make 2 huge invisible wall's (cubes would do the trick) and put them to the side of your game so nothing can fall off.
- Every move-frame set the Z to zero.


#1: bad idea, a lot of contacts will get generated for no useful purpose
#2: would probably work but if you set matrix to keep Z on zero, newton will re-build some internal structs to place the body into proper internal scene graph place, which can be slow with a lot of bodies.

I would suggest writing a specialized joint that keeps bodies on ground level, or you can check out this project, they likely do what you need to keep bodies at "ground":


PPIsaac is an OOP wrapper of the Newton Game Dynamics engine and is especially designed for 2D game environments.

http://www.pyroplay.de/ppisaac.html

However for starters, a upvector joint (so bodies dont fall down) with a ground level & gravity can get you started for 2d use in no time.