i have written a program using newton 2.33, linux 32-Bit and everything worked fine.
Now i changed my linux to 64-Bit and needed to recompile all my projects in order to use them.
unfortunatunely i was not able to get a linux 64-Bit version from the old newton ver 2.33 so i had to switch to the newest 3.14 version.
As i am writing in Free Pascal i implemented a wrapper class that handles all my newton relevant stuff (to better support all that changes)
In Basic i only use the primitives (points, boxes, cones, spheres ..) and combine them to compound collision, as far as i found out until now this has to be done different now. Hoping that someone of you will help me to reimplement the specific part (and funny thing only these 100 lines needs to be changed) i post them here. Some hints / tutorials how to make this would also help
All relevant method names are the same as in the c++ version so i think even if you do not program Pascal you can get the idea of the code.
In short i do this
1. Create a lot of Newtoncollision
2. Combine them with "newtoncreateCompoundCollision" to a single one
3. give it a mass if needed
4. Set it to a special material
To make things clearer i added a few comments in english, the original code was commented in german
- Code: Select all
Procedure TNewtonCompoundCollision.AddtoNewtonworld(Const Parent: Pointer;
Const Newtonworld: newtonworld; Mass_, Material: Integer; Origin: TVector3;
callback: NewtonApplyForceAndTorque);
// in pascal you need to declare all your variables at the beginning
Var
Collision: Array Of NewtonCollision; // TMP Variablen für die Collider
rescollider: NewtonCollision; // Der Resultierende Collider
i, j: integer;
id: TMatrix4x4;
Inertia: TVector3;
b: Boolean;
Begin
If (high(Fpoints) = -1) And (high(FSPheres) = -1) And
(high(fCylinders) = -1) And (high(fCones) = -1) Then exit;
fcallback := callback;
fparent := Parent;
fmaterial := Material;
FnewtonWorld := Newtonworld;
fmass := Mass_;
fOrigin := Origin;
// Create a array that holds all the single objects that later on needs to be combined to one big compound collision
setlength(Collision, high(Fpoints) + high(FSPheres) + high(fCylinders) + high(fCones) + 4);
// Hinzufügen der Convexen Hüllen
j := 0;
For i := 0 To high(Fpoints) Do Begin
Collision[j] := NewtonCreateConvexHull(newtonworld, high(Fpoints[i]) + 1, @fpoints[i][0], 12, 0, 0, Nil);
inc(j);
End;
// Hinzufügen der Spheres
For i := 0 To high(FSPheres) Do Begin
// Die Position der Sphere mit einrechnen
If (FSPheres[i].Point) = v3(0, 0, 0) Then Begin
Collision[j] := NewtonCreateSphere(newtonworld, FSPheres[i].Radius, 0, Nil);
End
Else Begin
id := IdentityMatrix4x4;
id[3, 0] := FSPheres[i].Point.x;
id[3, 1] := FSPheres[i].Point.y;
id[3, 2] := FSPheres[i].Point.z;
Collision[j] := NewtonCreateSphere(newtonworld, FSPheres[i].Radius, 0, @id[0, 0]);
End;
inc(j);
End;
// Hinzufügen der Cylinder
For i := 0 To high(fCylinders) Do Begin
id := fCylinders[i].RenderData.Matrix;
id[3, 0] := fCylinders[i].Center.x;
id[3, 1] := fCylinders[i].Center.y;
id[3, 2] := fCylinders[i].Center.z;
Collision[j] := NewtonCreateCylinder(Newtonworld, fCylinders[i].Radius, fCylinders[i].Radius, fCylinders[i].Height, 0, @id[0, 0]);
inc(j);
End;
// Hinzufügen der Cones
For i := 0 To high(fCones) Do Begin
id := fCones[i].RenderData.Matrix;
id[3, 0] := fCones[i].Center.x;
id[3, 1] := fCones[i].Center.y;
id[3, 2] := fCones[i].Center.z;
Collision[j] := NewtonCreateCone(Newtonworld, fCones[i].Radius, fCones[i].Height, 0, @id[0, 0]);
inc(j);
End;
// Erzeugen des Gesamtkolliders
If High(Collision) = 0 Then Begin
rescollider := Collision[0];
End
Else Begin
(*
* This routine is not available anymore with ver 3.14
*)
rescollider := newtoncreateCompoundCollision(newtonworld, High(Collision) + 1, @Collision[0], 0);
End;
// Übernehmen dieses Pointers in die Newtonworld
id := IdentityMatrix4x4;
(*
* This routine is not available anymore with ver 3.14
*)
fNewtonBody := NewtonCreateBody(NewtonWorld, rescollider, @id[0]);
Inertia := ZeroV3();
// Der Inertia wird vorberechnet, falls das Objekt später noch Beweglich wird.
NewtonConvexCollisionCalculateInertialMatrix(rescollider, @Inertia, @Origin);
finertia := Inertia; // Speichern falls das Object später noch beweglich wird.
If Mass_ = 0 Then
NewtonBodySetMassMatrix(fNewtonBody, 0, 0, 0, 0)
Else Begin
NewtonBodySetMassMatrix(fNewtonBody, Mass_, inertia.x * Mass_, inertia.y * Mass_, inertia.z * Mass_)
End;
// Remove the collider, we don't need it anymore
If High(Collision) = 0 Then Begin
(*
* This routine is not available anymore with ver 3.14
*)
NewtonReleaseCollision(NewtonWorld, Collision[0]);
End
Else Begin
(*
* This routine is not available anymore with ver 3.14
*)
NewtonReleaseCollision(NewtonWorld, rescollider);
For i := 0 To high(Collision) Do Begin
(*
* This routine is not available anymore with ver 3.14
*)
NewtonReleaseCollision(NewtonWorld, Collision[i]);
End;
End;
Setlength(Collision, 0);
// Todo : Das hier ist der Totale hack, aber nur so lassen sich Wippe und Barrier gleichzeitig "gefühlt" richtig Simulieren !
//b := (high(FSPheres) = -1) And (high(fCylinders) = -1) And (high(fCones) = -1) And (mass <> 0);
//If b Then
NewtonBodySetCentreOfMass(FNewtonBody, @Origin); // Setzen des Masseschwerpunktes, dieser sollte Eigentlich (0/0/0) sein !
// Now set the position of the body's matrix
NewtonBodyGetMatrix(fNewtonBody, @id[0, 0]);
id[3, 0] := fPosition.x;
id[3, 1] := fPosition.y;
id[3, 2] := fPosition.z;
NewtonBodySetMatrix(fNewtonBody, @id[0, 0]);
// Set the Material Group
NewtonBodySetMaterialGroupID(fnewtonbody, Material);
// Set the User Data = Pointer to Parent Class
NewtonBodySetUserData(fNewtonBody, parent);
// Set ForceCallback if Needed
If Fmass <> 0 Then Begin
NewtonBodySetForceAndTorqueCallBack(fNewtonBody, callback);
// Dafür sorgen das die Engine unseren Player nie Blockiert !!
(*
Removed for 2.0
*)
//NewtonWorldUnfreezeBody(NewtonWorld, fNewtonBody);
//NewtonBodySetAutoFreeze(fNewtonBody, 0);
// *)}
End;
End;
Furthermore it seems that the routines
NewtonSetBodyLeaveWorldEvent
and
NewtonSetWorldSize
where gone too, are they not needed anymore ?