Project Unity

Share with us how are you using the powerrrr of the force

Moderator: Alain

Project Unity

Postby Stucuk » Tue May 17, 2005 12:49 pm

Unity Video (2mb)
Unity Video - Newton (1mb)

Note: Since fraps is evil it reduced the FPS to around 20-30 fps. The Newton video was speeded up by 2x to compensate for fraps evilness.
User avatar
Posts: 800
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Postby tomek » Tue May 17, 2005 1:06 pm

Very nice!

How did you managed to make that stack of boxes collapse without slowdowns?
Posts: 102
Joined: Wed Jun 23, 2004 12:34 pm

Postby Sascha Willems » Tue May 17, 2005 2:43 pm

Looking nice Stucuk! Always great to see some other people that use Delphi for their interesting projects.

And as for the framerate with fraps :
I use fraps to for capturing videos (see e.g. the ones for the NewtonPlayGround) and don't have problems with physics timing during capture. What timing method are you using? I'm using accumulative time-slicing for all physics apps now and it's by far the best method to get consistent physics behaviour at all different framerates.
User avatar
Sascha Willems
Posts: 346
Joined: Fri Aug 27, 2004 10:18 am
Location: Germany

Postby Stucuk » Tue May 17, 2005 5:24 pm


The minute they start collapsing fps goes up.(unless fps is already at the cut off stage, 60 fps in my case) There created in the map editor as cubes and done in the app as convex hulls.(Yes a cube could be used insted of convex hull but since there generated in the map editor they could be triangles, bannanas, cars, anything)

P.S Source Added to End.

Delphi Rox, Down with C++!!!!!! heh.

Well im sending the newtonupdate thingy the Frametime(using a timer to work out how much time has passed between frames). Which is generaly 0.001 or something.

What exactly is time slicing? Using the newtonupdate more than once depending on fps?

For anyone who hasn't played Return To Castle Wolfenstien in the Unity Video the levels shown are all from Return To Castle Wolfenstien.

How to make ur own Newton_Object!!! (Proberly useless to ppl.... anyway... Newton_Object is the class the boxes are)
Code: Select all
Procedure Newton_Object_Process(Self : PBSPEntity); cdecl;

Self.HasMass := True;



Procedure CreateNewtonObjectEntity(Self : PBSPEntity; Const NoGrav,NoCollision,Strip,CollisionTree : Boolean);

Self.NewtonIndex := -1;

If not (copy(Self.model,1,1) = '*') then exit;

Self.mid := strtoint(copy(Self.model,2,length(Self.model)));

If (Self.mid < 0) or (Self.mid > Engine.Map.BSP.numOfModels-1) then exit;


Self.NewtonIndex := Engine.Map.BSP.numOfNewtonObjects-1;

If not Self.HasMass then
Self.Mass := 0
If Self.Mass = 0 then
Self.Mass := 100;

Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1] := TNewtonObject.Create;
Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].EntityIndex := Self.EntityIndex;
Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].Mass        := Self.Mass;
Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].ClassType   := FindEntityTypeId(Self.Classname);
Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].model       := Self.mid;
Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].Origin      := Engine.Map.BSP.StripOriginFromModel(Self.mid,Strip);
If Self.OriginUsed then
Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].Origin      := AddVector(Self.Origin,Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].Origin);
Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].NoGrav      := NoGrav;
Engine.Map.BSP.Data.NewtonObjects[Engine.Map.BSP.numOfNewtonObjects-1].NoCollision := NoCollision;

If not CollisionTree then


