home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / Mech.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-01-22  |  18.9 KB  |  657 lines

  1. #include "Mech.h"
  2.  
  3. #include "Game.h"
  4. #include "Renderer.h"
  5. #include "log.h"
  6.  
  7. #include <math.h>
  8. #include "matrixmath.h"
  9.  
  10. #define MECH_GROUND_CONTACT_STABLE    0.8f
  11.  
  12.  
  13. Mech::Mech(Client* client): Vehicle(client){
  14.     groundContact = false;
  15.     jumpjetsActive = false;
  16.     jumpjetsEnergyConsumption = 20.0f;
  17.  
  18.     torsoModel = NULL;
  19.     torsoAnimator = NULL;
  20.     legsModel = NULL;
  21.     legsAnimator = NULL;
  22.  
  23.     dlpcs.clear();
  24.     legsModelSecondaryColors = NULL;
  25.     torsoModelSecondaryColors = NULL;
  26.     for(int i=0;i<4;i++){
  27.         weaponModelSecondaryColors[i] = NULL;
  28.     }
  29. }
  30.  
  31. Mech::~Mech(){
  32.     int i, j;
  33.  
  34.     if( legsModelSecondaryColors != NULL ){
  35.         for(i=0;i<legsModel->numMeshes;i++){
  36.             delete[] legsModelSecondaryColors[i];
  37.         }
  38.         delete[] legsModelSecondaryColors;
  39.     }
  40.     if( torsoModelSecondaryColors != NULL ){
  41.         for(i=0;i<torsoModel->numMeshes;i++){
  42.             delete[] torsoModelSecondaryColors[i];
  43.         }
  44.         delete[] torsoModelSecondaryColors;
  45.     }
  46.     for(i=0;i<4;i++){
  47.         if( weaponModelSecondaryColors[i] != NULL ){
  48.             for(j=0;j<weapons[i]->model->numMeshes;j++){
  49.                 delete[] weaponModelSecondaryColors[i][j];
  50.             }
  51.             delete[] weaponModelSecondaryColors[i];
  52.         }
  53.     }
  54.  
  55. //    if( torsoModel != NULL )
  56. //        delete torsoModel;
  57.     if( torsoAnimator != NULL )
  58.         delete torsoAnimator;
  59. //    if( legsModel != NULL )
  60. //        delete legsModel;
  61.     if( legsAnimator != NULL )
  62.         delete legsAnimator;
  63.  
  64.     for(unsigned int k=0;k<dlpcs.size();k++){
  65.         dlpcs[k].dlpc->vehicles.remove(this);
  66.  
  67.         if( legsModel != NULL ){
  68.             for(j=0;j<legsModel->numMeshes;j++){
  69.                 delete[] dlpcs[k].legsModel_colors[j];
  70.             }
  71.             delete[] dlpcs[k].legsModel_colors;
  72.         }
  73.  
  74.         if( torsoModel != NULL ){
  75.             for(j=0;j<torsoModel->numMeshes;j++){
  76.                 delete[] dlpcs[k].torsoModel_colors[j];
  77.             }
  78.             delete[] dlpcs[k].torsoModel_colors;
  79.         }
  80.     }
  81.     dlpcs.clear();
  82. }
  83.  
  84.  
  85. void Mech::moveForward(float deltaT){
  86.     vec3_t tmp;
  87.     vectorInit3d((float)(cos(yaw)), 0.0f, (float)(sin(yaw)), tmp);
  88.     vectorMA3d(vel_inp, deltaT*moveSpeed, tmp, vel_inp);
  89. }
  90. void Mech::moveBackward(float deltaT){
  91.     vec3_t tmp;
  92.     vectorInit3d((float)(cos(yaw)), 0.0f, (float)(sin(yaw)), tmp);
  93.     vectorMA3d(vel_inp, -deltaT*moveSpeed, tmp, vel_inp);
  94. }
  95. void Mech::moveLeft(float deltaT){
  96.     vec3_t tmp;
  97.     vectorInit3d((float)(cos(yaw-PI*0.5f)), 0.0f, (float)(sin(yaw-PI*0.5f)), tmp);
  98.     vectorMA3d(vel_inp, deltaT*moveSpeed, tmp, vel_inp);
  99. }
  100. void Mech::moveRight(float deltaT){
  101.     vec3_t tmp;
  102.     vectorInit3d((float)(cos(yaw-PI*0.5f)), 0.0f, (float)(sin(yaw-PI*0.5f)), tmp);
  103.     vectorMA3d(vel_inp, -deltaT*moveSpeed, tmp, vel_inp);
  104. }
  105. void Mech::moveUp(float deltaT){
  106.     vectorMA3d(vel_inp, deltaT*moveSpeed, e2, vel_inp);
  107. }
  108. void Mech::moveDown(float deltaT){
  109. //    vectorMA3d(vel_inp, -deltaT*moveSpeed, e2, vel_inp);
  110. }
  111.  
  112.  
  113.  
  114. void Mech::move(){
  115.     unsigned int currentMillis = SDL_GetTicks();
  116.     
  117.     if( lastMoveMillis >= currentMillis )    // sanity check
  118.         return;
  119.         
  120.     float deltaT = (currentMillis - lastMoveMillis)/1000.0f;
  121.     lastMoveMillis = currentMillis;
  122.  
  123.     reconstructVectors();    // make sure local COSystem is orthonormal
  124.     anglesFromVectors();
  125.  
  126.     // calc recovery
  127.     calcRecovery();
  128.  
  129.     // set animation
  130.     if( legsAnimator != NULL ){
  131.         if( vel_inp[0]*vel_inp[0] + vel_inp[2]*vel_inp[2] > 0.001f && vel_inp[1] <= 0.0f ){    // walking
  132.             vec3_t tmp;
  133.             vectorInit3d((float)(cos(yaw)), 0.0f, (float)(sin(yaw)), tmp);
  134.             if( vectorDotP3d(tmp, vel_inp) >= 0.0f ){    // walking forward
  135.                 legsAnimator->setPlayBackwards(false);
  136.             }else{    // walking backwards
  137.                 legsAnimator->setPlayBackwards(true);
  138.             }
  139.             legsAnimator->start();
  140.         }else{
  141.             legsAnimator->pause();
  142.         }
  143.     }
  144.  
  145.     // jumpjets
  146.     float energyCosts = deltaT * jumpjetsEnergyConsumption;
  147.     if( vel_inp[1] > 0.001f && energy-energyCosts > 0.0f){
  148.         jumpjetsActive = true;
  149.         energy -= energyCosts;
  150.     }else{
  151.         jumpjetsActive = false;
  152.     }
  153.  
  154.  
  155.     float groundContactRatio = calcGroundContactRatio();
  156.     groundContact = groundContactRatio > 0.0f;
  157.  
  158.     if( groundContactRatio > 1.0f ){    // stuck in ground -> add a slight upward movement to correct this
  159. //        vectorMA3d(vel, 20.0f*deltaT, e2, vel);
  160.         vec3_t correctingDisplacement;
  161.         vectorScale3d(0.01f, e2, correctingDisplacement);
  162.         if( collisionDetection(correctingDisplacement) ){        // check if move is save
  163.             vectorAdd3d(pos, correctingDisplacement, pos);    // ...and move
  164.         }
  165.     }
  166.  
  167.     // do physics
  168.     if( groundContactRatio > MECH_GROUND_CONTACT_STABLE && !jumpjetsActive ){    // standing stable
  169.  
  170.         vectorInit3d(0.0f, 0.0f, 0.0f, vel);    // to avoid problems with slow clients (∩┐╜erschwinger)
  171.         vectorCopy3d(vel, physicsInfo.v);
  172.         vectorInit3d(0.0f, 0.0f, 0.0f, physicsInfo.F_i);
  173.         //physicsInfo.r = 6000.0f;
  174.         physicsInfo.r = 0.0f;
  175.         physicsInfo.g = 0.0f;
  176.         physicsInfo.calcAcceleration();
  177.  
  178.         vectorMA3d(vel, moveSpeed, vel_inp, vel);
  179.         vectorMA3d(vel, deltaT, physicsInfo.a, vel);
  180. //    printf("vi: %f %f %f\n", vel_inp[0], vel_inp[1], vel_inp[2]);
  181. //    printf("v: %f %f %f\n", vel[0], vel[1], vel[2]);
  182.  
  183. //        printf("STANDING\n");
  184.     }else{ // falling, flying, standing on edge, ...
  185.  
  186.         vec3_t tmp;
  187.         vectorCopy3d(vel_inp, tmp);
  188.         if( jumpjetsActive ){
  189.             tmp[1] = 4.5f;
  190.         }else{
  191.             tmp[1] = -0.6f*Game::arena->gravity;
  192.         }
  193.         vectorScale3d(600.0f, tmp, physicsInfo.F_i);
  194.         vectorCopy3d(vel, physicsInfo.v);
  195.         physicsInfo.r = 50.0f;
  196.         physicsInfo.g = Game::arena->gravity;
  197.         physicsInfo.calcAcceleration();
  198.         vectorMA3d(vel, deltaT, physicsInfo.a, vel);
  199. //        printf("FALLING\n");
  200.     }
  201.     vec3_t tmp;
  202.     vectorInit3d(vel[0], 0.0f, vel[2], tmp);
  203.     if( vectorLength3d(tmp) > moveSpeed ){
  204.         vectorNormalize3d(tmp, tmp);
  205.         vectorScale3d(moveSpeed, tmp, tmp);
  206.         vel[0] = tmp[0];
  207.         vel[2] = tmp[2];
  208.     }
  209.  
  210.     vec3_t displacement;
  211.     vectorScale3d(deltaT, vel, displacement);
  212.  
  213.     if( collisionDetection(displacement) ){        // check if move is save
  214.         vectorAdd3d(pos, displacement, pos);    // ...and move
  215.     }
  216.  
  217.     vectorScale3d(1.0f/deltaT, displacement, vel);
  218. }
  219.  
  220.  
  221. float Mech::calcGroundContactRatio(){
  222.     vec3_t testPos, normal;
  223.     trace_t trace;
  224.     trace.ignoreFlags = 0 | COLLISION_FLAG_BACKFACES | COLLISION_FLAG_WALK_THROUGH;
  225.     float ret = -1.0f;
  226.  
  227.     AABB_t testAABB;
  228.     vectorInit3d(moveAABB.max[0], moveAABB.min[1]+0.15f, moveAABB.max[2], testAABB.max);
  229.     vectorInit3d(moveAABB.min[0], moveAABB.min[1], moveAABB.min[2], testAABB.min);
  230.  
  231.     // move into ground to check if we have ground contact
  232.     vectorMA3d(pos, -0.15f, e2, testPos);
  233.  
  234.     traceAABB(pos, testPos, testAABB, &trace);
  235.     for(unsigned int i=0;i<trace.hits.size();i++){
  236.         if( trace.hits[i].face != NULL ){
  237.             vectorCopy3d(trace.hits[i].face->normal, normal);
  238.         }
  239.  
  240.         if( trace.hits[i].vehicle != NULL ){    // hit a vehicle
  241.             if( trace.hits[i].vehicle == this )
  242.                 continue;
  243.  
  244.             vectorSub3d(this->pos, trace.hits[i].vehicle->pos, normal);
  245.             vectorNormalize3d(normal, normal);
  246.         }
  247.  
  248.         float dp = vectorDotP3d(normal, e2);
  249.         ret = dp > ret ? dp : ret;
  250.     }
  251.  
  252.     // check if we have TOO MUCH ground contact (i.e. stuck in ground)
  253.     if( ret > MECH_GROUND_CONTACT_STABLE ){
  254.         vectorMA3d(pos, -0.10f, e2, testPos);
  255.  
  256.         traceAABB(pos, testPos, testAABB, &trace);
  257.         if( trace.hits.size() > 1 ){    // do NOT count self as hit...
  258.             ret = 2.0f;
  259. //            printf("STUCK IN GROUND!\n");
  260.         }
  261.     }
  262.  
  263.     return ret;
  264. }
  265.  
  266.  
  267.  
  268.  
  269.  
  270. void Mech::addDynamicLightParticleCluster(DynamicLightParticleCluster* dlpc){
  271.     int i, j, k;
  272.     mech_dlpcCombo_t c;
  273.  
  274.     c.dlpc = dlpc;
  275.  
  276.     // LEGS
  277.     if( legsModel != NULL ){
  278.         int frame = (int)legsAnimator->getCurrentFrame();
  279. //        printf("frame: %i\n", frame);
  280.  
  281.         vec3_t tmp;
  282.         vectorInit3d((float)(cos(yaw)), 0.0f, (float)(sin(yaw)), tmp);
  283.         float m[] = {    left[0], left[1], left[2], 0.0f,
  284.                         e2[0], e2[1], e2[2], 0.0f,
  285.                         tmp[0], tmp[1], tmp[2], 0.0f,
  286.                         pos[0], pos[1], pos[2], 1.0f
  287.                     };
  288.  
  289.         float im[16];
  290.         float cm[16];
  291.         vec4_t transformedPos;
  292.  
  293.         c.legsModel_colors = new GLfloat*[legsModel->numMeshes];
  294.         for(i=0;i<legsModel->numMeshes;i++){
  295.             Mesh* mesh = legsModel->meshes[i];
  296.             c.legsModel_colors[i] = new GLfloat[mesh->numVertices*3];
  297.         
  298.             matrixMultMatrix(m, legsModel->matrices[frame][i], 4, cm);
  299.             matrixInvert(cm, 4, im);
  300.             vectorInit4d(dlpc->pos[0], dlpc->pos[1], dlpc->pos[2], 1.0f, transformedPos);
  301.             matrixMultVector(im, transformedPos, 4, transformedPos);
  302.             float transformedRadius = dlpc->radius;// * (float)(fabs(im[0]);
  303.     
  304.             for(j=0;j<mesh->numVertices;j++){
  305.                 float f = vectorPointDistance3d(transformedPos, &mesh->vertices[j*3]) / transformedRadius;
  306.                 if( f < 0.0f ){        // most likely matrix was not inverted correctly...
  307. //                    printf("LEGS: f: %f;  tr: %f\n", f, transformedRadius);
  308.                     f = 0.0f;
  309.                 }
  310.                 if( f > 1.0f ){
  311. //                    printf("LEGS: f: %f;  tr: %f\n", f, transformedRadius);
  312.                     f = 1.0f;
  313.                 }
  314.                 //f = f > 1.0f ? 1.0f : f;
  315.                 vectorScale3d(1.0f - f, dlpc->col, &c.legsModel_colors[i][j*3]);
  316.                 vectorAdd3d(&legsModelSecondaryColors[i][j*3], &c.legsModel_colors[i][j*3], &legsModelSecondaryColors[i][j*3]);
  317.             }
  318.         }
  319.     }
  320.  
  321.     // TORSO
  322.     if( torsoModel != NULL ){
  323.         int frame = 0;//(int)legsAnimator->getCurrentFrame();
  324. //        printf("frame: %i\n", frame);
  325.  
  326. //        vec3_t tmp;
  327. //        vectorInit3d((float)(cos(yaw)), 0.0f, (float)(sin(yaw)), tmp);
  328.         float m[] = {    left[0], left[1], left[2], 0.0f,
  329.                         up[0], up[1], up[2], 0.0f,
  330.                         dir[0], dir[1], dir[2], 0.0f,
  331.                         pos[0], pos[1], pos[2], 1.0f
  332.                     };
  333.  
  334.         float im[16];
  335.         float cm[16];
  336.         vec4_t transformedPos;
  337.  
  338.         c.torsoModel_colors = new GLfloat*[torsoModel->numMeshes];
  339.         for(i=0;i<torsoModel->numMeshes;i++){
  340.             Mesh* mesh = torsoModel->meshes[i];
  341.             c.torsoModel_colors[i] = new GLfloat[mesh->numVertices*3];
  342.         
  343.             matrixMultMatrix(m, torsoModel->matrices[frame][i], 4, cm);
  344.             matrixInvert(cm, 4, im);
  345.             vectorInit4d(dlpc->pos[0], dlpc->pos[1], dlpc->pos[2], 1.0f, transformedPos);
  346.             matrixMultVector(im, transformedPos, 4, transformedPos);
  347.             float transformedRadius = dlpc->radius;// * (float)fabs(im[0]);
  348.     
  349.             for(j=0;j<mesh->numVertices;j++){
  350.                 float f = vectorPointDistance3d(transformedPos, &mesh->vertices[j*3]) / transformedRadius;
  351.                 if( f < 0.0f ){        // most likely matrix was not inverted correctly...
  352. //                    printf("TORSO: f: %f;  tr: %f\n", f, transformedRadius);
  353.                     f = 0.0f;
  354.                 }
  355.                 if( f > 1.0f ){
  356. //                    printf("TORSO: f: %f;  tr: %f\n", f, transformedRadius);
  357.                     f = 1.0f;
  358.                 }
  359. //                f = f > 1.0f ? 1.0f : f;
  360.                 vectorScale3d(1.0f - f, dlpc->col, &c.torsoModel_colors[i][j*3]);
  361.                 vectorAdd3d(&torsoModelSecondaryColors[i][j*3], &c.torsoModel_colors[i][j*3], &torsoModelSecondaryColors[i][j*3]);
  362.             }
  363.         }
  364.     }
  365.  
  366.     // WEAPONS
  367.     for(k=0;k<4;k++){
  368.         if( weapons[k] != NULL ){
  369.             int frame = 0;
  370.             float m[] = {    left[0], left[1], left[2], 0.0f,
  371.                             up[0], up[1], up[2], 0.0f,
  372.                             dir[0], dir[1], dir[2], 0.0f,
  373.                             pos[0], pos[1], pos[2], 1.0f
  374.                         };
  375.     
  376.             float transM[] =    {    1.0f, 0.0f, 0.0f, 0.0f, 
  377.                                     0.0f, 1.0f, 0.0f, 0.0f,
  378.                                     0.0f, 0.0f, 1.0f, 0.0f,
  379.                                     weapons[k]->mountPoint[0], weapons[k]->mountPoint[1], weapons[k]->mountPoint[2], 1.0f
  380.                                 };
  381.  
  382.             float im[16];
  383.             float cm[16];
  384.             vec4_t transformedPos;
  385.  
  386.             c.weaponModel_colors[k] = new GLfloat*[weapons[k]->model->numMeshes];
  387.             for(i=0;i<weapons[k]->model->numMeshes;i++){
  388.                 Mesh* mesh = weapons[k]->model->meshes[i];
  389.                 c.weaponModel_colors[k][i] = new GLfloat[mesh->numVertices*3];
  390.         
  391.                 matrixMultMatrix(m, transM, 4, cm);
  392.                 matrixMultMatrix(cm, weapons[k]->model->matrices[frame][i], 4, cm);
  393.                 matrixInvert(cm, 4, im);
  394.                 vectorInit4d(dlpc->pos[0], dlpc->pos[1], dlpc->pos[2], 1.0f, transformedPos);
  395.                 matrixMultVector(im, transformedPos, 4, transformedPos);
  396.                 float transformedRadius = dlpc->radius;// * (float)fabs(im[0]);
  397.     
  398.                 for(j=0;j<mesh->numVertices;j++){
  399.                     float f = vectorPointDistance3d(transformedPos, &mesh->vertices[j*3]) / transformedRadius;
  400.                     if( f < 0.0f ){        // most likely matrix was not inverted correctly...
  401.                         f = 0.0f;
  402.                     }
  403.                     if( f > 1.0f ){
  404.                         f = 1.0f;
  405.                     }
  406.                     vectorScale3d(1.0f - f, dlpc->col, &c.weaponModel_colors[k][i][j*3]);
  407.                     vectorAdd3d(&weaponModelSecondaryColors[k][i][j*3], &c.weaponModel_colors[k][i][j*3], &weaponModelSecondaryColors[k][i][j*3]);
  408.                 }
  409.             }
  410.         }
  411.     }
  412.  
  413.     dlpcs.push_back(c);
  414. //    printf("dlpc added!\n");
  415. }
  416. void Mech::removeDynamicLightParticleCluster(DynamicLightParticleCluster* dlpc){
  417.     int i,j;
  418.  
  419.     for( vector<mech_dlpcCombo_t>::iterator iter = dlpcs.begin(); iter != dlpcs.end(); iter++ ){
  420.         if( iter->dlpc == dlpc ){
  421.             if( legsModel != NULL ){
  422.                 for(i=0;i<legsModel->numMeshes;i++){
  423.                     Mesh* m = legsModel->meshes[i];
  424.                     for(j=0;j<m->numVertices;j++){
  425.                         vectorSub3d(&legsModelSecondaryColors[i][j*3], &iter->legsModel_colors[i][j*3], &legsModelSecondaryColors[i][j*3]);
  426.                     }
  427.                     delete[] iter->legsModel_colors[i];
  428.                 }
  429.                 delete[] iter->legsModel_colors;
  430.             }
  431.  
  432.             if( torsoModel != NULL ){
  433.                 for(i=0;i<torsoModel->numMeshes;i++){
  434.                     Mesh* m = torsoModel->meshes[i];
  435.                     for(j=0;j<m->numVertices;j++){
  436.                         vectorSub3d(&torsoModelSecondaryColors[i][j*3], &iter->torsoModel_colors[i][j*3], &torsoModelSecondaryColors[i][j*3]);
  437.                     }
  438.                     delete[] iter->torsoModel_colors[i];
  439.                 }
  440.                 delete[] iter->torsoModel_colors;
  441.             }
  442.  
  443.             for(int k=0;k<4;k++){
  444.                 if( weapons[k] != NULL ){
  445.                     for(i=0;i<weapons[k]->model->numMeshes;i++){
  446.                         Mesh* m = weapons[k]->model->meshes[i];
  447.                         for(j=0;j<m->numVertices;j++){
  448.                             vectorSub3d(&weaponModelSecondaryColors[k][i][j*3], &iter->weaponModel_colors[k][i][j*3], &weaponModelSecondaryColors[k][i][j*3]);
  449.                         }
  450.                         delete[] iter->weaponModel_colors[k][i];
  451.                     }
  452.                     delete[] iter->weaponModel_colors[k];
  453.                 }
  454.             }
  455.  
  456.             dlpcs.erase(iter);
  457.             break;
  458.         }
  459.     }
  460.  
  461. //    printf("dlpc removed!\n");
  462. }
  463.  
  464.  
  465.  
  466. void Mech::render(){
  467.     int i, j, k;
  468.  
  469.     int lm_sav = Renderer::info.var.lightingMode;
  470.  
  471.     // calc the shading color
  472.     if( Renderer::info.var.shadeVehicles &&
  473.         (Renderer::info.var.lightingMode == LIGHTING_MODE_VERTEX || Renderer::info.var.lightingMode == LIGHTING_MODE_LIGHTMAP) ){
  474.  
  475.         Renderer::info.var.lightingMode = LIGHTING_MODE_VERTEX;    // set to vertex lighting because we need vertex colors
  476.  
  477.         vec3_t col, absMin, absMax;
  478.         vectorInit3d(0.0f, 0.0f, 0.0f, col);
  479.         float w_sum = 0.0f;
  480.         float maxDistance = 7.0f;
  481.  
  482.         vectorInit3d(pos[0]-maxDistance, pos[1]-maxDistance, pos[2]-maxDistance, absMin);
  483.         vectorInit3d(pos[0]+maxDistance, pos[1]+maxDistance, pos[2]+maxDistance, absMax);
  484.         vector<SpacePartitioningTreeNode*> nodes = Game::arena->sptree->getLeafNodesIntersectingAABB(absMin, absMax);
  485.  
  486.         for(i=0;i<(signed int)nodes.size();i++){
  487. //            nodes[i]->drawBorders();
  488.             Mesh* m = nodes[i]->mesh;
  489.             if( m != NULL ){
  490.  
  491.                 for(j=0;j<m->numVertices;j++){
  492.                     float d = vectorPointDistance3d(pos, &m->vertices[j*3]);
  493. //                    vec3_t tmp;
  494. //                    vectorSub3d(&m->vertices[j*3], pos, tmp);
  495. //                    float d = vectorLength3d(tmp);
  496.                     if( d < maxDistance /*&& vectorDotP3d(tmp, &m->normals[j*3]) < 0.0f*/ ){
  497.                         float w = 1.0f - d/maxDistance;
  498.                         w_sum += w;
  499.                         vectorMA3d(col, w, &m->colors[j*3], col);
  500. //                        Renderer::debug_renderLinesegment(pos, &m->vertices[j*3]);
  501.                     }
  502.                 }
  503.  
  504. //                if( nearestIndex != -1 ){
  505. //                    vectorCopy3d(&m->colors[nearestIndex*3], col);
  506. //                    Renderer::debug_renderLinesegment(pos, &m->vertices[nearestIndex*3]);
  507. //                }
  508.             }
  509.         }
  510.         
  511.         if( w_sum > 0.0f ){    // assign new colors
  512.             vectorScale3d(1.0f/w_sum, col, col);
  513.  
  514.             if( torsoModel != NULL ){
  515.                 for(i=0;i<torsoModel->numMeshes;i++){
  516.                     for(j=0;j<torsoModel->meshes[i]->numColors;j++){
  517.                         vectorCopy3d(col, &torsoModel->meshes[i]->colors[j*3]);
  518.                     }
  519.                 }    
  520.             }
  521.             if( legsModel != NULL ){
  522.                 for(i=0;i<legsModel->numMeshes;i++){
  523.                     for(j=0;j<legsModel->meshes[i]->numColors;j++){
  524.                         vectorCopy3d(col, &legsModel->meshes[i]->colors[j*3]);
  525.                     }
  526.                 }
  527.             }
  528.             for(k=0;k<4;k++){
  529.                 if( weapons[k] ==  NULL )
  530.                     continue;
  531.  
  532.                 for(i=0;i<weapons[k]->model->numMeshes;i++){
  533.                     for(j=0;j<weapons[k]->model->meshes[i]->numColors;j++){
  534.                         vectorCopy3d(col, &weapons[k]->model->meshes[i]->colors[j*3]);
  535.                     }
  536.                 }
  537.             }
  538.         }else{    // keep old colors
  539.         }
  540.  
  541.     }
  542.  
  543.     // legs
  544.     if( legsModel != NULL ){
  545.  
  546.         if( Renderer::info.var.useDynamicLighting && legsModelSecondaryColors != NULL ){    // setup dyn lighting
  547.             for(i=0;i<legsModel->numMeshes;i++){
  548.                 legsModel->meshes[i]->secondaryColors = legsModelSecondaryColors[i];
  549.             }
  550.  
  551.         }
  552.  
  553.         glPushMatrix();
  554.  
  555.         vec3_t tmp;
  556.         vectorInit3d((float)(cos(yaw)), 0.0f, (float)(sin(yaw)), tmp);
  557.         float m[] = {    left[0], left[1], left[2], 0.0f,
  558.                         e2[0], e2[1], e2[2], 0.0f,
  559.                         tmp[0], tmp[1], tmp[2], 0.0f,
  560.                         pos[0], pos[1], pos[2], 1.0f
  561.                     };
  562.         glMultMatrixf(m);
  563.  
  564.         float frame = 0.0f;
  565.         if( legsAnimator != NULL ){
  566.             frame = legsAnimator->calcCurrentFrame();
  567.         }
  568.         Renderer::renderModel(legsModel, frame);
  569.  
  570.         glPopMatrix();
  571.  
  572.         if( Renderer::info.var.useDynamicLighting && legsModelSecondaryColors != NULL ){
  573.             for(i=0;i<legsModel->numMeshes;i++){
  574.                 legsModel->meshes[i]->secondaryColors = NULL;
  575.             }
  576.         }
  577.     }
  578.  
  579.  
  580.     // torso
  581.     if( torsoModel != NULL &&
  582.             !(Game::cam.mode == CAMERA_MODE_FIRST_PERSON && Game::cam.target == this) ){
  583.  
  584.         if( Renderer::info.var.useDynamicLighting && torsoModelSecondaryColors != NULL ){    // setup dyn lighting
  585.             for(i=0;i<torsoModel->numMeshes;i++){
  586.                 torsoModel->meshes[i]->secondaryColors = torsoModelSecondaryColors[i];
  587.             }
  588.         }
  589.  
  590.  
  591.         
  592.         glPushMatrix();
  593.         float m[] = {    left[0], left[1], left[2], 0.0f,
  594.                     up[0], up[1], up[2], 0.0f,
  595.                     dir[0], dir[1], dir[2], 0.0f,
  596.                     pos[0], pos[1], pos[2], 1.0f
  597.                 };
  598.         glMultMatrixf(m);
  599.         Renderer::renderModel(torsoModel);
  600.  
  601.         glPopMatrix();
  602.  
  603.         if( Renderer::info.var.useDynamicLighting && torsoModelSecondaryColors != NULL ){
  604.             for(i=0;i<torsoModel->numMeshes;i++){
  605.                 torsoModel->meshes[i]->secondaryColors = NULL;
  606.             }
  607.         }
  608.  
  609.     }
  610.  
  611.     // weapons
  612.     for( k=0; k<4; k++ ){
  613.         if( weapons[k] == NULL )
  614.             continue;
  615.  
  616.         if( Renderer::info.var.useDynamicLighting && weaponModelSecondaryColors[k] != NULL ){    // setup dyn lighting
  617.             for(i=0;i<weapons[k]->model->numMeshes;i++){
  618.                 weapons[k]->model->meshes[i]->secondaryColors = weaponModelSecondaryColors[k][i];
  619.             }
  620.         }
  621.         
  622.         glPushMatrix();
  623.         float m[] = {    left[0], left[1], left[2], 0.0f,
  624.                     up[0], up[1], up[2], 0.0f,
  625.                     dir[0], dir[1], dir[2], 0.0f,
  626.                     pos[0], pos[1], pos[2], 1.0f
  627.                 };
  628.         glMultMatrixf(m);
  629.  
  630.         glTranslatef(weapons[k]->mountPoint[0], weapons[k]->mountPoint[1], weapons[k]->mountPoint[2]);
  631.  
  632.         float frame = 0.0f;
  633.         if( weapons[k]->animator != NULL ){    // setup animation
  634.             frame = weapons[k]->animator->calcCurrentFrame();
  635. //            printf("frame: %f\n", frame);
  636.         }
  637.         Renderer::renderModel(weapons[k]->model, frame);
  638.  
  639.         glPopMatrix();
  640.  
  641.         if( Renderer::info.var.useDynamicLighting && weaponModelSecondaryColors[k] != NULL ){
  642.             for(i=0;i<weapons[k]->model->numMeshes;i++){
  643.                 weapons[k]->model->meshes[i]->secondaryColors = NULL;
  644.             }
  645.         }
  646.     }
  647.  
  648.     if( Renderer::info.var.shadeVehicles &&
  649.         (Renderer::info.var.lightingMode == LIGHTING_MODE_VERTEX || Renderer::info.var.lightingMode == LIGHTING_MODE_LIGHTMAP) ){
  650.  
  651.         Renderer::info.var.lightingMode = lm_sav;    // restore lm if we did vehcile shading
  652.     }
  653.  
  654.     Vehicle::render();
  655.  
  656. }
  657.