Newton Game Dynamics

Panda3D has an internal physics engine, and there are several demos on how to use PyODE with Panda3D, so why another physics engine?

Well, basically because I wanted to get some more experience with Python/C++ integration. This goal is met. And because Newton is frequently used in small or medium game projects.

I will try to compare the three physics engines, but please keep in mind this is a personal opinion and my current state of knowledge (which might be wrong and incomplete):

Panda3D physics:

  • Very basic and made for particle systems, accoring to the Panda3D manual
  • No joints or restraints, few collision primitives
  • Sometimes funny collision response (e.g. pusher)

ODE:

  • Open source
  • Perhaps a little bit more ‘realistic’ than Newton
  • Problems with TriMesh/TriMesh collisions
  • Python bindings are mature

Newton:

  • Close source, but free (even for commercial use)
  • Perhaps a little bit ‘faster’ than ODE
  • Highly optimized collision (tree collision & convex hull)
  • Python bindings are alpha and still incomplete
  • Python bindings are tailored for Panda3D integration
  • Not much documentation

The biggest disadvantage of Newton is, in my eyes, that it is closed source. There are SDKs available for Windows, Linux and Mac, and using the physics engine even in commercial projects is free. But there is no guarantee that this won’t change in the future. On the other hand, if this should happen sometime, you can always continue using the last free version of Newton.

One of the main advantages of Newton is the highly optimized collision system. AFAIK you can create similar fast structures with ODE, using hash space and arranging bodies in subspaces, but considerable effort that has to be spent here. Feeding several 10’000 polygons to a single Newton tree collision (read: the full static environment) is easy and fast.

So it is probably a question of personal preferences between ODE and Newton. Anyway, here is the first release (0.3) of my Newton bindings for Panda3D:

http://www.dachau.net/users/pfrogner/PandaNewton.zip

The download contains the source code, several tutorials and the Windows binaries. The extension is compiled with VS Toolkit 2003 and single-threaded statically linked (\MT) against Newton 1.53 SDK and Panda 1.3.2.

Sorry, no unix/linux/whatever binaries so far, but the code is very vanilla, so it should be possible to compile it on other platforms too. Just tweak the makefile.

Future plans:

  • documentation
  • unfinished business (ragdolls, user defined 6DOF joint)
  • standalone collision system

enn0x

Hey…

What is the source of dVector.h, dMatrix.h, etc? I assume they’re from either Newton Win32 or MSVC? I have neither on Unix.

Just trying to get this extension to compile. :smiley:

I am curious how Bullet would do in your comparisson.
continuousphysics.com/Bullet/

Unfortunately it seems most of the documentation is not online atm.

@arrr

dVector etc. are from the Newton SDK, toolbox subdirectory, and get imported via “stdafx.h”. Hmmm… there might be several different stdafx.h files on your system, since this is a very popular name for standard includes, so perhaps it might be better to import dVector, dMatrix directly. Thanks for the tip. Will probably change this in the next release. Or change all dVector to float*, since I don’t really need the vector arithmetics.

@Laurens

I have been working with both Newton and ODE, but not with Bullet. Hard to make statements about something you don’t know. I better don’t attempt this.

But what I see from the link you gave me is that it is open source too, which is in my eyes positive. About Newton vs. ODE: the underlying C++ libs are about the same, differences have been listed mainly in the Python bindings. Mature but vanilla in case of ODE, vs. alpha and “Panda3D-oriented” in case of Newton.

I have not released the code because I want everybody to use Newton, but because it might come handy if you want to do own wrappers, or as an inspiration on how to modify ODE bindings.

Speaking about ODE bindings: ODE bindings are written in Pyrex, a Python wrapper language for C code. Syntax is roughly Python, so it is easy to code in Pyrex (for Python developers), and you don’t have to care about many of the Python/C-conversion details or reference-counting. I highly recommend spending some time on playing around with Pyrex if you want to speed up Python code. I haven’t solved all problems that come with using Pyrex for interfacing with C++ code (Panda3D is C++, no C), but this seems to be the way to go. And actually PandaNewton 0.2 (unreleased) is my first serious attempt at Pyrex/Panda3D.

enn0x

@ennox:

As you may be aware, “stdafx.h” is exclusively used by MSVC from Microsoft (not to be confused with precompiled headers):
http://en.wikipedia.org/wiki/Precompiled_header#stdafx.h

Also, ‘dVector.h’ and ‘dMatrix.h’ don’t exist in the Linux Newton SDK, I assume they’re win32 only.

I’ll try to change dVector to float32 and see what happens.

Tx!

Read careful please. This is quoted from your wikipedia link:

stdafx.h is used for project specific includes too. It is a common habit with MSVC projects to have a project-specific file named stdafx.h which contains frequently used things (e.g. vector math), but it is nothing exclusive to MSVC.

