Newton Dynamic Physics Integration

Programming Reality Factory and Genesis3D.
Post Reply
User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Newton Dynamic Physics Integration

Post by federico » Wed Sep 19, 2007 3:42 am

I know, this doesn't seem rational: I'm implementing the Newton Dynamics Physics Engine in RF.

Tokamak was a Nout's choice, and it was a good choice ( for several reason I don't need to repeat), but I always felt disturbed by the engine limitations and instability (the latter in particular). Now that the TOKA integration is quite stable, I wanted to make some final tests. So:

1) I wanted to try the Genesis3d internal physics. I used the Nout's schema and it was quite simple. The Genesis3d physics entities work as storage devices for the physics calculation but the engine doesn't provide that calculation, you have to do all the work by yourself (collision, math...). :x

2) The alternatives were: Newton SDK, Bullet Physics, Simple Physics engine, True axis.
The choice relied on:
- proven stability (search walaber on google)
- development and updates frequency
- ease of use and integration
- features that are lacking in tokamak: native ragdoll, native vehicle, more shapes (cone, Chamfer Cylinder, orientable capsule)

Newton is quite similar to Tokamak. The prove is that I was able to integrate it in RF using the Nout's tokamak integration as my path. Newton is better in updating procedures, using internal callbacks to update only the bodies that need to be moved or rotated. The issues are quite the same: RF has an enourmous world scaling, so the simulation must be tweaked setting the Iteration and StepTime (and eventually solving the problem internally somehow).

I integrated the rigidbody simulation. The next step is to add BSP collision. I have to understand how pass the data I get with the G3d sirkorgans BSP defan function to the newton collision callbak. I know kikosmalltalk got it (if you are listening, please show up and help :wink: )

Video:
Newton RigidBody Simulation: http://video.tinypic.com/player.php?v=63axlog&s=1

User avatar
zany_001
Posts: 1047
Joined: Fri Mar 02, 2007 8:36 am
Location: Aotearoa

Post by zany_001 » Wed Sep 19, 2007 4:35 am

:D you are awesome fredireco!!!whatever you decide to do, Im going to say its the right choice, becase your more experienced than me. Sortof as an offtopic, i was thinking, i should make a GE called Dream Factory and it could be a sister project to RF, but focused on strategy and possibly racing, which means better physics. If this was to happen, i would need you, fredireco, to be a part of it cos i couldnt do physics, and you could probably help me with more simple stuff too. But if QoD thinks RF2 will be able to do good strategy and racing games, there would be no point.QoD?
Once I was sad, and I stopped being sad and was awesome instead.
True story.

User avatar
QuestOfDreams
Site Admin
Posts: 1520
Joined: Sun Jul 03, 2005 11:12 pm
Location: Austria
Contact:

Post by QuestOfDreams » Wed Sep 19, 2007 8:53 am

:? To be honest I don't really like the Newton SDK cause it has a really ugly license (similar to the old Tokamak license)
http://www.newtondynamics.com/SDKLicense.html

User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico » Wed Sep 19, 2007 10:25 am

Yes you're right, it's not free but it's opensource.
Newton Game Dynamics SDK License Version 1.52
Copyright 2003-2006 Newton Game Dynamics. All rights reserved.

LIMITED WARRANTY
This software is provided "as-is", without any express or implied warranty.
In no event shall the author be held liable for any damages arising from the use of this software.

This is a contract. By accepting the Newton Game Dynamics SDK (the SOFTWARE), you (either an individual or a single entity, the LICENSEE) accept the terms and conditions of this licensing agreement.

If the LICENSEE does not accept the terms and conditions, then LICENSEE must not accept the SOFTWARE.

If at a later time the LICENSEE decides not to continue licensing the SOFTWARE under these terms and conditions, then the LICENSEE must delete permanently all files constituting the SOFTWARE.


LICENSE AGREEMENT
Newton Game Dynamics Limited grants to the LICENSEE and the LICENSEE hereby accepts a perpetual nontransferable and nonexclusive license to use and distribute the SOFTWARE, for any purpose. In addition, the following conditions apply:

