I try to create a compound collission with Newton. If i use only NewtonCreateConvexHull it works as expected. But when mixing Spheres and NewtonCreateConvexHull or only use Spheres (using the Offset Matrix), the Object does not Collide as expected ( the Object seems to leave the world in a unexpected way, the object rotates where it should not .. )
After reading this post i tried to switch the position index in the "id" matrix. But my object seems not to behave right.
So i think maybe i am freeing the memory of the Offset matrix to early, or, ... i don't know.
Maybe my thoughts of generating the newtoncreateCompoundCollision are generaly wrong. So did i missed something important here ?
Corpsman
- Code: Select all
Procedure TNewtonCompoundCollision.AddtoNewtonworld(Const Parent: Pointer;
Const Newtonworld: Pnewtonworld; Mass_, Material: Integer; Origin: TVector3;
callback: NewtonApplyForceAndTorque);
Var
Collision: Array Of PNewtonCollision; // TMP Variablen für die Collider
rescollider: PNewtonCollision; // Der Resultierende Collider
i, j: integer;
id: TMatrix4x4;
Inertia: TVector3;
Begin
If (high(Fpoints) = -1) And (high(FSPheres) = -1) And
(high(fCylinders) = -1) And (high(fCones) = -1) Then exit;
fmass := Mass_;
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;
id := IdentityMatrix4x4;
// Hinzufügen der Spheres
For i := 0 To high(FSPheres) Do Begin
// Die Position der Sphere mit einrechnen
// Todo : Klären wie das genau geht..
If (FSPheres[i].Point) = v3(0, 0, 0) Then Begin
Collision[j] := NewtonCreateSphere(newtonworld, FSPheres[i].Radius, FSPheres[i].Radius, FSPheres[i].Radius, 0, Nil);
End
Else Begin
id := IdentityMatrix4x4;
id[2, 0] := FSPheres[i].Point.x;
id[2, 1] := FSPheres[i].Point.y;
id[2, 2] := FSPheres[i].Point.z;
// id[0, 2] := FSPheres[i].Point.x;
// id[1, 2] := FSPheres[i].Point.y;
// id[2, 2] := FSPheres[i].Point.z;
Collision[j] := NewtonCreateSphere(newtonworld, FSPheres[i].Radius, FSPheres[i].Radius, FSPheres[i].Radius, 0, @id[0, 0]);
End;
inc(j);
End;
// Todo : Hinzufügen der Cylinder
// Todo : Hinzufügen der Cones
// Erzeugen des Gesamtkolliders
If High(Collision) = 0 Then Begin
rescollider := Collision[0];
End
Else Begin
rescollider := newtoncreateCompoundCollision(newtonworld, High(Collision) + 1, @Collision[0], 0);
End;
// Übernehmen dieses Pointers in die Newtonworld
id := IdentityMatrix4x4;
fNewtonBody := NewtonCreateBody(NewtonWorld, rescollider, @id[0]);
If Mass_ = 0 Then
NewtonBodySetMassMatrix(fNewtonBody, 0, 0, 0, 0)
Else Begin
Inertia := ZeroV3();
// Keine Ahnung für was der Inertia Vektor ist, aber so wird er erzeugt.
NewtonConvexCollisionCalculateInertialMatrix(rescollider, @Inertia, @Origin);
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
NewtonReleaseCollision(NewtonWorld, Collision[0]);
End
Else Begin
NewtonReleaseCollision(NewtonWorld, rescollider);
For i := 0 To high(Collision) Do Begin
NewtonReleaseCollision(NewtonWorld, Collision[i]);
End;
End;
Setlength(Collision, 0);
// 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
// Todo : Callback für die Schwerkraft
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;