I agree it might not be the best coding style, but all Newton samples use a stdafx.h that ships with Newton SDK. So why re-invent the wheel. I adapted to Newton coding style when wrapping Newton.

By the way, I just downloaded the Linux SDK (1.53) and it does contain this header file too. Here is the path: newtonSDK/samples/toolBox/stdafx.h. These are the first three lines from this file:

// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently

enn0x

Finally the greatest sidekick is here. :smiley:
I have some Qs and suggestions :

1. Your mouse driven camera setup is hard to navigate. Instead of pushing away the scene, why not pulling back the camera (base.cam) ? By doing so, camera rotation pivot remains at base.camera (0,0,0), where the scene focus should be.

2.
vehicle tut
Your vehicle is a little odd, just like my old ODE car. The center of mass is lower than the axle, introducing the contrary behaviour of the real thing. You must want to avoid the roll, but setting it lower than the axle is weird. Why not decreasing the friction ?
I made these changes and it looks better :
vehicle mass : 900
vehicle center of mass Z offset : .1
level-tire material pair friction : 1, .8
It provides a wider range of driving styles.

what is tire grip ?
I didn’t see any difference no matter how I change it.

The finishing touch :
it’d be better if you apply wheel angle threshold, depends on car’s speed, just like any driving sim games, to provide safer turn. I use this equation in my ODE car :

        maxTurn = TOP_SPEED_TURN_LIMIT + WHEEL_TURN_RANGE * (FORWARD_LIMIT - abs(self.speed))/FORWARD_LIMIT
         self.wheelHeading = clampScalar(self.wheelHeading-WHEEL_TURNRATE*dt, -maxTurn, maxTurn)

3. Have you tried to avoid quantum tunnel ?

The rest is great !!

Wow! Great contribution! :smiley:

I’ll be sure to study this…btw, In your opinions of ODE and Newton you mention

—What are your opinions of the trimesh/trimesh collision of newton vs Pyode (ODE).
—When you mention a standalone collision system do you mean one that doesnt use the Newton SDK at all but your own perhaps?

Inspiring stuff…thanks for sharing!

BTW…thanks for the great text tutorials and documents…that in itself is awesome

Wow, quite a lot of questions. I try to answer as good as I can.

@Liquid7800

1. TriMesh/TriMesh collision becomes slow if the meshes get bigger. I think the first ODE “Egg & Bowl” demo demonstrates this. And they demonstrate how to cope with this, by replacing one TriMesh by several primitives (three spheres in this case, if I am right).

Next, according to the ODE userguide, size of timesteps has to be small for tri-mesh collision, and you have to track the position of tri-meshes outside of ODE for dCollideTTL to work efficient. The tutorial suggest something like this:

const double *DoubleArrayPtr =
    Bodies[BodyIndex].TransformationMatrix->GetArray();
        dGeomTriMeshDataSet( TriMeshData,
        TRIMESH_LAST_TRANSFORMATION,
        (void *) DoubleArrayPtr );

I haven’t seen similar code in the PyODE wrappers though. I’m not an expert on collision detection, but might be the problem of OPCODE is that it doesn’t distinguish between concave and convex collision shapes.

2. No, I meant something else. Newton, like ODE and Bullet, contains two mayor subsystems: collision detection, and dynamics (physics). In case if ODE the collision detection subsystem even has a name (OPCODE) and is interchangeable.

I meant to use the Newton collision system without using Newton rigid body physics. More explicit: create collision shapes, but no bodies, and then register collision callbacks, and implement collision response (if any) yourself. This could be handy if you don’t need a full-blown physics system for your game, or if you want to implement triggers (the player leaves an area, get’s close to an NPC, drives/flies over a waypoint)

Lauren has pointed me at Bullet, which is another physics engine, open source, with emphasis on collision detection. Bullet seems to have the same convex/concave collision shapes as Newton (convex hull, bounding volume hirarchy optimized triangle mesh), plus some nice additions (e.g. moving concave shapes via GIMPACT). And I heard rumors that ODE is going to exchange OPCODE for Bullet. So perhaps my plan will change, and after completing Newton documentation I will spend some more time on Bullet.

@ynjh_jo

1. I didn’t implement any camera control code because I wanted the tutorials to be as simple as possible, concerning code, not usability. In other words: focus on how to use Newton. Panda3D coders will know how to implement their own controls.

But you are right. If I want to convince people how ‘great’ Newton is then I would have to make attractive (visual, performance, mouse control) demos which not only show how to use Newton, but demonstrate it’s capabilities too. I will put it on a todo-List. Thank you for the suggestion.

2. Yes, I am aware the the demo vehicle is very odd. The car is intended to be ‘glued’ to the ground, and never roll over or slip away.

