A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by 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?
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by 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
by 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.
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Julio Jerez » Tue Dec 01, 2009 3:13 pm
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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.
-

Dave Gravel
-
- Posts: 801
- Joined: Sat Apr 01, 2006 9:31 pm
- Location: Quebec in Canada.
-
by 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
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by 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.
-

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