Advertisement

Vehicle Wheels Position

Started by January 14, 2016 12:22 PM
5 comments, last by Medo Mex 9 years ago

I'm trying to position the vehicle wheels correctly based on a model file that I have loaded

The model contains a list of meshes

model->mesh[0] = Vehicle chassis mesh

model->mesh[1] = Wheel 1 mesh

model->mesh[2] = Wheel 2 mesh

model->mesh[3] = Wheel 3 mesh

model->mesh[4] = Wheel 4 mesh

Each mesh has its own world matrix, so to get wheel 1 world matrix: mesh[1]->worldMatrix

To add a wheel I do the following:


vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, SuspensionRestLength, wheelRadius, VehicleTuning, isFrontWheel);

How do I calculate the connection point (connectionPointCS0) based on the wheel world matrix?

You need to create a relationship between the parent mesh (car) and it's children (wheels), also for the matrices. The child (wheel) matrices have to me multiplied by the parent (car) world matrix.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

@cozzie: I tried the following, but I don't see the wheels positioned correctly:


D3DXMATRIX MatWorld;

// Wheel 1
D3DXMatrixMultiply(&MatWorld, &_pModel->listMesh[1]->WorldMatrix, &chassisWorldMatrix);
btVector3 connectionPointCS0 = btVector3(MatWorld_41, MatWorld._42, MatWorld._43);
vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, SuspensionRestLength, wheelRadius, VehicleTuning, isFrontWheel);

?// Wheel 2
D3DXMatrixMultiply(&MatWorld, &_pModel->listMesh[2]->WorldMatrix, &chassisWorldMatrix);
connectionPointCS0 = btVector3(MatWorld_41, MatWorld._42, MatWorld._43);
vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, SuspensionRestLength, wheelRadius, VehicleTuning, isFrontWheel);

isFrontWheel = false;

?// Wheel 3
D3DXMatrixMultiply(&MatWorld, &_pModel->listMesh[3]->WorldMatrix, &chassisWorldMatrix);
connectionPointCS0 = btVector3(MatWorld_41, MatWorld._42, MatWorld._43);
vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, SuspensionRestLength, wheelRadius, VehicleTuning, isFrontWheel);


?// Wheel 4
D3DXMatrixMultiply(&MatWorld, &_pModel->listMesh[4]->WorldMatrix, &chassisWorldMatrix);
connectionPointCS0 = btVector3(MatWorld_41, MatWorld._42, MatWorld._43);
vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, SuspensionRestLength, wheelRadius, VehicleTuning, isFrontWheel);

I'm able to position the wheels and the vehicle can now move, but the wheels are rotating incorrectly during the vehicle movement, also the initial wheel rotation is incorrect.

See the following screenshot:

[attachment=30287:wheels rotation.png]

Any idea how can I make the wheels rotate correctly during the vehicle movement?

Make sure you apply rotations only to the child matrices, and then multiply by the parent.

Looking at the image you're rotating the wrong or too many axes, just rotating along the Z axis should do it

(assuming in the local origin system of the car model, the car's front and back are facing along the X axis (left and right).

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

i tried to reply that topic then i saw bullet tag and i just closed the page without leaving any reply, but now i see i will have to post it, you want to rotate wheels areound their own axis + around base model axis (chassis axis) ok then you will have to calculate center point of all models (all 4 wheels + chassis + other parts if exist) basically you go throu all models vertices add them up and divide by the amount additionally you calculate center point of every model.

now after calculating that you translate everything by -whole_model_center this will move all your vertices to lets say base position where you can rotate around geometrical center)

then you draw chassis using

translation_mat = matrix_from_point(vehicle_position);

chassis_mat = rotation mat * translation_mat;

then you draw each wheel

wheel_mat = wheel_rotation_around_its_own_axis;

wheel_drawing_mat = matrix_from_point(-wheel_centerpoint) * wheel_mat * matrix_from_point(wheel_centerpoint);

the reason for doing such is that you have first to rotate your wheel around 0,0,0 point ( or in other words around geometrical center of the wheel itself)

so you translate back to 0,0,0 point and multiply that mat by rotation mat then you multiple that again by translation mat to position it to the original position.

after that

you pass to shader wheel world matrix as: wheel_drawing_mat * vehicle(chassis)_world_mat

and draw the wheel

do that for every wheel.

the key idea is to set whole model center at 0,0,0 point

since im on old notebook i have only old code that prooves my idea ;]

[spoiler]

Drawing routine:

[spoiler]










			void __fastcall TFighterJet::Draw()
			{
back = vector_multiple(YPRangle.rf,-15.0f);
up = vector_multiple(YPRangle.ru,7.0f);
back = vectors_add(back, up);
//
//						glColor3f(1,1,1);
//						
//glEnable( GL_VERTEX_PROGRAM_ARB );
//VertexLighting_ID.Bind();

//helperLight->SET_UP_LIGHT(0, t3dpoint<float>(1000,50,0),t3dpoint<float>(1,0,0),t3dpoint<float>(0,0,1) );
//
//glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 8, float(YPRangle.AIR_MATRIX[0]), float(YPRangle.AIR_MATRIX[1]), float(YPRangle.AIR_MATRIX[2]), float(YPRangle.AIR_MATRIX[3]));
//glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 9, float(YPRangle.AIR_MATRIX[4]), float(YPRangle.AIR_MATRIX[5]), float(YPRangle.AIR_MATRIX[6]), float(YPRangle.AIR_MATRIX[7]));
//glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 10, float(YPRangle.AIR_MATRIX[8]), float(YPRangle.AIR_MATRIX[9]), float(YPRangle.AIR_MATRIX[10]), float(YPRangle.AIR_MATRIX[11]));
//glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 11, float(YPRangle.AIR_MATRIX[12]), float(YPRangle.AIR_MATRIX[13]), float(YPRangle.AIR_MATRIX[14]), float(YPRangle.AIR_MATRIX[15]));


// if (tpp == false)
// {
//  if (FPP_CAM != NULL) FPP_CAM->SetView();
// } 
//else
//CAMERA->DrawSet_Camera_View();



WORLD_MAT.LoadIdentity();
WORLD_MAT.TranslateP(pos);

SetShaderMatrix(WORLD_MAT, ACTUAL_VIEW, ACTUAL_PROJECTION);




WORLD_MAT.LoadIdentity();


WORLD_MAT.LoadGLMatrix(YPRangle.AIR_MATRIX);
	   tmp.LoadIdentity();
	   tmp.TranslateP(pos);
WORLD_MAT = WORLD_MAT * tmp;

SetShaderMatrix(WORLD_MAT, ACTUAL_VIEW, ACTUAL_PROJECTION);







SendParamToShader(1.0,0.0,0.0, 1.0,  5);
			FUSELAGE->model->DrawSimpleModel();
			WING_LEFT->model->DrawSimpleModel();
			WING_RIGHT->model->DrawSimpleModel();
			TAIL_LEFT->model->DrawSimpleModel();
			TAIL_RIGHT->model->DrawSimpleModel();

//==============================================================================Draw AILERON LEFT

tmp2.LoadIdentity();

tmp2.RotateX(  		AILERON_LEFT->pitcha * imopi  		);

tmp2 = ReturnTranslateMatP(-AILERON_LEFT->model->CENTER_POINT)
* tmp2 *
ReturnTranslateMatP(AILERON_LEFT->model->CENTER_POINT);

SetShaderMatrix(tmp2*WORLD_MAT, ACTUAL_VIEW, ACTUAL_PROJECTION);

AILERON_LEFT->model->DrawSimpleModel();

//==============================================================================Draw AILERON RIGHT

tmp2.LoadIdentity();

tmp2.RotateX(  		AILERON_RIGHT->pitcha * imopi  		);

tmp2 = ReturnTranslateMatP(-AILERON_RIGHT->model->CENTER_POINT)
* tmp2 *
ReturnTranslateMatP(AILERON_RIGHT->model->CENTER_POINT);

SetShaderMatrix(tmp2*WORLD_MAT, ACTUAL_VIEW, ACTUAL_PROJECTION);

AILERON_RIGHT->model->DrawSimpleModel();


//==============================================================================Draw ELEVATOR RIGHT

tmp2.LoadIdentity();

tmp2.RotateX(  		ELEVATOR_RIGHT->pitcha * imopi  		);

tmp2 = ReturnTranslateMatP(-ELEVATOR_RIGHT->model->CENTER_POINT)
* tmp2 *
ReturnTranslateMatP(ELEVATOR_RIGHT->model->CENTER_POINT);


SetShaderMatrix(tmp2*WORLD_MAT, ACTUAL_VIEW, ACTUAL_PROJECTION);

ELEVATOR_RIGHT->model->DrawSimpleModel();

//==============================================================================Draw ELEVATOR LEFT

tmp2.LoadIdentity();

tmp2.RotateX(  		ELEVATOR_LEFT->pitcha * imopi  		);

tmp2 = ReturnTranslateMatP(-ELEVATOR_LEFT->model->CENTER_POINT)
* tmp2 *
ReturnTranslateMatP(ELEVATOR_LEFT->model->CENTER_POINT);


SetShaderMatrix(tmp2*WORLD_MAT, ACTUAL_VIEW, ACTUAL_PROJECTION);

ELEVATOR_LEFT->model->DrawSimpleModel();

//==============================================================================Draw RUDDER LEFT

tmp2.LoadIdentity();

tmp2.RotateY(  		RUDDER_LEFT->pitcha * imopi  		);

tmp2 = ReturnTranslateMatP(-RUDDER_LEFT->model->CENTER_POINT)
* tmp2 *
ReturnTranslateMatP(RUDDER_LEFT->model->CENTER_POINT);

SetShaderMatrix(tmp2*WORLD_MAT, ACTUAL_VIEW, ACTUAL_PROJECTION);

RUDDER_LEFT->model->DrawSimpleModel();


//==============================================================================Draw RUDDER RIGHT


tmp2.LoadIdentity();

tmp2.RotateY(  		RUDDER_RIGHT->pitcha * imopi  		);

tmp2 = ReturnTranslateMatP(-RUDDER_RIGHT->model->CENTER_POINT)
* tmp2 *
ReturnTranslateMatP(RUDDER_RIGHT->model->CENTER_POINT);

SetShaderMatrix(tmp2*WORLD_MAT, ACTUAL_VIEW, ACTUAL_PROJECTION);

RUDDER_RIGHT->model->DrawSimpleModel();


//glDisable( GL_VERTEX_PROGRAM_ARB );

                ACTUAL_MODEL.LoadIdentity();
SetShaderMatrix(ACTUAL_MODEL, ACTUAL_VIEW, ACTUAL_PROJECTION);






[/spoiler]

Positioning models.

[spoiler]











	 double x,y,z;
		model = new TachoGLModel<double>();
		model->LoadModel(k+cfg->getValue("BASE_MODEL"));

model->CalcCenterPoint();

x = model->CENTER_POINT.x;
y = model->CENTER_POINT.y;
z = model->CENTER_POINT.z;

model->MoveToGeometricCenter();

model->CalcCenterPoint();


model->ForceCalculateNormals();
model->ReverseNormals();

model->CalculateMinMax();
double modelspan;
double modellen;
double modelheight;

modelspan = absnf(model->MAX.x-model->MIN.x);
modellen = absnf(model->MAX.z-model->MIN.z);
modelheight = absnf(model->MAX.y-model->MIN.y);

double spanfactor = span / modelspan;   //spanfactor = 1.0 / spanfactor;

double lenfactor = length / modellen;//   lenfactor  = 1.0 / lenfactor;

double hfactor = heightm / modelheight;  // hfactor  = 1.0 / hfactor;

model->Scale(spanfactor, hfactor, lenfactor);
model->CalcCenterPoint();
//model->MoveToGeometricCenter();
model->CalculateMinMax();






//===================scale all moving parts==============================
   //ALOG("scale and move movable model");
ScaleAndMoveMovableModel(ELEVATOR_LEFT->model,spanfactor, hfactor, lenfactor,x,y,z);
ScaleAndMoveMovableModel(ELEVATOR_RIGHT->model,spanfactor, hfactor, lenfactor,x,y,z);

ScaleAndMoveMovableModel(AILERON_RIGHT->model,spanfactor, hfactor, lenfactor,x,y,z);
ScaleAndMoveMovableModel(AILERON_LEFT->model,spanfactor, hfactor, lenfactor,x,y,z);

ScaleAndMoveMovableModel(FLAP_RIGHT->model,spanfactor, hfactor, lenfactor,x,y,z);
ScaleAndMoveMovableModel(FLAP_LEFT->model,spanfactor, hfactor, lenfactor,x,y,z);

ScaleAndMoveMovableModel(WING_RIGHT->model,spanfactor, hfactor, lenfactor,x,y,z);
ScaleAndMoveMovableModel(WING_LEFT->model,spanfactor, hfactor, lenfactor,x,y,z);






----------------------------------------------------------------

 void __fastcall ScaleAndMoveMovableModel(T spanfactor, T hfactor, T lenfactor, T tx, T ty, T tz)
{
T x,y,z;

Translate(-tx,-ty,-tz);

CalcCenterPoint();

MoveToGeometricCenter();

Scale(spanfactor, hfactor, lenfactor);

Translate(CENTER_POINT.x,CENTER_POINT.y,CENTER_POINT.z);

x = CENTER_POINT.x * spanfactor;
y = CENTER_POINT.y * hfactor;
z = CENTER_POINT.z * lenfactor;

CalcCenterPoint();

TranslateToPoint(triplesingletoT3DPOINT(x,y,z));

CalcCenterPoint();
}



[/spoiler]

[/spoiler]

that may not be visible but elevators are rotated:

2t.png

or a topkek vid

Advertisement

Right now, I'm able to setup the vehicle and get it to work, but one problem exists

I have a convex hull shape (chassis), If I set the wheels a little far from the chassis it works, but if I adjust the wheels to the right position (wheels colliding with the chassis) I get big performance issue (frame rate drop dramatically) and the vehicle turn upside down.

This topic is closed to new replies.

Advertisement