1) The LICENSEE may not use the SOFTWARE to reverse engineer the computer algorithm used by the SOFTWARE.

2) The origin of the SOFTWARE must not be misrepresented; If the LICENSEE uses the SOFTWARE to distribute a product, the LICENSEE must not claim that He or She wrote the original SOFTWARE.

3) The LICENSEE agrees to credit the use of the Newton Game Dynamics in any program information, including splash screens, "About" dialogs, program notes or instructions and shrink-wrapped packaging.

4) The LICENSEE may not redistribute the SOFTWARE, except as part of a compiled software program that is not itself a physics library.

5) The LICENSEE agrees to notify http://www.newtondynamics.com of any products, commercial, shareware or free that incorporate the Newton Game Dynamics technology.
...but it's still better than the Genesis3d license. That is for us a splash screen, a note in the credits menu, a copy of their license in the RF one, an email to http://www.newtondynamics.com.
4) The LICENSEE may not redistribute the SOFTWARE, except as part of a compiled software program that is not itself a physics library.
means only the source, not the dll.

I don't know if Newton will be a better solution for RF than tokamak. I will release both for you. As I said in another post, I want to work on a release candidate instead of a community release. I want your approval and feedback, QoD. So please
follow this transformation and let me know what do you think about.

User avatar
paradoxnj
RF2 Dev Team
Posts: 1328
Joined: Wed Mar 01, 2006 7:37 pm
Location: Brick, NJ
Contact:

Post by paradoxnj » Wed Sep 19, 2007 3:22 pm

What about ODE? That is LGPL which is compatible with Genesis.

User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico » Wed Sep 19, 2007 4:51 pm

I tried but I wasn't able to integrate it, sorry. Anyway I think Newton it's more lightweight and somehow easier: it has a vehicle container and a ragdoll container as well. I think that the tokamak alternatives (same power and complexity) are: Newton, SPE (Simple physics engine), True Axis. Newton is the more similar (that's why I tried it, and that's why I was able to integrate it) to Tokamak.

I know why you suggest another engine but my early tests say that Newton is much better than Tokamak for RF. The power is quite the same but Newton shows more stability with the slow Genesis. It's a stressful condition for a physics engine. The Tokamak simulation sometimes "goes crazy" and in general it's more free (try to understand) while the Newton Dynamics simulation is deterministic: you can make that boxes fall for hundred of times: they will fall all the time in same manner.

About the license I don't think negative: it's even better (or the same) than the Genesis license.

User avatar
paradoxnj
RF2 Dev Team
Posts: 1328
Joined: Wed Mar 01, 2006 7:37 pm
Location: Brick, NJ
Contact:

Post by paradoxnj » Wed Sep 19, 2007 5:45 pm

5) The LICENSEE agrees to notify http://www.newtondynamics.com of any products, commercial, shareware or free that incorporate the Newton Game Dynamics technology.
Make sure you notify Newton Dynamics that RF is using Newton.

kikosmalltalk
Posts: 37
Joined: Mon Sep 25, 2006 1:12 pm

Post by kikosmalltalk » Fri Sep 21, 2007 8:02 pm

Hi Federico

My code is Smalltalk

I made it this way:


Code: Select all

NewtonParser(Class)>>parse: aGenesisWorld  to:aNewtonWorld  with:pFCallback    
  
   "Parse the Genesis world geometry to Newton geometry"    
  
       |treeCollision|           
                        
treeCollision:=NewtonTreeCollision create: aNewtonWorld   
                                                       with: pFCallback.   
treeCollision beginBuild.                               
self parseGeometry:aGenesisWorld to:treeCollision.  
treeCollision endBuild.   
^treeCollision  
  
  
NewtonParser(Class)>>parseGeometry: aGenesisWorld to: treeCollision  
  
       "Parse the Genesis world geometry to Newton Tree Collision"    
  
   |vertex arrayVertex  numVertex   arrayIndex  index numIndexs vertexPtr hModule   |    
     
vertex:=LONG localNew.      
index:=LONG localNew.  
numVertex:=LONG localNew.    
numIndexs:=LONG localNew.       
hModule:=HModule loadLibrary: 'C:\\Archivos de programa\\Smalltalk MT 5.2\\Genesis3d\\Genesis.dll'.       
  
hModule callProc: 'geWorld_GetWorldGeometry'  
            with: aGenesisWorld   
            with:  vertex basicAddress   
            with: numVertex  basicAddress  
            with: index     basicAddress  
            with: numIndexs basicAddress.     
              
                          
                          
                         
arrayVertex := Array new: numVertex asInteger. "Array of GeVec3D structures"   
  
  
1 to:numVertex asInteger do:[:j | arrayVertex at:j put:(GeVec3D fromBytes:(vertex asInteger + (12 * (j - 1))))].  
    
  
arrayIndex :=Array new: numIndexs asInteger.     
1 to: numIndexs asInteger do:[:x | arrayIndex at:x   
     put:(MemoryManager atAddress: (index asInteger  + (4 * (x - 1))))].  
     
1 to: (arrayIndex size//3) do:[:i |    
        
    vertexPtr:= GeVecMatrix new.   
   vertexPtr _0:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+3)) x.           
   vertexPtr _1:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+3)) y.      
   vertexPtr _2:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+3)) z.    
   vertexPtr _3:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+2)) x.           
   vertexPtr _4:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+2)) y.           
   vertexPtr _5:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+2)) z.           
   vertexPtr _6:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+1)) x.           
   vertexPtr _7:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+1)) y.           
   vertexPtr _8:(arrayVertex at: 1+ (arrayIndex at:((i-1)*3)+1)) z.          
                        
    
treeCollision addFace:vertexPtr   ].   
WINAPI free: index  .  
WINAPI free: vertex.   
hModule close.  



I used the sirkogan function directly and I don't implement the function inside my smalltalk for not losing time.

GeVecMatrix is a structure with 3 vector.

I implemented these methods a long time ago.
I made it the more quick possible, it is possible that this has things to correct or to optimize.
But it can surely serve so that you understand as passing him you data to Newton.
If you don't understand something, please don't doubt to ask.


Kiko

PD: If there is something to optimize I also want to listen to it

kikosmalltalk
Posts: 37
Joined: Mon Sep 25, 2006 1:12 pm

Post by kikosmalltalk » Fri Sep 21, 2007 8:12 pm

Hi

Federico that scale will use?


kiko

User avatar
paradoxnj
RF2 Dev Team
Posts: 1328
Joined: Wed Mar 01, 2006 7:37 pm
Location: Brick, NJ
Contact:

Post by paradoxnj » Fri Sep 21, 2007 9:18 pm

Federico, kiko is referring to the following post on the Genesis forums:

http://www.genesis3d.com/forum/viewtopi ... 37&forum=3

User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico » Fri Sep 21, 2007 9:19 pm

Thanks kiko. I really appreciate your help. Anyway this morning I got it working. Looking at your code I see we came at the same result in two different ways. :D

Video: http://video.tinypic.com/player.php?v=4v3vmkx&s=1

This is my solution:

Code: Select all

	
if (CollideWithBsp == true)
	{	
		NewtonCollision* g_newtonmap;
		NewtonBody* g_newtonmapbody;

		//Create the Newton trecollision
		g_newtonmap = NewtonCreateTreeCollision(nWorld, NULL);
		NewtonTreeCollisionBeginBuild(g_newtonmap);	

		geVec3d *verts = NULL;
		int numVerts = NULL;
		long *indices = NULL;
		long numIndices = NULL; 

		int v1i, v2i, v3i;
		// Get the world data from the BSP + put it into the TreeCollision
		if(geWorld_GetWorldGeometry(CCD->World(), &verts, &numVerts, &indices, &numIndices))
		{ 
			for(i = 0; i < numIndices; i+=3)
			{
				float vArray[9]; // vertex array (3*3 floats)
				
				v1i = indices[i+2];
				v2i = indices[i+1];
				v3i = indices[i+0];
				
				vArray[0] = verts[v1i].X;
				vArray[1] = verts[v1i].Y;
				vArray[2] = verts[v1i].Z;
				vArray[3] = verts[v2i].X;
				vArray[4] = verts[v2i].Y;
				vArray[5] = verts[v2i].Z;
				vArray[6] = verts[v3i].X;
				vArray[7] = verts[v3i].Y;
				vArray[8] = verts[v3i].Z;

				NewtonTreeCollisionAddFace(g_newtonmap, 3, (float*)vArray, sizeof(float)*3, i);
			}
			
			char szError[256];
			sprintf(szError, "BSP added to the Physics System with %d Vertices and %d Faces", numVerts, numIndices/3);
			CCD->ReportError(szError, false);
		}
		//Stop Building the TreeCollision and Create the Terrain Body
		NewtonTreeCollisionEndBuild(g_newtonmap, 0);
		g_newtonmapbody = NewtonCreateBody(nWorld, g_newtonmap);
	
		NewtonReleaseCollision(nWorld, g_newtonmap);
	}
	

Please stay tuned I need to compare some of my solutions with yours. For example, how did you set the proper rotation of the objects using matrices?

I created a method that uses this code:

Code: Select all

geVec3d Angles;
		geVec3d_Set(&Angles,Rot.X*0.0174532925199433f,Rot.Y*0.0174532925199433f,Rot.Z*0.0174532925199433f);
		
		geXForm3d M;
		geXForm3d_SetEulerAngles(&M,&Angles);

		float matrix[16]; 

		matrix[0] = M.AX;
		matrix[1] = M.BX;
		matrix[2] = M.CX;
		matrix[4] = M.AY;
		matrix[5] = M.BY;	
		matrix[6] = M.CY;
		matrix[8] = M.AZ;
		matrix[9] = M.BZ;
		matrix[10] = M.CZ;

		matrix[12] = Origin.X;
		matrix[13] = Origin.Y;
		matrix[14] = Origin.Z;
		
		NewtonBodySetMatrix(rigidBody[Ph_rNr], &matrix[0]);
It doesn't seem to set the rotation correctly...
Thanks.
Last edited by federico on Fri Sep 21, 2007 9:42 pm, edited 1 time in total.

User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico » Fri Sep 21, 2007 9:30 pm

ops! we were answering at the same time... :lol:

I don't use scale. I saw a post in the newton forum about scaling down the physics world, but I didn't tried yet. I use the method Nout wrote for tokamak:

Code: Select all

//Tick
	float dwTicks = 0.0f;
	dwTicks = (float)(TimeTicks)/IterationTime;
	
	//Whooo...., the preparation job is done !
	//Run now the real physics simulation
	//Calculate the new positions for all rigid bodies

	//If the engine is slow, run multiple physics loops
	for (int p = 0; p <(1 + dwTicks); p++) 
	{
		NewtonUpdate (nWorld, AdvanceTime*0.01f);
	}
Iteration is the number of physics loop to run every frame and AdvanceTime is the time (millisecons?) we want to advance the simulation every frame.
dwTicks id the parameter passed to the Tick method on the physicsmanager. It's a variable that stores the RF internal time. Anyway dwTicks is the same as you call CCD->GetTimePassed_F(); that is

Code: Select all

/* ------------------------------------------------------------------------------------ */
//	Get the amount of time passed since the last call, in milliseconds.
//	..Return the result as a floating-point value.
/* ------------------------------------------------------------------------------------ */
geFloat CCommonData::GetTimePassed_F()
{

	geFloat DeltaTime;

	DeltaTime = (geFloat)TimeCounter - (geFloat)LastTimePoll;

	LastTimePoll = TimeCounter;
	
	LastTimePassed_D = (DWORD)DeltaTime;		// Last elapsed time as DWORD
	LastTimePassed_F = DeltaTime;						// Need in both places
	
	return DeltaTime;
}
@paradoxnj
yes, thanks, I know that post. The sirkorgan function was created for a tokamak integration and was the main basis for the Nout's integration of TOKA. the problem is that newton wants the vertices in a different ordered so I had to fight to find some info about how to pass a Quake-like BSP geometry on the physics engine....

kikosmalltalk
Posts: 37
Joined: Mon Sep 25, 2006 1:12 pm

Post by kikosmalltalk » Wed Sep 26, 2007 3:37 am

Hi Federico.

I could not see your video but I believe that this can help


http://www.newtondynamics.com/forum/vie ... ighthanded


If I intuit their problem well

KIKO[/u]

kikosmalltalk
Posts: 37
Joined: Mon Sep 25, 2006 1:12 pm

Post by kikosmalltalk » Wed Sep 26, 2007 4:01 am

Hi Federico

I transform this way:

from: aGeXForm3d

"Return an instance of the receiver from aGeXForm3d"

|answer |


answer:=NewtonMatrix new.
answer _as:NewtonMatrix.
answer _11: aGeXForm3d ax;
_12: aGeXForm3d ay;
_13: aGeXForm3d az;
_21: aGeXForm3d bx;
_22: aGeXForm3d by;
_23: aGeXForm3d bz;
_31: aGeXForm3d cx;
_32: aGeXForm3d cy;
_33: aGeXForm3d cz;
_41: (NewtonVector fromBytes:(aGeXForm3d translation)) x;
_42: (NewtonVector fromBytes:(aGeXForm3d translation)) y;
_43: (NewtonVector fromBytes:(aGeXForm3d translation)) z .
^answer.

This topic perhaps can help .

http://www.newtondynamics.com/forum/vie ... highlight=


KIKO

User avatar
federico
RF Dev Team
Posts: 443
Joined: Tue Jul 05, 2005 3:14 pm
Contact:

Post by federico » Sun Sep 30, 2007 3:30 am

thanks alot kiko, but I solved in another way. The problem was the initial matrix definition. In fact, if the object isn't active, the matrix modification doesn't affect the physical body. In the first loop of the Tick, I set a loop to pose and rotate the bodies.

Well, physics is quite ready! whoooo :wink:
This version will be simpler than the Nout's Tokamak integration, having less entities and features, but it should be more intuitive for the Rf user. In the editor you can set Rigid and Static Bodies (Static bodies are bodies with 0 mass) assigning a mass and a Material to each body. You can define several materials using the PhysicsMaterial entity, defining the physical parameters (softness, frictions, elasticity) and the impact sound used in the collision callback. The ragdoll works quite well even at these early stages and I was able to re-use my code to place and rotate the actor bones. The shooting code works even better with newton.

VIDEO: http://youtube.com/watch?v=chARlTWvigA

TO-DO:

- Right now there's a lack of a physicsJoint entity for the Worldeditor (quite easy)
- the PhysicsScript entity must be re-arranged a bit: simplified. Basicly the joint, material body creation commands plus some command to control the bodies (freezing, unfreezing, apply impulse forces, set the rotation/position) and the joints (set the limits and break the joint).
- I need to understand better the timeslicer (I will probably need some help with the optimization...).

Newton works better than tokamak in every aspect. It's more stable, the simulation is more deterministic, and the general feeling is more solid. In the API there are generalized procedures to handle the physics event in a easy way. In the video you can listen to the material-defined impact sounds. In tokamak that was a unresolved point, in newton there's a callback to handle the collision event: 1 line of code to call all the procedure, and all the work is taken by the material system. 8)

A physics engine inside the old genesis3d bears performance issues, but they are smaller than the tokamak ones and the sleeping mode works better: when an object has a really small velocity, the engine takes it as static and stops the physics calculations and updates for that body. Anyway my dev machine is really low-end so I can't actually appreciate the impact on the application itself (testers are welcome!).

I hope you can enjoy my efforts. One-two weeks and it should be ready.

@QoD I integrated newton from scratch to have all the source commented. I hope you can evaluate this as a release candidate (0.76A?) and take a look at it personally.

Federico

Post Reply