Semi trailer joint

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Semi trailer joint

Postby JernejL » Tue Dec 01, 2009 6:14 am

I'm going to try and add towed trailers to my little top down game.

Now i don't know what kind of joint would be efficient and generally a good idea to use for this, but the best one that would function well in 2D environment would be a simplistic constraint that holds two points on two bodies close without any angular limits, like a very stiff spring joint, has anybody written a joint like this that i could use?
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1587
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Semi trailer joint

Postby Dave Gravel » Tue Dec 01, 2009 10:36 am

Here I use the Universal joint, I know it's surely so much for you need.
In 3d with big rigs it is important to can have access to some angle limitation, and the universal have this limite.
In 2d you only need to let's it turn left and right ? you don't need limitation ?

http://sites.google.com/site/orionx3d/S ... e_0003.wmv
http://www.youtube.com/watch?v=k8XA7JJuQYw
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://orionx3d.sytes.net
https://www.facebook.com/dave.gravel1
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 801
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: Semi trailer joint

Postby samisaham » Tue Dec 01, 2009 2:32 pm

If it's 2d, how about a simple hinge joint?
samisaham
 
Posts: 15
Joined: Mon Mar 24, 2008 11:59 am

Re: Semi trailer joint

Postby JernejL » Tue Dec 01, 2009 2:49 pm

samisaham wrote:If it's 2d, how about a simple hinge joint?


That won't work, the 2D cars are flat sprites, but physical bodies can still tilt on slopes.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1587
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Semi trailer joint

Postby Julio Jerez » Tue Dec 01, 2009 3:13 pm

[quote="Dave Gravel"][/quote]


Darn boy, where did you have that one?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Semi trailer joint

Postby Dave Gravel » Tue Dec 01, 2009 6:59 pm

lol the demo and script soon I working on that last night.
I let's you know.
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://orionx3d.sytes.net
https://www.facebook.com/dave.gravel1
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 801
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: Semi trailer joint

Postby JernejL » Wed Dec 02, 2009 6:23 pm

Dave: is that a universal joint? you got some pointers on how to use NewtonConstraintCreateUniversal? i'm clueless as how to set up the pivot and 2 pin dirs, what i tried so far made the bodies explode spectacularly in my face :( a illustration would me help a lot.

EDIT: managed to get this working with a ball & socket joint, looks good so far: http://mathpudding.com/tdc/tdctrailers.avi
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1587
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Semi trailer joint

Postby Dave Gravel » Thu Dec 03, 2009 1:10 am

My universal is the same that you can find in the customjoint code, but adapted for my system.
I have the 6 dof too that one can make any types, but in the video it is the simple custom universal.
PS: In the video the limite is not active but in the normal demo yes.

Something like this...

Code: Select all
constructor TOXCUniversalJoint.Create(aOwner: TPersistent);
begin
  inherited Create(aOwner);
  JointPinLength:=50.0;
  MaxDOF:=6;
  LocalUse:=False;
  FJointLimitOn0:=false;
  FJointLimitOn1:=false;
  FJointAngularmotorOn0:=false;
  FJointAngularmotorOn1:=false;
  FJointMinAngle0:=-45.0;
  FJointMaxAngle0:=45.0;
  FJointMinAngle1:=-45.0;
  FJointMaxAngle1:=45.0;
  FJointAngularDamp0:=0.5;
  FJointAngularAccel0:=-4.0;
  FJointAngularDamp1:=0.3;
  FJointAngularAccel1:=-4.0;
  FMinAngle0:=0;
  FMaxAngle0:=0;
  FMinAngle1:=0;
  FMaxAngle1:=0;
 // Use callback create method because I have multiple methods to init joint...
  OnCustomBothCreate:=CustomBothCreate;
  OnCallBack:=SubmitConstrainst;
end;
{******************************************************************************}
//  [v2.11 2009]: TOXCUniversalJoint SetJointMinAngle0
{******************************************************************************}
procedure TOXCUniversalJoint.SetJointMinAngle0(val: cfloat);
begin
  if val<>FJointMinAngle0 then begin
    FJointMinAngle0:=val;
    FMinAngle0:=FJointMinAngle0*oxPIdiv180;
  end;
end;
{******************************************************************************}
// [v2.11 2009]:  TOXCUniversalJoint SetJointMaxAngle0
{******************************************************************************}
procedure TOXCUniversalJoint.SetJointMaxAngle0(val: cfloat);
begin
  if val<>FJointMaxAngle0 then begin
    FJointMaxAngle0:=val;
    FMaxAngle0:=FJointMaxAngle0*oxPIdiv180;
  end;
end;
{******************************************************************************}
//  [v2.11 2009]: TOXCUniversalJoint SetJointMinAngle1
{******************************************************************************}
procedure TOXCUniversalJoint.SetJointMinAngle1(val: cfloat);
begin
  if val<>FJointMinAngle1 then begin
    FJointMinAngle1:=val;
    FMinAngle1:=FJointMinAngle1*oxPIdiv180;
  end;
