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](https://sites.google.com/site/customprog/home/2t.png)
or a topkek vid