Procedure CreateNewtonObject(var pSceneBSP : TBSPMap; const ModelId : Integer; IsDNDMesh : Boolean; NewtonObjectId : Integer; Angles : TVector3f);
 Collider : PNewtonCollision;
 Mass : Single;
 Inertia,Size : TVector3f;
 M : TMatrix4f;

     If IsDNDMesh then
    // Collider := CreateConvexHullFromModel_DNDMesh(pSceneBSP,ModelId)
     Collider := CreateConvexHullFromModel(pSceneBSP,ModelId);

     pSceneBSP.Data.NewtonObjects[NewtonObjectId].Body  := NewtonCreateBody(Engine.Newton.NewtonWorld, Collider);

     If IsDNDMesh then
     //Size := SubtractVector(pSceneBSP.DNDMeshs[ModelId].Header.max,pSceneBSP.DNDMeshs[ModelId].Header.min)
     Size := SubtractVector(pSceneBSP.Data.Models[ModelId].max,pSceneBSP.Data.Models[ModelId].min);
     Size := DivVector2(Size,2);
     // Calculate real moment of inertia
     Mass    := pSceneBSP.Data.NewtonObjects[NewtonObjectId].Mass;
     Inertia := V3(Mass * (Size.X * Size.Y + Size.X * Size.Z) / 12,
                   Mass * (Size.Y * Size.X + Size.Y * Size.Z) / 12,
                   Mass * (Size.Z * Size.X + Size.Z * Size.Y) / 12);
     pSceneBSP.Data.NewtonObjects[NewtonObjectId].Inertia := Inertia;
     NewtonBodySetMassMatrix(pSceneBSP.Data.NewtonObjects[NewtonObjectId].Body, Mass, Inertia.X, Inertia.Y, Inertia.Z);

// Set spawn position
Matrix_SetTransform(M, pSceneBSP.Data.NewtonObjects[NewtonObjectId].Origin);
// Some orientation
Matrix_SetRotation(M, Angles);
NewtonBodySetMatrix(pSceneBSP.Data.NewtonObjects[NewtonObjectId].Body, @M[0,0]);
pSceneBSP.Data.NewtonObjects[NewtonObjectId].Matrix := M;
// Set callbacks
NewtonBodySetMaterialGroupID(pSceneBSP.Data.NewtonObjects[NewtonObjectId].Body, Engine.Newton.MatWater);
NewtonBodySetForceAndTorqueCallBack(pSceneBSP.Data.NewtonObjects[NewtonObjectId].Body, PhysicsApplyGravityForce);
NewtonBodySetTransformCallBack(pSceneBSP.Data.NewtonObjects[NewtonObjectId].Body, PhysicsSetTransformNewtonObject);
NewtonReleaseCollision(Engine.Newton.NewtonWorld, Collider);

NewtonBodySetUserData(pSceneBSP.Data.NewtonObjects[NewtonObjectId].Body, pSceneBSP.Data.NewtonObjects[NewtonObjectId]);

// Create a Convex Hull for a model (not the world model)
Function CreateConvexHullFromModel(const pSceneBSP : TBSPMap; ModelID : Integer) : PNewtonCollision;
 TmpFace : array [0..2] of TVector3f;
 TmpFaceNo : Integer;
 TmpM    : TMatrix4f;
 Min     : TVector3f;
 Max     : TVector3f;
 m,f,c     : Integer;

c := 0;
if pSceneBSP.numOfFaces > 0 then
   for f :=[ModelID].faceIndex to[ModelID][ModelID].numOfFaces-1 do
   If[f].FaceType = 1 then
   If[f].numMeshVerts > 0 then

     for m := 0 to[f].numMeshVerts-1 do
     inputBuffer[c] :=[[f][[f].meshVertIndex+m]];


Result := NewtonCreateConvexHull(Engine.Newton.NewtonWorld,c,@inputBuffer[0].Position.x,SizeOf(TRBSPVertex),Nil);


// Below is the force n torq thingy the Newton_Object uses
procedure Default_Newton_Process(NewtonObject : PNewtonObject; Matrix : TMatrix4f; Mass,Ixx,Iyy,Izz : Single); cdecl;
Force : TVector3f;

 if Engine.Map.BSP.IsInWater(SetVector(Matrix[3,0],Matrix[3,1],Matrix[3,2])) then
 // Body is in fluid, so we add buoyancy forces
 Force := SetVector(0, -0.17, 0);
 NewtonBodyAddBuoyancyForce(NewtonObject.Body, 0.1, 0.9, 0.9, @Force, GetBuoyancyPlane, nil);
 // When in a fluid, we don't want our body to get autofreezed
 NewtonBodySetAutoFreeze(NewtonObject.Body, 0);
 // Body is not in fluid, so just apply normal gravity
 Force := SetVector(0, Mass * -Engine.Newton.GravValue, 0);
 NewtonBodySetForce(NewtonObject.Body, @Force);
 // When outside the fluid, we can use the autofreezing feature of newton
 NewtonBodySetAutoFreeze(NewtonObject.Body, 0);