end;
{******************************************************************************}
//  [v2.11 2009]: TOXCUniversalJoint SetJointMaxAngle1
{******************************************************************************}
procedure TOXCUniversalJoint.SetJointMaxAngle1(val: cfloat);
begin
  if val<>FJointMaxAngle1 then begin
    FJointMaxAngle1:=val;
    FMaxAngle1:=FJointMaxAngle1*oxPIdiv180;
  end;
end;
{******************************************************************************}
//  [v2.11 2009]: TOXCUniversalJoint CustomBothCreate
{******************************************************************************}
procedure TOXCUniversalJoint.CustomBothCreate(cBody,pBody: PNewtonBody; cPivot,cPin,pPivot,pPin: TOXVector3);
var
  matrix0: TOXMatrix;
  matrix1: TOXMatrix;
  matrixInvert: TOXMatrix;
  pinAndPivotMatrix: TOXMatrix;
begin
  FBody0:=cBody;FBody1:=pBody;
  // Get the global matrices of each rigid body.
  NewtonBodyGetMatrix(cBody,@matrix0[0,0]);
  matrix1:=oxIdentityM;
  if pBody<>nil then
    NewtonBodyGetMatrix(pBody,@Matrix1[0,0]);
  // create a global matrix at the pivot point with front vector aligned to the pin vector
  oxMSetColumn(pinAndPivotMatrix,0,
  oxVScale(oxV4Make(cPin),1.0/sqrt(oxVDotProduct(cPin,cPin))));
  oxMSetColumn(pinAndPivotMatrix,2,
  oxV4Make(oxVCrossProduct(cPin,pPin)));
  oxMSetColumn(pinAndPivotMatrix,2,
  oxVScale(pinAndPivotMatrix[2],1.0/sqrt(oxVDotProduct(pinAndPivotMatrix[2],pinAndPivotMatrix[2]))));
  oxMSetColumn(pinAndPivotMatrix,1,
  oxVCrossProduct(pinAndPivotMatrix[2],pinAndPivotMatrix[0]));
  oxMSetColumn(pinAndPivotMatrix,3,
  oxV4Make(cPivot[0],cPivot[1],cPivot[2],1));
  // calculate the relative matrix of the pin and pivot on each body
  MatrixInvert:=Matrix0;
  oxInvertM(MatrixInvert);
  FcLocalMatrix0:=oxMMultiply(pinAndPivotMatrix,MatrixInvert);
  MatrixInvert:=Matrix1;
  oxInvertM(MatrixInvert);
  FcLocalMatrix1:=oxMMultiply(pinAndPivotMatrix,MatrixInvert);
  LocalMatrix0:=FcLocalMatrix0;
  LocalMatrix1:=FcLocalMatrix1;
  FMinAngle0:=JointMinAngle0*oxPIdiv180;
  FMaxAngle0:=JointMaxAngle0*oxPIdiv180;
  FMinAngle1:=JointMinAngle1*oxPIdiv180;
  FMaxAngle1:=JointMaxAngle1*oxPIdiv180;
end;

{******************************************************************************}
// [v2.11 2009]: TOXCUniversalJoint SubmitConstrainst
{******************************************************************************}
procedure TOXCUniversalJoint.SubmitConstrainst(userJoint: PNewtonJoint; timestep: cfloat; threadIndex: cInt);
var
  p0: TOXVector4;
  p1: TOXVector4;
  q0: TOXVector4;
  q1: TOXVector4;
  dir0: TOXVector4;
  dir1: TOXVector4;
  dir2: TOXVector4;
  dir3: TOXVector4;
  angle: cfloat;
  omega0: TOXVector4;
  omega1: TOXVector4;
  relOmega: cfloat;
  relAccel: cfloat;
  relAngle: cfloat;
  sinAngle: cfloat;
  cosAngle: cfloat;
  matrix0: TOXMatrix;
  matrix1: TOXMatrix;