I never did a car game, so I lack experience here. But I have been playing some games (e.g. GTA SanAndreas, 4x4EVO, Need for Speed, Test Drive Off Road), and I noticed that what sells as ‘realistic’ vehicle dynamics is far from being realistic. Acceleration, suspension and ground traction are ridiculous in most cases. But this way games are more fun. And this is what games are for: having a good time. Well, back to your questions.

Right. The car’s center of mass has been set below the axle plane to avoid roll. The computed center has been discarded. Realistic would be to have it somewhere in the lower third of the car, near engine and drivetrain. So your value of +0.1 is perfectly realistic for this car egg file.

To avoid tire slip, even for acceleration beyond realistic values.

By the way, did you notice the increased gravity? Another trick I found on the Newton forums to keep the wheels on the ground.

Right. This simple demo allows only three values for wheel heading: -maximum, 0 +maximum. In real life, turning the steering wheel more than a little bit while going at full speed will result in a crash. But again, just a simple demo and not a full blown car game.

Tire.setGrip( ) is PandaNewton addition to Newton. That means, Newton doesn’t know such a method. It is valid only if you use the default tire callback. C++ Implementation of this callback follows a suggestion of wallaber (http://walaber.com/), given on the Newton forums. Walaber suggest a grip of 1 to 3 (hmm, wonder why I set it to 30).

This is what walaber suggest…

 Ogre::Real speed = tire->getOmega() * tire->getRadius();
Ogre::Real load = tire->getNormalLoad();

tire->setMaxSideSlipSpeed( speed * tire->getGrip() );
tire->setSideSlipCoefficient( speed * load * (tire->getGrip()) );

speed = tire->getLongitudinalSpeed();

tire->setMaxLongitudinalSlipSpeed( speed * tire->getGrip() );
tire->setLongitudinalSlipCoefficient( speed * load * (tire->getGrip()) ); 

…and this is part of my tire callback implementation

_tire = (PyTireObject*) NewtonVehicleGetTireUserData( vehicle, tireId );

load = NewtonVehicleGetTireNormalLoad( vehicle, tireId );
grip = _tire->m_grip;
omega = NewtonVehicleGetTireOmega( vehicle, tireId );

...

// side slip
if ( ! NewtonVehicleTireLostSideGrip( vehicle, tireId ) )
{
    speed = omega * _tire->m_radius;

    NewtonVehicleSetTireMaxSideSleepSpeed( vehicle, tireId, speed * grip );
    NewtonVehicleSetTireSideSleepCoeficient( vehicle, tireId, speed * grip * load );
}

// longitudal slip
if ( ! NewtonVehicleTireLostTraction( vehicle, tireId ) )
{
    speed = NewtonVehicleGetTireLongitudinalSpeed( vehicle, tireId );

    NewtonVehicleSetTireMaxLongitudinalSlideSpeed( vehicle, tireId, speed * grip );
    NewtonVehicleSetTireLongitudinalSlideCoeficient( vehicle, tireId, speed * grip * load );
}

So grip is a constant factor that increases longitudal and sideway traction, but valid only in the default (C++) callback implementation.

Implementation of this callback isn’t finished yet. Brakes are still missing and wheel relaxation has to be handled dependent on the current timestep. And it is not the only way to to it. The Newton forums offer more than one suggestion.

3. If it is high-speed collision detection you mean then the answer is yes and no. Yes, Newton has such a feature, and no, I did not test if it is working right. By the way: about 50% of the API is untested :slight_smile:

To enable high-speed collision detection (according to the SDK help files) you have to set continuous collision mode on the material pair and at least on of the two colliding bodies.

For the next release I want to complete object and method doc-strings. That means, just copy content from the SDK’s help files, and edit if something is different in Python. Perhaps some details become more clear then.

enn0x

Thx. What an explanation.

I didn’t talk about any fancy controls, but the way you set up your scene. It’s only about adding this 1 line :

base.cam.setY(-Y)

and instead of

yourModel.setPos(x, +Y, z)

you can put it at zero Y.
So camera focus is at your model.
So if the user rotate the camera at the 1st place, they wouldn’t be faced to the ground. Hey, there is nothing on the ground, so why doing that ? I just try to minimize the need to pan the camera.

Well, I’m not even a game dev’er. Moreover, I haven’t installed C/C++ in my head.

Thx again for spending so much time on this.

Yes, thanks for the in depth replies. I look forward to more experimentals.

@ynjh_jo

Ok, got you know. The next release (as soon as I have completed documentation and fixed some loose ends) will have the tutorials updated.

enn0x

Here is the next version of PandaNewton (0.4):
http://www.dachau.net/users/pfrogner/PandaNewton.zip

What is new:

(1) Documentation on all classes and methods. You can use e.g. pydoc to generate about 300k of html. Please don’t sue me for documentation quality, since it is only copy&pasted from the original SDK help files and modified where necessary. I even have copied most of the, well, orthographic weaknesses.

(2) Slight modification of the tutorials according to a suggestion of ynjh_jo. This is placement of scene objects and vehicle parameters. Tahnk you again, ynjh_jo

(3) Added some missing methods (e.g. stop alpha calculation). About 95 percent of Newton is wrapped now.

(4) RagDoll calbacks (both default and custom) are implemented now. The default implementation assumes a gravity of (0,0,-9.81).

(5) Default tire callback now has brakes implemented, and vehicle tutorial is updated. Down arrow kew now stops the vehicle.

(6) License is fixed to LGPL now.

What is still missing is a good example for ragdolls, including proper bone sizes and bone limits, either computed or measured from the actor model.

enn0x

Thanks for the awesome work! This’ll surely give a great starting place to use Newton dynamics with panda or similar things.

hmmm… following to the discussion this seems to be bigger than a normal “code snipplet” - maybe an idea for the showroom?

In case thats desired (and just and only in that case) just leave me a message to move the topic over there (maybe leaving a shadow topic here).

Seems to be great work :smiley:

  • Even if I haven’t had neither time nor ability to check the work in detail. :frowning:

Regards, Bigfoot29

Again a new version of PandaNewton (0.5). I didn’t have much time to work on PandaNewton or Panda3D in general the last few weeks, so it took me some time to finish this release.

http://www.dachau.net/users/pfrogner/PandaNewton.zip

New in version 0.5:

(1) “foreachFaceDo” callback, which can be used to draw a wireframe model of a bodies collision geometry for debugging purposes. A demo is provided too.

(2) It is now possible to set user defined per-face attributes (integer) for tree collisions and use them to customize contact behaviour. This can be used for example to simulate varying ground friction (ice, tarmac, grass, sand) for car games. No demo so far.

(3) UserDefinedJoint. This is a full customizable 6-DOF joint which can be used to create advanced physical constraints. It is unlikely that this joint type will be needed by anybody, but for the sake of completeness it is now wrapped too.

@bigfoot29
Thank you for the offer, but I’m fine with this place. I didn’t opt for the showroom because there is actually not much to “show”, in terms of good looking screenshots. And there is other great work here too (e.g. PandaSteer2 or EggOctree).

enn0x

Hello,

Do you know if PandaNewton is working against latest version of Panda?
I’ve copied the PandaNewton in my P3D folder.
The PandaNewton.dll from the download is located in the tutorials folder where i launch the
tutorial01 (“Getting Started”) from command line.

At the PandaNewton Import line, i’ve got the following error:

EntryPoint ?getPrimitive@geom@@QBEPVBGeomPrimitive@H@Z is not found in Libpanda.dll.

Should i recompile the PandaNewton.dll ?

Nota:I believe it may be linked to pandaversion because the error is thrown during the PandaNewton import but it’s shown as related to pandalib.dll. With simple PyNewton, i dont have the error.

In all case it looks like a real good work.

[/code]

Yes, PandaNewton is linked against both Panda3D and Newton. I have uploaded a new version which is linked against current Panda3D release (1.4.0). New version because I have added some missing raycast methods.

http://www.dachau.net/users/pfrogner/PandaNewton.zip

Right now I discourage using PandaNewton. Might be I have been trying to be too smart when making PandaNewton, but I have experienced some random crashes. Probably I am been stealing NodePath references somewhere. Whatever, for now I suggest using either ODE or PhysX (if the small part of PhysX that has been wrapped by now is sufficient for your needs).

I will touch PandaNewton again when the new Newton version is out, and then it will probably be a mayor re-design using interrogate, so it will be some time before I will post results.

enn0x

Ok so i guess i wil try to use Newton with only PyNewton :slight_smile:

Hello,

I’m currently using Newton with the ctypes module in python.
I would have a question regarding the Axis.

It seems to me that Panda Axis and Newton Axis are different.

ex: in Tutorial gravitiy is set like this (0,-9.8*mass,0)
However if i apply it in my simulation my boxes goes horizontally.
I have to do gravity like this :frowning:0,0,-9.8mass) to have the box goes downward.

So i wonder if it’s my P3D matrix to Newton and Newton to P3D matrix conversion that is false or if there is really different Axis convention in Panda and Newton.

In this later case, should i:
_ modify matrix calculation code
or
_ can i only invert the components when i set / get position of Newton Body from a PandaObject.
ex: if pBox.getPos() gives X,Y,Z
should i use it in newton like it said X,Z,Y?

Thanks for your inputs

Best regards…