//Gravity value
Engine.Newton.GravValue := 19.8;
User avatar
Posts: 800
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Postby Julio Jerez » Tue May 17, 2005 9:20 pm

Very nice demo Stucuk I see you are using the bouyancy funtionality, It is very nice to see a fresh demo in the show case.
I was wonder if the door is opening using a hinge or by doing your technique of resetting the velocity.
I hope you really mater the technique of using joints, it is not that complex one you get the ideas how they work, I see lot of potencial in you engine.
Julio Jerez
Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Postby Stucuk » Wed May 18, 2005 8:35 am

i use a hinge joint. Tho its a bit buggy.... proberly how i restrict the doors movement.

I basicaly apply torq to the door so it opens and wrongly "null" the velocity, torq, etc when i want the door to stop moving (when it gets to the end of how much it can open)

I see lot of potencial in you engine.


P.S 1.30 rox! (Collision Trees with mass!)
User avatar
Posts: 800
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Postby tomek » Wed May 18, 2005 8:46 am

Stucuk wrote:P.S 1.30 rox! (Collision Trees with mass!)

Hey, stop cheating :wink:
Posts: 102
Joined: Wed Jun 23, 2004 12:34 pm

Postby cleathley » Wed May 18, 2005 8:56 am

very sweat..
User avatar
Posts: 63
Joined: Sat May 22, 2004 12:19 am
Location: Perth, Australia

Postby Julio Jerez » Wed May 18, 2005 9:51 am

I see, you find it buggy because, it is difficult to control object with forces. So what the Newton school of rigid body dynamics for students of the dart site do. We call on the oracle and the Oracle say:
“We will add PID class to the SDK with good demos of Sliding doors and platform, so the user can see how this thing can be control with almost not overshooting”.
New SDK will add PID for simple control of objects with joints.

PID is not part of the engine it will all be implemented in the SDK tutorials.
Julio Jerez
Posts: 10954
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Postby Sury » Wed May 18, 2005 12:08 pm

Fantastic video !
Can't wait to try a demo out of this.
User avatar
Posts: 193
Joined: Sat Aug 14, 2004 5:32 am
Location: Bulgaria

Postby Stucuk » Wed May 18, 2005 2:31 pm

Err whats PID? (I know no Physical terms.... except force.... torq.....etc)

Flyby Video (3MB - 1 Minute 11 Seconds) - Basicaly just some flyby's on 3 Q3 levels and some Elite Force levels.

Unity Demo (1.43MB)

Included with the demo is 3 small levels.

If you own Return To Castle Wolfenstein, Quake 3 or Elite force you can extract the pk3 files to the directorys included in the zips and unity will read the levels (And with RTCW run the cutscenes). Jedi Knight 2, 3 and Soldier of fortune 2 material does work with unity but there is lightmap problems. (Evil RBSP's)

W,S - Forward, Backwards
A,D - Strafe
Space - Action

Mouse 1 + Drag - Rotates camera
Mouse 2 + Drag - Moves newton objects

Note: Unity is far from finished, most entitys havn't been made and there is no actual "player" yet. (its just a camera that flys around and through the level)

Following things are still to be done:
MDS files (stores charactors bodys)
Weapon System
User avatar
Posts: 800
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Postby Electron » Wed May 18, 2005 3:21 pm

PID=proportinonal integral derivative controller. Personally i don't quite understand the calculus terms but PID controllers often approximate them anyway. integral is basically the accumulated error over time and derivative is the rate fo change of the error (I think). The PID controllertakes the current error as input and generally gives the steer angle as output. A PID controller can give smoother more natural looking steering than proportional control alone. The main hard part is tweaking the three coefficients (one for each term) to yield desired response speeds, avoid overshoot, etc.
User avatar
Posts: 10
Joined: Sat Apr 03, 2004 8:09 pm
Location: Massachusetts USA

Postby Stucuk » Fri Aug 05, 2005 10:53 pm

Website Launched (no new downloads yet, tho there is some new pics)

Project Unitys Website

Note: The one picture with a 'full' flag from RTCW was edited so its not Illegal in Germany.
User avatar
Posts: 800
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Return to User Gallery

Who is online

Users browsing this forum: No registered users and 1 guest