begin
    // calculate the position of the pivot point and the Jacobian direction vectors, in global space.
    CalculateGlobalMatrix(LocalMatrix0,LocalMatrix1,matrix0,matrix1);
    // get the pin fixed to the first body
    dir0:=Matrix0[0];
    // get the pin fixed to the second body
    dir1:=Matrix1[1];
    // construct an orthogonal coordinate system with these two vectors
    dir2:=oxVCrossProduct(dir0,dir1);
    dir2:=oxVScale(dir2,1.0/sqrt(oxVDotProduct(dir2,dir2)));
    dir3:=oxVCrossProduct(dir2,dir0);
    //dir3:=oxVScale(dir3,1.0/sqrt(oxVDotProduct(dir3,dir3)));
    p0:=Matrix0[3];
    p1:=Matrix1[3];
    q0:=oxVAdd(p0,oxVScale(dir3,JointPinLength));
    q1:=oxVAdd(p1,oxVScale(dir1,JointPinLength));
    AddLinearRow(@p0[0],@p1[0],@dir0[0]);
    SetRowStiffness(1);
    AddLinearRow(@p0[0],@p1[0],@dir1[0]);
    SetRowStiffness(1);
    AddLinearRow(@p0[0],@p1[0],@dir2[0]);
    SetRowStiffness(1);
    AddLinearRow(@q0[0],@q1[0],@dir0[0]);
    SetRowStiffness(1);
    // if limit are enable ...
    if (JointLimitOn0) then begin
      sinAngle:=oxVDotProduct(oxVCrossProduct(Matrix0[1],Matrix1[1]),Matrix0[0]);
      cosAngle:=oxVDotProduct(Matrix0[1],Matrix1[1]);
      angle:=ArcTan2(sinAngle,cosAngle);
      if (angle<IntMinAngle0) then begin
        relAngle:=angle-IntMinAngle0;
        // tell joint error will minimize the exceeded angle error
        AddAngularRow(relAngle,@matrix0[0,0]);
        // need high stiffeners here
        SetRowStiffness(1);
        // allow the joint to move back freely
        SetRowMaximumFriction(0.0);
     end else
     if (angle>IntMaxAngle0) then begin
       relAngle:=angle-IntMaxAngle0;
       // tell joint error will minimize the exceeded angle error
       AddAngularRow(relAngle,@matrix0[0,0]);
       // need high stiffness here
       SetRowStiffness(1);
       // allow the joint to move back freely
       SetRowMinimumFriction(0.0); 
     end;
     end else begin
       if (JointAngularmotorOn0) then begin
         omega0:=oxV4Make(0.0,0.0,0.0);
         omega1:=oxV4Make(0.0,0.0,0.0);
         // get relative angular velocity
         if Body0<>nil then
           NewtonBodyGetOmega(body0,@omega0[0]);
         if Body1<>nil then
           NewtonBodyGetOmega(body1,@omega1[0]);
         // calculate the desired acceleration
         relOmega:=oxVDotProduct(oxVSubtract(omega0,omega1),Matrix0[0]);
         relAccel:=JointAngularAccel0-JointAngularDamp0*relOmega;
         // add and angular constraint row to that will set the relative acceleration to zero
         AddAngularRow(0.0,@matrix0[0,0]);
         // override the joint acceleration.
         SetRowAcceleration(relAccel);
       end;
     end;
     // check is the joint limit are enable
     if (JointLimitOn1) then begin
       sinAngle:=oxVDotProduct(oxVCrossProduct(Matrix0[0],Matrix1[0]),Matrix1[1]);
       cosAngle:=oxVDotProduct(Matrix0[0],Matrix1[0]);
       angle:=ArcTan2(sinAngle,cosAngle);
       if (angle<IntMinAngle1) then begin
         relAngle:=angle-IntMinAngle1;
         // tell joint error will minimize the exceeded angle error
         AddAngularRow(relAngle,@matrix1[1,0]);
         // need high stiffeners here
         SetRowStiffness(1);
         // allow the joint to move back freely
    SetRowMaximumFriction(0.0);
       end else
       if (angle>IntMaxAngle1) then begin
         relAngle:=angle-IntMaxAngle1;
         // tell joint error will minimize the exceeded angle error
         AddAngularRow(relAngle,@matrix1[1,0]);
         // need high stiffness here
         SetRowStiffness(1);
         // allow the joint to move back freely
         SetRowMinimumFriction(0.0);
       end;
       // check is the joint limit motor is enable
       end else begin
         if (JointAngularmotorOn1) then begin
           omega0:=oxV4Make(0.0,0.0,0.0);
           omega1:=oxV4Make(0.0,0.0,0.0);
           // get relative angular velocity
           if Body0<>nil then
             NewtonBodyGetOmega(body0,@omega0[0]);
           if Body1<>nil then
             NewtonBodyGetOmega(body1,@omega1[0]);
           // calculate the desired acceleration
           relOmega:=oxVDotProduct(oxVSubtract(omega0,omega1),Matrix1[1]);
           relAccel:=JointAngularAccel1-JointAngularDamp1*relOmega;
           // add and angular constraint row to that will set the relative acceleration to zero
           AddAngularRow(0.0,@matrix1[1,0]);
           // override the joint acceleration.
           SetRowAcceleration(relAccel);
         end;
     end;
end;


You can use GetInfo too with custom joint.
Some personne prefered to work with radian value but for my part I prefered in degree it coming more simple in the utilisation.
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://orionx3d.sytes.net
https://www.facebook.com/dave.gravel1
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 801
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron