CustomMultiBodyVehicle joint - How to use it ?

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Tue Oct 14, 2008 7:33 pm

Since the CustomMultiBodyVehicle joint is new in the 2.0, there isn't any doc or sample on how to use it. I'm trying to build a car with Newton in DirectX, but it's kind of working by trials and errors. The major thing I need to know is:

In the Transform callback of the car body, if I get the tires body and then their matrix, what is it supposed to be ?

- Does it includes the transformation of the parent car ?
- Is it the offset matrix of the tire to the vehicle's body ?
- Does it include the rotation matrix of the steering ?

Please help me on these things cuz I really can't get them working.
If someone coulg give me a short example of how to use it, that would be nice too.

Thanks in advance,
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby Julio Jerez » Wed Oct 15, 2008 10:04 am

I beileve the answere is yes to all.
Julio Jerez
Moderator
Moderator
 
Posts: 11154
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Thu Oct 16, 2008 4:23 pm

I'm continuing to work on my implementation of the CustomMultiBodyVehicle (since two weeks now) and I haven't got it to work.

I realized that the tires did not seem to be added correctly because the vehicle main body did fall on the ground without stopping (on eventual tires) and the tires were rendered inside the body of the vehicle. WTF !?!

Also, the tire transform callback never gets called (I suppose that's what my tires get rendered inside the vehicle and not correctly with the tire invisible "rigid body".

If anyone can help me, please.
I've been trying so hard to get this thing working and it doesn't.

However, here's the code :

(for car and tire class definitions)
Code: Select all
class Car
{
public:
   Car(LPDIRECT3DDEVICE9 _pDevice);
   virtual ~Car();

   virtual bool Initialize(NewtonWorld* _pWorld, const D3DVECTOR& _pos);
   virtual void Render();
   virtual void SetColor(const D3DCOLORVALUE& _color);
private:
   class Tire : public VisualObject
   {
   public:
      Tire(LPDIRECT3DDEVICE9 _pDevice);
      virtual ~Tire();

      void Setup(CustomJoint* _vehicle, const D3DVECTOR& _position, int _tireID);
   private:
      static void SetTireForceAndTorqueCallback (const NewtonBody* _pBody, const dFloat _timestep, const int _threadIndex);
      static void SetTireTransformCallback(const NewtonBody* _pBody, const float* _pMatrix, int _threadIndex);
   protected:
      int tireID;
   };
   static void SetCarForceAndTorqueCallback (const NewtonBody* _pBody, const dFloat _timestep, const int _threadIndex);
   static void SetCarTransformCallback(const NewtonBody* _pBody, const float* _pMatrix, const int _threadIndex);

   VisualBox mainBox;
   CustomJoint* pVehicleJoint;
   NewtonBody* pVehicleBody;
   Tire frontLeftTire, frontRightTire, rearLeftTire, rearRightTire;
};


(for creating the vehicle) :
Code: Select all
bool Car::Initialize(NewtonWorld* _pWorld, const D3DVECTOR& _pos)
{
   D3DXVECTOR3 pos = _pos;
   // Height of the center of the car. Elevate it a little so it's gonna be just above the position we want.
   pos.y += 1;
   // Create a DirectX box (the car's box body).
   mainBox.Initialize(pos, 2.0f, 0.5f, 1.0f);

   // Create the hull (here a big stupid bounding box).
   NewtonCollision* collision = NULL;
   collision = NewtonCreateBox(_pWorld, 2.0f, 0.5f, 1.0f, NULL);

   // Create the physics rigid body that has the collision hull.
   pVehicleBody = NewtonCreateBody(_pWorld, collision);

   //NewtonBodySetAutoSleep(pVehicleBody, FALSE);
   NewtonBodySetUserData(pVehicleBody, &mainBox);
   NewtonBodySetTransformCallback(pVehicleBody, SetCarTransformCallback);
   NewtonBodySetForceAndTorqueCallback(pVehicleBody, SetCarForceAndTorqueCallback);

   D3DVECTOR inertia;
   D3DVECTOR origin;

   // Calculate the moment of inertia and the center of mass of this collision object.
   NewtonConvexCollisionCalculateInertialMatrix(collision, &inertia.x, &origin.x);

   float ixx = VEHICLE_MASS * inertia.x;
   float iyy = VEHICLE_MASS * inertia.y;
   float izz = VEHICLE_MASS * inertia.z;

   // Set the mass of this rigid body.
   NewtonBodySetMassMatrix(pVehicleBody, VEHICLE_MASS, ixx, iyy, izz);

   origin.y *= 0.5f;
   NewtonBodySetCentreOfMass (pVehicleBody, &origin.x);

   // Set the placement matrix for the rigid body.
   D3DXMATRIX mat;
   D3DXMatrixTranslation(&mat, pos.x, pos.y, pos.z);
   NewtonBodySetMatrix(pVehicleBody, (dFloat*)&mat.m);

   NewtonReleaseCollision(_pWorld, collision);

   D3DVECTOR front = { 1, 0, 0 };
   D3DVECTOR up = { 0, 1, 0 };
   pVehicleJoint = CreateCustomMultiBodyVehicle(&front.x, &up.x, pVehicleBody);

   D3DVECTOR lfOff = { 0.6f, -0.1f, -0.8f };
   D3DVECTOR rfOff = { 0.6f, -0.1f, 0.8f };
   D3DVECTOR lrOff = { -0.6f, -0.1f, -0.8f };
   D3DVECTOR rrOff = { -0.6f, -0.1f, 0.8f };

   D3DCOLORVALUE color = { 0.1f, 0.1f, 0.1f, 0.9f };
   // Create the tires.
   frontLeftTire.Setup(pVehicleJoint, lfOff, 0);
   frontRightTire.Setup(pVehicleJoint, rfOff, 1);
   rearLeftTire.Setup(pVehicleJoint, lrOff, 2);
   rearRightTire.Setup(pVehicleJoint, rrOff, 3);

   frontLeftTire.SetColor(color);
   frontRightTire.SetColor(color);
   rearLeftTire.SetColor(color);
   rearRightTire.SetColor(color);

   return true;
}


(for setting the tire) :
Code: Select all
void Car::Tire::Setup(CustomJoint* _vehicle, const D3DVECTOR& _position, int _tireID)
{
   tireID = _tireID;

   // Create a cylinder (tire).
   D3DXCreateCylinder(pDevice, 0.5f, 0.5f, 0.5f, 30, 30, &pMesh, NULL);

   CustomMultiBodyVehicleAddTire(_vehicle, this, &_position.x, 5, 0.5f, 0.5f, 0.1f, 0.1f, 0.1f);

   const NewtonBody* pTireBody = CustomMultiBodyVehicleGetTireBody(_vehicle, tireID);

        // This callback never gets called.
   NewtonBodySetTransformCallback(pTireBody, SetTireTransformCallback);
   NewtonBodySetForceAndTorqueCallback(pTireBody, SetTireForceAndTorqueCallback);
}


Thanks for those who are gonna take a little time to take a look at my problem.
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby Dave Gravel » Thu Oct 16, 2008 10:27 pm

It's hard to say what is the problem, without debuging the code directly.

Here it's a quick implementation that I have make to use the newton dll joint vehicle multibody.
It is write with delphi and it derived from my engine object system,
No idea if it can help you but normally the vehicle and newton part's setup is similar.

This default code working very nice, but it is totally unfinished and the code is not clean it is again in construction but working already.
All multibody vehicle demo's that I have post on the newton forum use this vehicle...

http://evadlevarg.googlepages.com/oxNew ... cledll.pas

Here it's my dll import because I can't use it like you use it from the c++
It can help you to find my this section in my code.
Code: Select all
function  oxCreateMultiBodyVehicleJoint(CJoint: POXMultibodyVehicleJoint; const frontDir: PDFloat; const upDir: PDFloat; const carBody: PNewtonBody): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleAddTire(CJoint: POXMultibodyVehicleJoint; const userData: pointer; const localPosition: PDFloat; mass: dFloat; radius: dFloat; width: dFloat; suspensionLength: dFloat; springConst: dFloat; springDamper: dFloat): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleAddSlipDifferencial(CJoint: POXMultibodyVehicleJoint; leftTireIndex: int; rightToreIndex: int; maxFriction: dFloat): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleGetTiresCount(CJoint: POXMultibodyVehicleJoint): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleGetTireBody(CJoint: POXMultibodyVehicleJoint; tireIndex: int): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleGetSpeed(CJoint: POXMultibodyVehicleJoint): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleGetTireSteerAngle(CJoint: POXMultibodyVehicleJoint; index: int): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleApplyTorque(CJoint: POXMultibodyVehicleJoint; tireIndex: int; torque: dFloat): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleApplySteering(CJoint: POXMultibodyVehicleJoint; tireIndex: int; angle: dFloat): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleApplyBrake(CJoint: POXMultibodyVehicleJoint; tireIndex: int; brakeTorque: dFloat): POXMultibodyVehicleJoint;

function  oxMultiBodyVehicleApplyTireRollingDrag(CJoint: POXMultibodyVehicleJoint; tireIndex: int; angularDampingCoef: dFloat): POXMultibodyVehicleJoint;

function  oxDestroyMultiBodyVehicle(CJoint: POXMultibodyVehicleJoint): POXMultibodyVehicleJoint;


Good luck and sorry to can't help more.
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://www.facebook.com/dave.gravel1
http://orionx3d.googlepages.com/
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 725
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Fri Oct 17, 2008 12:34 am

I Understand. I know it's hard to help on the fly with just a chunk of the code.

Anyway, I've looked at your code and I saw that you set a Transform Callback for each of the tires ... But I can't find the definition of this method in the file but I want to know, how does your callback gets called ? I know it may seem really newbie, but my transform callback for the body gets called, while those for the tires are never called. Why ? Also, I want to know what are you supposed to do exactly in this callback ? Receive the new matrix for the tire body and set it directly to the tire visual ? Is the matrix global or is it relative to the parent ? Does it applies rotations for steering and torque (I hope so...) ?

Thanks.
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby Dave Gravel » Fri Oct 17, 2008 2:22 am

About the transform callback it is the same callback that I use with all objects type in newton.
Code: Select all
procedure oxPSetTransform(const Body: PNewtonBody; const Matrix: PDFloat; threadIndex: int); cdecl;
var
  m: TMatrix;
  obj: TOXNewtonDynBaseObject;
begin
  obj:=TOXNewtonDynBaseObject(NewtonBodyGetUserData(Body));
  m:=PMatrix(Matrix)^;
  oxSetNewtonTransform(obj,m);
end;
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://www.facebook.com/dave.gravel1
http://orionx3d.googlepages.com/
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 725
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Fri Oct 17, 2008 1:06 pm

Always the same problem : I just don't know where my tires are and their transform callback NEVER gets called, while the one of the vehicle body does get called.
I've tried so much things, and nothing worked. (except normal collisions).


I can't believe anybody here hasn't done something similar in C++. Please may this person send me a working example or can I have at least a small tutorial (at the very BASICS) of how to do it ? There must be some. Someone must have done it somewhere.
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Fri Oct 17, 2008 2:25 pm

Now I have tried to set the matrix of the tires in the vehicle's body callback. To set the matrix of the tire visual mesh, I use NewtonBodyGetMatrix on the tire body to get it. When checking the value of the 13 element of the matrix in the debug (I think this element should be the position in x), its value is -1,07e+008 which is way too big. From this I can conclude that my tires are just out of the map. But why are they there ? This I can't figure out.
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Fri Oct 17, 2008 2:55 pm

Knowing not what do try else, I decided to set a matrix for the tires (which I'm not supposed to, according to the so few examples I saw). And BANG ! The transform callback for the tires did get called ! But it was throwing exceptions each time and the vehicle nor the tires were visible. After looking in the debug, I saw the exceptions were thrown because all the floats in the matrix where at value -1.#IND, which means NaN - not a number, an invalid value. But why does it give that result ?
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby Dave Gravel » Fri Oct 17, 2008 9:58 pm

Maybe this code can help you better.
I have wait the ok from the creator before post it.

http://evadlevarg.googlepages.com/tutor ... ehicle.zip

This code is a demo test made by Julio in a old newton beta.
My code is based on this demo a lot.
The code is good to use, but remember you the vehicle multibody can come implemented differently and it is totally customizable.
This code demo is working but it is unfinished, you can surely find a better version in the futur with newer newton version.
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://www.facebook.com/dave.gravel1
http://orionx3d.googlepages.com/
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 725
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Sat Oct 18, 2008 10:27 am

Thanks for the sample. Although I need to adapt it a bit to Newton 1.6, hope is there.

However, where does the call PhysicsSetTransform() in the SetTransform() callback of the car is defined. I don't find it.

Also, I'm using Visual Studio 2005 and DirectX 9, and no I can't change my tools. I don't have the choice. That's imposed by our teacher.
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Sat Oct 18, 2008 11:59 am

I've assumed that PhysicsSetTransform() just sets the matrix of the visual body and nothing else. Hope I'm right.

I've managed to make my own class Car that looks like MultiBodyCar (with the inheritance, and so on). But I don't know how to set the matrix to initialize it in CreateBasicCar(). I've tried putting all zeros (w = 1 for all vectors) but that doesn't work.

Could you give me an example of how to set the matrix for the vehicle to be initially placed in (x = 0, y = 2, z = 0) ?

Thanks
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Sat Oct 18, 2008 12:03 pm

Could there be an interference because DirectX uses left-handed matrices and all other things use the right-handed ones ? (just wondering, maybe ... )
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Sun Oct 19, 2008 1:47 pm

It worked !!! A great thanks to k00m !!

The driving needs some tweaking, but it's not that bad, at least it works !
So when the car will be driving ok, I'll clean up the code, and I'll post the source on my website for those who are interested. As I think this is the only example I found which uses DirectX 9 and Newton, it will surely help someone and/or avoid him a lot of frustrating hours. I also feel that it has worked because of the great Newton community support, so it's normal to give some back.

My website : frankdevelopper.com
Since it's a school project, I have a short time to finish it so it souldn't be long before it goes online.

Thanks again for helping me !
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Re: CustomMultiBodyVehicle joint - How to use it ?

Postby frankk » Sun Oct 19, 2008 2:53 pm

Hello, I have located the bug in the driving of the car that makes drive ugly and I don't know what it is. I'm sure you'll find out quikly. In the car transform callback, the matrices of my tires (obtained via NewtonBodyGetMatrix()) rotate my tires by 90 degrees in addition to place them correctly in the world, So it gives strange behaviors.

For example :
If I apply torque to the back wheels without steering, that's fine, the car moves or slows and goes back without problem.
If I steer, without applying torque (but I have already applied one before, so the car has a speed), the car turns just fine. Realistic.

But if I steer the front wheels while applying torque to the back wheels, the force applied to the car seems to be in the same direction as the car turns, which result is that the back of the car turns faster than the front, and it gives a spin in the inverse way I was steering. Instead the force should be in the opposite way from which I steer, so the back of the car would help the whole car turn. That would be realistic.

Hope I'm clear.
And I have a feeling that I'm missing something obvious and the solution is simple.
Thanks.
frankk
 
Posts: 32
Joined: Thu Oct 09, 2008 2:40 pm
Location: Quebec, Canada

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest