LCOV - code coverage report
Current view: top level - src - Terrain.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 5.5 % 527 29
Test Date: 2026-04-03 02:26:39 Functions: 26.9 % 26 7

            Line data    Source code
       1              : //////////////////////////////////////////////////////////////////
       2              : // Description : Functions for terrain generation and display.  //
       3              : //////////////////////////////////////////////////////////////////
       4              : #include "Terrain.h"
       5              : 
       6              : #include <cstdlib>
       7              : #include <fstream>
       8              : 
       9              : //------------------------------------------------------------------------------
      10           18 : Terrain::Terrain() : Object() {
      11            9 :   vertex_         = NULL;
      12            9 :   lightIntensity_ = NULL;
      13            9 :   color_          = NULL;
      14            9 :   type_           = NULL;
      15            9 :   vertexNormal_   = NULL;
      16              : 
      17            9 :   init();
      18              : 
      19            9 :   typeId_         = 100;
      20           18 : }
      21              : 
      22              : //------------------------------------------------------------------------------
      23            9 : void Terrain::init() {
      24            9 :   unload();
      25              : 
      26            9 :   xSize_          = 0;
      27            9 :   zSize_          = 0;
      28            9 :   scaleFactor_    = 1.0f;
      29              : 
      30            9 :   isCurveEnabled_ = true;
      31            9 :   curveDistance_  = 200.0f;
      32            9 :   curveRate_      = 0.05f;
      33              : 
      34            9 :   enableSphereTest_ = false;
      35            9 : }
      36              : 
      37              : //------------------------------------------------------------------------------
      38           27 : Terrain::~Terrain() {
      39              :   // TODO: On linux there is an issue on unload
      40           27 : }
      41              : 
      42              : //------------------------------------------------------------------------------
      43            0 : void Terrain::draw(Object* c) {
      44            0 :   if (!vertex_ || !lightIntensity_ || !color_ || !type_) {
      45            0 :     return;
      46              :   }
      47              : 
      48              :   int x1, x2;
      49              :   int z1, z2;
      50              : 
      51              :   float xStart, zStart;
      52              :   float xPer1, xPer2, zPer1, zPer2;
      53              :   float tPer;
      54              :   GLfloat v[3];
      55              : 
      56            0 :   xStart = zStart = 0;
      57              : 
      58            0 :   glPushMatrix();
      59            0 :   QuadTreeNode* n = displayList_->head;
      60              : 
      61            0 :   while (n != NULL) {
      62            0 :     glBegin(GL_TRIANGLE_STRIP);
      63            0 :     xStart = n->min[0] / scaleFactor_;
      64            0 :     zStart = n->min[1] /  scaleFactor_;
      65              : 
      66            0 :     x1 = (int)xStart;
      67            0 :     x2 = ((int)xStart) + 1;
      68              : 
      69            0 :     z1 = (int)zStart;
      70            0 :     z2 = ((int)zStart) + 1;
      71              : 
      72            0 :     v[0] = vertex_[x1][z1][0];
      73            0 :     v[2] = vertex_[x1][z1][2];
      74              : 
      75            0 :     Vector cPosition = c->getPosition();
      76              : 
      77            0 :     xPer1 = (vertex_[x1][z1][0] - cPosition.x) * (vertex_[x1][z1][0] - cPosition.x);
      78            0 :     xPer2 = (vertex_[x2][z1][0] - cPosition.x) * (vertex_[x2][z1][0] - cPosition.x);
      79            0 :     zPer1 = (vertex_[x1][z1][2] - cPosition.z) * (vertex_[x1][z1][2] - cPosition.z);
      80            0 :     zPer2 = (vertex_[x1][z2][2] - cPosition.z) * (vertex_[x1][z2][2] - cPosition.z);
      81              : 
      82            0 :     tPer = sqrt(xPer1 + zPer1);
      83              : 
      84              :     //offset = 1000000;
      85              : 
      86            0 :     if (isCurveEnabled_ && tPer > curveDistance_) {
      87            0 :       tPer = tPer - curveDistance_;
      88            0 :       v[1] = -(curveRate_ * (tPer)) * (curveRate_ * (tPer))  + vertex_[x1][z1][1];
      89            0 :     }
      90              :     else
      91            0 :       v[1] = vertex_[x1][z1][1];
      92              : 
      93            0 :     glColor3fv(color_[x1][z1]);
      94            0 :     glTexCoord1f(lightIntensity_[x1][z1]);
      95            0 :     glVertex3fv(v);
      96              : 
      97            0 :     v[0] = vertex_[x2][z1][0];
      98            0 :     v[2] = vertex_[x2][z1][2];
      99              : 
     100            0 :     tPer = sqrt(xPer2 + zPer1);
     101              : 
     102            0 :     if (isCurveEnabled_ && tPer > curveDistance_) {
     103            0 :       tPer = tPer - curveDistance_;
     104            0 :       v[1] = -(curveRate_ * (tPer)) * (curveRate_ * (tPer))  + vertex_[x2][z1][1];
     105            0 :     }
     106              :     else
     107            0 :       v[1] = vertex_[x2][z1][1];
     108              : 
     109            0 :     glColor3fv(color_[x2][z1]);
     110            0 :     glTexCoord1f(lightIntensity_[x2][z1]);
     111            0 :     glVertex3fv(v);
     112              : 
     113            0 :     v[0] = vertex_[x1][z2][0];
     114            0 :     v[2] = vertex_[x1][z2][2];
     115              : 
     116            0 :     tPer = sqrt(xPer1 + zPer2);
     117              : 
     118            0 :     if (isCurveEnabled_ && tPer > curveDistance_) {
     119            0 :       tPer = tPer - curveDistance_;
     120            0 :       v[1] = -(curveRate_ * (tPer)) * (curveRate_ * (tPer))  + vertex_[x1][z2][1];
     121            0 :     }
     122              :     else
     123            0 :       v[1] = vertex_[x1][z2][1];
     124              : 
     125            0 :     glColor3fv(color_[x1][z2]);
     126            0 :     glTexCoord1f(lightIntensity_[x1][z2]);
     127            0 :     glVertex3fv(v);
     128              : 
     129            0 :     tPer = sqrt(xPer2 + zPer2);
     130              : 
     131            0 :     v[0] = vertex_[x2][z2][0];
     132            0 :     v[2] = vertex_[x2][z2][2];
     133              : 
     134            0 :     if (isCurveEnabled_ && tPer > curveDistance_) {
     135            0 :       tPer = tPer - curveDistance_;
     136            0 :       v[1] = -(curveRate_ * (tPer)) * (curveRate_ * (tPer) )  + vertex_[x2][z2][1];
     137            0 :     }
     138              :     else
     139            0 :       v[1] = vertex_[x2][z2][1];
     140              : 
     141            0 :     glColor3fv(color_[x2][z2]);
     142            0 :     glTexCoord1f(lightIntensity_[x2][z2]);
     143            0 :     glVertex3fv(v);
     144            0 :     glEnd();
     145              : 
     146            0 :     n = n->next;
     147              :   }
     148              : 
     149            0 :   glPopMatrix();
     150            0 : }
     151              : 
     152              : //------------------------------------------------------------------------------
     153            0 : void Terrain::drawOutline(Object* c) {
     154            0 :   if (!vertex_ || !lightIntensity_ || !color_ || !type_) {
     155            0 :     return;
     156              :   }
     157              : 
     158              :   int x1, x2;
     159              :   int z1, z2;
     160              : 
     161              :   float xStart, zStart;
     162              :   float xPer1, xPer2, zPer1, zPer2 ;
     163              :   float tPer;
     164              :   GLfloat v[3];
     165              : 
     166            0 :   xStart = zStart = 0;
     167              : 
     168            0 :   glPushMatrix();
     169            0 :   QuadTreeNode* n = displayList_->head;
     170              : 
     171            0 :   glColor3f(0.0f, 0.0f, 0.0f);
     172              : 
     173            0 :   while (n) {
     174            0 :     glBegin(GL_TRIANGLES);
     175            0 :     xStart = n->min[0] / scaleFactor_;
     176            0 :     zStart = n->min[1] / scaleFactor_;
     177              : 
     178            0 :     x1 = (int)xStart;
     179            0 :     x2 = ((int)xStart) + 1;
     180              : 
     181            0 :     z1 = (int)zStart;
     182            0 :     z2 = ((int)zStart) +1;
     183              : 
     184            0 :     v[0] = vertex_[x1][z1][0];
     185            0 :     v[2] = vertex_[x1][z1][2];
     186              : 
     187            0 :     Vector cPosition = c->getPosition();
     188              : 
     189            0 :     xPer1 = (vertex_[x1][z1][0] - cPosition.x) * (vertex_[x1][z1][0] - cPosition.x);
     190            0 :     xPer2 = (vertex_[x2][z1][0] - cPosition.x) * (vertex_[x2][z1][0] - cPosition.x);
     191            0 :     zPer1 = (vertex_[x1][z1][2] - cPosition.z) * (vertex_[x1][z1][2] - cPosition.z);
     192            0 :     zPer2 = (vertex_[x1][z2][2] - cPosition.z) * (vertex_[x1][z2][2] - cPosition.z);
     193              : 
     194            0 :     tPer = sqrt(xPer1 + zPer1);
     195              : 
     196            0 :     if (isCurveEnabled_ && tPer > curveDistance_) {
     197            0 :       tPer = tPer - curveDistance_;
     198            0 :       v[1] = -(curveRate_ * (tPer)) * (curveRate_ * (tPer))  + vertex_[x1][z1][1];
     199            0 :     }
     200              :     else
     201            0 :       v[1] = vertex_[x1][z1][1];
     202              : 
     203            0 :     glVertex3fv( v );
     204              : 
     205            0 :     v[0] = vertex_[x2][z1][0];
     206            0 :     v[2] = vertex_[x2][z1][2];
     207              : 
     208            0 :     tPer = sqrt(xPer2 + zPer1);
     209              : 
     210            0 :     if (isCurveEnabled_ && tPer > curveDistance_) {
     211            0 :       tPer = tPer - curveDistance_;
     212            0 :       v[1] = -(curveRate_ * (tPer)) * (curveRate_ * (tPer))  + vertex_[x2][z1][1];
     213            0 :     }
     214              :     else
     215            0 :       v[1] = vertex_[x2][z1][1];
     216              : 
     217            0 :     glVertex3fv(v);
     218              : 
     219            0 :     v[0] = vertex_[x1][z2][0];
     220            0 :     v[2] = vertex_[x1][z2][2];
     221              : 
     222            0 :     tPer = sqrt(xPer1 + zPer2);
     223              : 
     224            0 :     if (isCurveEnabled_ && tPer > curveDistance_) {
     225            0 :       tPer = tPer - curveDistance_;
     226              : 
     227            0 :       v[1] = -(curveRate_ * (tPer)) * (curveRate_ * (tPer))  + vertex_[x1][z2][1];
     228            0 :     }
     229              :     else
     230            0 :       v[1] = vertex_[x1][z2][1];
     231              : 
     232            0 :     glVertex3fv(v);
     233              : 
     234            0 :     tPer = sqrt(xPer2 + zPer2);
     235              : 
     236            0 :     v[0] = vertex_[x2][z2][0];
     237            0 :     v[2] = vertex_[x2][z2][2];
     238              : 
     239            0 :     if (isCurveEnabled_ && tPer > curveDistance_) {
     240            0 :       tPer = tPer - curveDistance_;
     241            0 :       v[1] = -(curveRate_ * (tPer)) * (curveRate_ * (tPer))  + vertex_[x2][z2][1];
     242            0 :     }
     243              :     else
     244            0 :       v[1] = vertex_[x2][z2][1];
     245              : 
     246            0 :     glVertex3fv(v);
     247            0 :     glEnd();
     248              : 
     249            0 :     n = n->next;
     250              :   }
     251              : 
     252            0 :   glPopMatrix();
     253            0 : }
     254              : 
     255              : //------------------------------------------------------------------------------
     256            0 : void Terrain::generate() {}
     257              : 
     258              : //------------------------------------------------------------------------------
     259            0 : void Terrain::calcViewableTerrainNorm() {
     260            0 :   if (!vertex_ || !lightIntensity_ || !color_ || !type_) {
     261            0 :     return;
     262              :   }
     263              : 
     264              :   int x1, x2;
     265              :   int z1, z2;
     266              : 
     267              :   float xStart, zStart;
     268              : 
     269            0 :   xStart = zStart = 0;
     270              : 
     271            0 :   Vector surfaceNormal;
     272            0 :   Vector temp1;
     273            0 :   Vector temp2;
     274              :   GLfloat tempLightIntensity;
     275              : 
     276            0 :   Vector temp[5];
     277              : 
     278            0 :   Matrix tempMatrix;
     279            0 :   tempMatrix.loadIdentity();
     280              : 
     281            0 :   QuadTreeNode* n = displayList_->head;
     282              : 
     283            0 :   while (n != NULL) {
     284            0 :     xStart = n->min[0] / scaleFactor_;
     285            0 :     zStart = n->min[1] /  scaleFactor_;
     286              : 
     287            0 :     x1 = (int)xStart;
     288            0 :     x2 = ((int)xStart) + 1;
     289              : 
     290            0 :     z1 = (int)zStart;
     291            0 :     z2 = ((int)zStart) + 1;
     292              : 
     293              :     PRINT_DEBUG_LVL(5, "x1=%d, z1=%d, x2=%d, z2=%d\n", x1, z1, x2, z2);
     294              : 
     295            0 :     vertexNormal_[x1][z1].x = 0.0f;
     296            0 :     vertexNormal_[x1][z1].y = 0.0f;
     297            0 :     vertexNormal_[x1][z1].z = 0.0f;
     298              : 
     299            0 :     vertexNormal_[x1+1][z1].x = 0.0f;
     300            0 :     vertexNormal_[x1+1][z1].y = 0.0f;
     301            0 :     vertexNormal_[x1+1][z1].z = 0.0f;
     302              : 
     303            0 :     vertexNormal_[x1][z1+1].x = 0.0f;
     304            0 :     vertexNormal_[x1][z1+1].y = 0.0f;
     305            0 :     vertexNormal_[x1][z1+1].z = 0.0f;
     306              : 
     307            0 :     vertexNormal_[x1+1][z1+1].x = 0.0f;
     308            0 :     vertexNormal_[x1+1][z1+1].y = 0.0f;
     309            0 :     vertexNormal_[x1+1][z1+1].z = 0.0f;
     310              : 
     311            0 :     n = n->next;
     312              :   }
     313              : 
     314            0 :   n = displayList_->head;
     315              : 
     316            0 :   while (n != NULL) {
     317            0 :     xStart = n->min[0] / scaleFactor_;
     318            0 :     zStart = n->min[1] /  scaleFactor_;
     319              : 
     320            0 :     x1 = (int)xStart;
     321            0 :     x2 = ((int)xStart) + 1;
     322              : 
     323            0 :     z1 = (int)zStart;
     324            0 :     z2 = ((int)zStart) + 1;
     325              : 
     326            0 :     if (x2 >= xSize_ || z2 >= zSize_) {
     327            0 :       continue;
     328              :     }
     329              : 
     330            0 :     temp[0].setVector(vertex_[x1][z1][0], vertex_[x1][z1][1], vertex_[x1][z1][2]);
     331            0 :     temp[1].setVector(vertex_[x1][z2][0], vertex_[x1][z2][1], vertex_[x1][z2][2]);
     332            0 :     temp[2].setVector(vertex_[x2][z1][0], vertex_[x2][z1][1], vertex_[x2][z1][2]);
     333            0 :     temp[3].setVector(vertex_[x2][z2][0], vertex_[x2][z2][1], vertex_[x2][z2][2]);
     334              : 
     335            0 :     surfaceNormal.calcNorm(temp[0], temp[2], temp[1]);
     336              : 
     337            0 :     vertexNormal_[x1][z1].x += surfaceNormal.x;
     338            0 :     vertexNormal_[x1][z1].y += surfaceNormal.y;
     339            0 :     vertexNormal_[x1][z1].z += surfaceNormal.z;
     340              : 
     341            0 :     vertexNormal_[x1][z2].x += surfaceNormal.x;
     342            0 :     vertexNormal_[x1][z2].y += surfaceNormal.y;
     343            0 :     vertexNormal_[x1][z2].z += surfaceNormal.z;
     344              : 
     345            0 :     vertexNormal_[x2][z1].x += surfaceNormal.x;
     346            0 :     vertexNormal_[x2][z1].y += surfaceNormal.y;
     347            0 :     vertexNormal_[x2][z1].z += surfaceNormal.z;
     348              : 
     349            0 :     surfaceNormal.calcNorm(temp[2], temp[3], temp[1]);
     350              : 
     351            0 :     vertexNormal_[x2][z1].x += surfaceNormal.x;
     352            0 :     vertexNormal_[x2][z1].y += surfaceNormal.y;
     353            0 :     vertexNormal_[x2][z1].z += surfaceNormal.z;
     354              : 
     355            0 :     vertexNormal_[x1][z2].x += surfaceNormal.x;
     356            0 :     vertexNormal_[x1][z2].y += surfaceNormal.y;
     357            0 :     vertexNormal_[x1][z2].z += surfaceNormal.z;
     358              : 
     359            0 :     vertexNormal_[x2][z2].x += surfaceNormal.x;
     360            0 :     vertexNormal_[x2][z2].y += surfaceNormal.y;
     361            0 :     vertexNormal_[x2][z2].z += surfaceNormal.z;
     362              : 
     363            0 :     n = n->next;
     364              :   }
     365              : 
     366              :   // calculate light intensity at every vertex
     367            0 :   n = displayList_->head;
     368              : 
     369            0 :   while (n != NULL) {
     370            0 :     xStart = n->min[0] / scaleFactor_;
     371            0 :     zStart = n->min[1] / scaleFactor_;
     372              : 
     373            0 :     x1 = (int)xStart;
     374            0 :     x2 = ((int)xStart) + 1;
     375              : 
     376            0 :     z1 = (int)zStart;
     377            0 :     z2 = ((int)zStart) + 1;
     378              : 
     379            0 :     vertexNormal_[x1][z1].normalize();
     380              : 
     381            0 :     temp2.rotateVector(tempMatrix, vertexNormal_[x1][z1]);
     382            0 :     temp2.normalize();
     383              : 
     384            0 :     tempLightIntensity = temp2.dotProduct(*light_);
     385              : 
     386              :     // light correction //
     387            0 :     if (tempLightIntensity == 1.0f)
     388            0 :       tempLightIntensity = 0.5f;
     389            0 :     else if (tempLightIntensity < 0.0f)
     390            0 :       tempLightIntensity = 0.0f;
     391              : 
     392            0 :     lightIntensity_[x1][z1] = tempLightIntensity;
     393              : 
     394            0 :     n = n->next;
     395              :   }
     396            0 : }
     397              : 
     398              : //------------------------------------------------------------------------------
     399            0 : void Terrain::calcTerrainNorm(Vector* light) {
     400            0 :   if (!vertex_ || !lightIntensity_ || !color_ || !type_) {
     401            0 :     PRINT_ERROR("Could not save terrain.\n");
     402            0 :     return;
     403              :   }
     404              : 
     405            0 :   Vector surfaceNormal;
     406            0 :   Vector temp1;
     407            0 :   Vector temp2;
     408              :   GLfloat tempLightIntensity;
     409              : 
     410            0 :   Vector temp[5];
     411              : 
     412            0 :   Matrix tempMatrix;
     413            0 :   tempMatrix.loadIdentity();
     414              : 
     415              :   int x1, x2;
     416              :   int z1, z2;
     417              : 
     418              :   // calculate surface normal
     419            0 :   for (int z = 0; z < (zSize_-1); z++) {
     420            0 :     for (int x = 0; x < (xSize_-1); x++)  {
     421            0 :       x1 = x;
     422            0 :       x2 = x+1;
     423            0 :       z1 = z;
     424            0 :       z2 = z+1;
     425              : 
     426            0 :       temp[0].setVector(vertex_[x1][z1][0], vertex_[x1][z1][1], vertex_[x1][z1][2]);
     427            0 :       temp[1].setVector(vertex_[x1][z2][0], vertex_[x1][z2][1], vertex_[x1][z2][2]);
     428            0 :       temp[2].setVector(vertex_[x2][z1][0], vertex_[x2][z1][1], vertex_[x2][z1][2]);
     429            0 :       temp[3].setVector(vertex_[x2][z2][0], vertex_[x2][z2][1], vertex_[x2][z2][2]);
     430              : 
     431            0 :       surfaceNormal.calcNorm(temp[0], temp[2], temp[1]);
     432              : 
     433            0 :       vertexNormal_[x1][z1].x += surfaceNormal.x;
     434            0 :       vertexNormal_[x1][z1].y += surfaceNormal.y;
     435            0 :       vertexNormal_[x1][z1].z += surfaceNormal.z;
     436              : 
     437            0 :       vertexNormal_[x1][z2].x += surfaceNormal.x;
     438            0 :       vertexNormal_[x1][z2].y += surfaceNormal.y;
     439            0 :       vertexNormal_[x1][z2].z += surfaceNormal.z;
     440              : 
     441            0 :       vertexNormal_[x2][z1].x += surfaceNormal.x;
     442            0 :       vertexNormal_[x2][z1].y += surfaceNormal.y;
     443            0 :       vertexNormal_[x2][z1].z += surfaceNormal.z;
     444              : 
     445            0 :       surfaceNormal.calcNorm(temp[2], temp[3], temp[1]);
     446              : 
     447            0 :       vertexNormal_[x2][z1].x += surfaceNormal.x;
     448            0 :       vertexNormal_[x2][z1].y += surfaceNormal.y;
     449            0 :       vertexNormal_[x2][z1].z += surfaceNormal.z;
     450              : 
     451            0 :       vertexNormal_[x1][z2].x += surfaceNormal.x;
     452            0 :       vertexNormal_[x1][z2].y += surfaceNormal.y;
     453            0 :       vertexNormal_[x1][z2].z += surfaceNormal.z;
     454              : 
     455            0 :       vertexNormal_[x2][z2].x += surfaceNormal.x;
     456            0 :       vertexNormal_[x2][z2].y += surfaceNormal.y;
     457            0 :       vertexNormal_[x2][z2].z += surfaceNormal.z;
     458            0 :     }
     459            0 :   }
     460              : 
     461              :   // calculate light intensity at every vertex
     462            0 :   for (int z = 0; z < zSize_; z++) {
     463            0 :     for (int x = 0; x < xSize_; x++) {
     464            0 :       vertexNormal_[x][z].normalize();
     465              : 
     466            0 :       temp2.rotateVector(tempMatrix, vertexNormal_[x][z]);
     467            0 :       temp2.normalize();
     468              : 
     469            0 :       tempLightIntensity = temp2.dotProduct(*light);
     470              : 
     471              :       // light correction //
     472            0 :       if (tempLightIntensity == 1.0f)
     473            0 :         tempLightIntensity = 0.5f;
     474            0 :       else if (tempLightIntensity < 0.0f)
     475            0 :         tempLightIntensity = 0.0f;
     476              : 
     477            0 :       lightIntensity_[x][z] = tempLightIntensity;
     478            0 :     }
     479            0 :   }
     480            0 : }
     481              : 
     482              : //------------------------------------------------------------------------------
     483            0 : void Terrain::update(Vector* light) {
     484            0 :   if (vertex_ == NULL || lightIntensity_ == NULL || color_ == NULL || type_ == NULL) {
     485            0 :     return;
     486              :   }
     487              : 
     488            0 :   if (lastLight_.x != light->x || lastLight_.y != light->y || lastLight_.z != light->z) {
     489            0 :     calcViewableTerrainNorm();
     490            0 :     lastLight_.setVector(light->x, light->y, light->z);
     491            0 :   }
     492            0 : }
     493              : 
     494              : //------------------------------------------------------------------------------
     495            0 : float Terrain::getHeight(const float &x, const float &z) {
     496            0 :   if (vertex_ == NULL || lightIntensity_ == NULL || color_ == NULL || type_ == NULL) {
     497            0 :     return 0.0f;
     498              :   }
     499              : 
     500              :   float terX, terZ;
     501              : 
     502              :   // x and z value in terms of the terrain
     503            0 :   terX = x / scaleFactor_;
     504            0 :   terZ = -z / scaleFactor_;
     505              : 
     506              :   // calculate cell row and column into array
     507              :   int row, col1, col2;
     508            0 :   col1 = (int)(terX);
     509            0 :   row = (int)(terZ);
     510            0 :   col2 = col1 + 1;
     511              : 
     512            0 :   if (col1 < 0 || col2 < 0 || row < 0) {
     513              :     PRINT_DEBUG("Error: x=%f, z=%f, row=%d, col1=%d, col2=%d\n", x, -z, row, col1, col2);
     514            0 :     return 0.0f;
     515              :   }
     516              : 
     517              :   // test to make sure still in terrain
     518            0 :   if (col1 >= xSize_ || col2 >= xSize_ || row >= zSize_) {
     519              :     // TODO: Does subtracting the xSize from col2 provide any benefit?
     520              :     //col2 -= xSize_;
     521              :     PRINT_DEBUG("Calculated coordinates outside of the terrain...\n");
     522            0 :     return 0.0f;
     523              :   }
     524              : 
     525              :   // calculate percentage into cell
     526              :   float perX, perZ;
     527            0 :   perX = fmod(terX, xSize_) - col1;
     528            0 :   perZ = float(terZ) - row;
     529              : 
     530              :   // get height values at all 4 corners
     531              :   float height1, height2, height3, height4;
     532            0 :   height1 = vertex_[col1][row][1];
     533            0 :   height2 = vertex_[col2][row][1];
     534            0 :   height3 = vertex_[col1][row+1][1];
     535            0 :   height4 = vertex_[col2][row+1][1];
     536              : 
     537              :   // calculate the final height using bilinear interpolation
     538            0 :   float th1 = (1 - perZ )*height1 + (perZ*height3);
     539            0 :   float th2 = (1 - perZ )*height2 + (perZ*height4);
     540              : 
     541            0 :   float finalHeight = (1 - perX) * th1 + (perX * th2);
     542              : 
     543              :   PRINT_DEBUG_LVL(5, "returning height=%f\n", finalHeight);
     544              : 
     545            0 :   return (finalHeight);
     546            0 : }
     547              : 
     548              : //------------------------------------------------------------------------------
     549            0 : void Terrain::animate(const float &elapsedTime, Object* c) {
     550            0 :   if (vertex_ == NULL || lightIntensity_ == NULL || color_ == NULL || type_ == NULL) {
     551            0 :     return;
     552              :   }
     553              : 
     554            0 :   totalTime_ += elapsedTime;
     555              : 
     556              :   int x1;
     557              :   int z1;
     558              : 
     559              :   float xStart, zStart;
     560              : 
     561            0 :   xStart = zStart = 0;
     562              : 
     563            0 :   QuadTreeNode* n = displayList_->head;
     564              : 
     565              :   PRINT_DEBUG_LVL(5, "--------------\n");
     566              : 
     567            0 :   while (n != NULL) {
     568            0 :     xStart = n->min[0] / scaleFactor_;
     569            0 :     zStart = n->min[1] / scaleFactor_;
     570              : 
     571            0 :     x1 = (int)xStart;
     572              : 
     573            0 :     z1 = (int)zStart;
     574              : 
     575              :     PRINT_DEBUG_LVL(5, "x1=%d, z1=%d\n", x1, z1);
     576              : 
     577              :     //if (z1 < zSize_ - 1 && z1 > 3) {
     578            0 :     if (type_[x1][z1] == 1) {
     579            0 :       if (totalTime_ > 0.5f) {
     580            0 :         if (rand() % 100 < 20)
     581            0 :           type_[x1][z1] = 2;
     582            0 :       }
     583            0 :     }
     584            0 :     else if (type_[x1][z1] == 2) {
     585            0 :       vertex_[x1][z1][1] += (elapsedTime);
     586              : 
     587            0 :       if (vertex_[x1][z1][1] > 2.0f) {
     588            0 :         vertex_[x1][z1][1] = 2.0f;
     589            0 :         type_[x1][z1] = 3;
     590            0 :       }
     591            0 :     }
     592            0 :     else if (type_[x1][z1] == 3) {
     593            0 :       vertex_[x1][z1][1] -= (elapsedTime);
     594              : 
     595            0 :       if (vertex_[x1][z1][1] < 0.0f) {
     596            0 :         vertex_[x1][z1][1] =  0.0f;
     597            0 :         type_[x1][z1] = 1;
     598            0 :       }
     599            0 :     }
     600              :     //}
     601              : 
     602            0 :     n = n->next;
     603              :   }
     604              : 
     605            0 :   if (totalTime_ > 0.5f)
     606            0 :     totalTime_ = 0.0f;
     607              : 
     608            0 :   calcViewableTerrainNorm();
     609            0 : }
     610              : 
     611              : //------------------------------------------------------------------------------
     612            0 : void Terrain::load(const char* filePath, Vector* light) {
     613            0 :   init();
     614              : 
     615            0 :   GLfloat min[] = { 9999.0f, 9999.0f, 9999.0f };
     616            0 :   GLfloat max[] = { -9999.0f, -9999.0f, -9999.0f };
     617              : 
     618            0 :   light_ = light;
     619              : 
     620            0 :   std::ifstream fin;
     621            0 :   fin.open(filePath);
     622            0 :   fin >> xSize_;
     623            0 :   fin >> zSize_;
     624            0 :   fin >> scaleFactor_;
     625              : 
     626            0 :   vertex_ = new GLfloat**[xSize_];
     627            0 :   lightIntensity_ = new GLfloat*[xSize_];
     628            0 :   color_ = new GLfloat**[xSize_];
     629            0 :   type_ = new GLint*[xSize_];
     630              : 
     631            0 :   for (int i = 0; i < xSize_; i++) {
     632            0 :     vertex_[i] = new GLfloat*[zSize_];
     633            0 :     lightIntensity_[i] = new GLfloat[zSize_];
     634            0 :     color_[i] = new GLfloat*[zSize_];
     635            0 :     type_[i] = new GLint[zSize_];
     636              : 
     637            0 :     for (int j = 0; j < zSize_; j++) {
     638            0 :       vertex_[i][j] = new GLfloat[3];
     639            0 :       color_[i][j] = new GLfloat[3];
     640            0 :     }
     641            0 :   }
     642              : 
     643            0 :   for (int z = 0; z < zSize_; z++) {
     644            0 :     for (int x = 0; x < xSize_; x++) {
     645            0 :       fin >> vertex_[x][z][1];
     646            0 :       vertex_[x][z][0] = x * scaleFactor_;
     647            0 :       vertex_[x][z][2] = -z * scaleFactor_;
     648            0 :       fin >> color_[x][z][0] >> color_[x][z][1] >> color_[x][z][2];
     649            0 :       fin >> type_[x][z];
     650              : 
     651            0 :       if (type_[x][z] == 1) {
     652            0 :         vertex_[x][z][1] = (rand() % 100 / 100.0f) * 2.0f;
     653            0 :         int t = rand() % 100;
     654            0 :         if (t < 20) {
     655            0 :           type_[x][z] = 2;
     656            0 :         }
     657            0 :         else if (t < 40) {
     658            0 :           type_[x][z] = 3;
     659            0 :         }
     660            0 :       }
     661              : 
     662            0 :       for (int i = 0; i < 3; i++) {
     663            0 :         if (vertex_[x][z][i] < min[i])
     664            0 :           min[i] = vertex_[x][z][i];
     665              : 
     666            0 :         if (vertex_[x][z][i] > max[i])
     667            0 :           max[i] = vertex_[x][z][i];
     668            0 :       }
     669            0 :     }
     670            0 :   }
     671              : 
     672            0 :   fin.close();
     673              : 
     674            0 :   vertexNormal_ = new Vector*[xSize_];
     675            0 :   for (int i = 0; i < xSize_; i++) {
     676            0 :     vertexNormal_[i] = new Vector[zSize_];
     677            0 :   }
     678              : 
     679              :   // calculate normals in code for now, later add static calculation to be
     680              :   // loaded in... only water will be dynamic
     681            0 :   calcTerrainNorm(light);
     682              : 
     683            0 :   collisionBox_[0].setVector( min[0], min[1], min[2] );
     684            0 :   collisionBox_[1].setVector( max[0], max[1], max[2] );
     685              : 
     686              :   PRINT_DEBUG("Terrain Collision Box min x=%f, y=%f, z=%f\n", collisionBox_[0].x, collisionBox_[0].y, collisionBox_[0].z);
     687              :   PRINT_DEBUG("Terrain Collision Box max x=%f, y=%f, z=%f\n", collisionBox_[1].x, collisionBox_[1].y, collisionBox_[1].z);
     688            0 : }
     689              : 
     690              : //------------------------------------------------------------------------------
     691            9 : void Terrain::unload() {
     692            9 :   if (vertex_ != NULL && lightIntensity_ != NULL && color_ != NULL && type_ != NULL && vertexNormal_ != NULL) {
     693            0 :     for (int i = 0; i < xSize_; i++) {
     694            0 :       for (int j = 0; j < zSize_; j++) {
     695            0 :         delete[] vertex_[i][j];
     696            0 :         delete[] color_[i][j];
     697            0 :       }
     698              : 
     699            0 :       delete[] vertex_[i];
     700            0 :       delete[] lightIntensity_[i];
     701            0 :       delete[] color_[i];
     702            0 :       delete[] vertexNormal_[i];
     703            0 :       delete[] type_[i];
     704            0 :     }
     705              : 
     706            0 :     delete[] vertex_;
     707            0 :     delete[] lightIntensity_;
     708            0 :     delete[] color_;
     709            0 :     delete[] vertexNormal_;
     710            0 :     delete[] type_;
     711            0 :   }
     712              : 
     713            9 :   vertex_ = NULL;
     714            9 :   lightIntensity_ = NULL;
     715            9 :   color_ = NULL;
     716            9 :   vertexNormal_ = NULL;
     717            9 :   type_ = NULL;
     718            9 : }
     719              : 
     720              : //------------------------------------------------------------------------------
     721            0 : void Terrain::drawGrid() {
     722            0 :   glPushMatrix();
     723              :   //glDepthFunc( GL_ALWAYS );
     724            0 :   glColor3f(1.0f, 0.0f, 0.0f);
     725            0 :   glBegin(GL_LINES);
     726              : 
     727            0 :   for (int x = 0; x < xSize_; x++) {
     728            0 :     glVertex3f(x*scaleFactor_, 10.0f, 0.0f);
     729            0 :     glVertex3f(x*scaleFactor_, 10.0f, -(zSize_ - 1) * scaleFactor_);
     730            0 :   }
     731              : 
     732            0 :   for (int z = 0; z < zSize_; z++ ) {
     733            0 :     glVertex3f(0.0f, 10.0f, -z * scaleFactor_);
     734            0 :     glVertex3f((xSize_ - 1) * scaleFactor_, 10.0f, -z * scaleFactor_);
     735            0 :   }
     736              : 
     737            0 :   glEnd();
     738            0 :   glPopMatrix();
     739            0 : }
     740              : 
     741              : //------------------------------------------------------------------------------
     742            0 : void Terrain::save(const char* filePath, Vector* light) {
     743            0 :   if (vertex_ == NULL || lightIntensity_ == NULL || color_ == NULL || type_ == NULL) {
     744            0 :     PRINT_ERROR("Could not save terrain.\n");
     745            0 :     return;
     746              :   }
     747              : 
     748            0 :   std::ofstream fin;
     749            0 :   fin.open(filePath);
     750            0 :   fin << xSize_ << std::endl;
     751            0 :   fin << zSize_ << std::endl;
     752            0 :   fin << scaleFactor_ << std::endl;
     753              : 
     754            0 :   for (int z = 0; z < zSize_; z++) {
     755            0 :     for (int x = 0; x < xSize_; x++) {
     756            0 :       fin << vertex_[x][z][1] << std::endl;
     757              : 
     758            0 :       fin << color_[x][z][0] <<  "\t" << color_[x][z][1]<< "\t" << color_[x][z][2] << std::endl;
     759            0 :       int type = type_[x][z] == 0 ? 0 : 1;
     760            0 :       fin << type << std::endl;
     761            0 :     }
     762            0 :   }
     763              : 
     764            0 :   fin.close();
     765            0 : }
     766              : 
     767            0 : void Terrain::setVertexHeight(const int &x, const int &z, const float &height) {
     768            0 :   if (!vertex_)
     769            0 :     return;
     770              : 
     771            0 :   if ( x >= 0 && x <= xSize_ - 1 && z >= 0 && z <= zSize_ - 1) {
     772            0 :     vertex_[x][z][1] = height;
     773            0 :   }
     774            0 : }
     775              : 
     776            0 : void Terrain::setVertexType(const int &x, const int &z, const int &type) {
     777            0 :   if (!type_)
     778            0 :     return;
     779              : 
     780            0 :   if ( x >= 0 && x <= xSize_ - 1 && z >= 0 && z <= zSize_ - 1) {
     781            0 :     type_[x][z] = type;
     782            0 :   }
     783            0 : }
     784              : 
     785            0 : void Terrain::setVertexColor(const int &x, const int &z, const Vector &color) {
     786            0 :   if (!color_)
     787            0 :     return;
     788              : 
     789            0 :   if ( x >= 0 && x <= xSize_ - 1 && z >= 0 && z <= zSize_ - 1) {
     790            0 :     color_[x][z][0] = color.x;
     791            0 :     color_[x][z][1] = color.y;
     792            0 :     color_[x][z][2] = color.z;
     793            0 :   }
     794            0 : }
     795              : 
     796              : //------------------------------------------------------------------------------
     797            0 : float Terrain::getVertexHeight(const int &x, const int &z) {
     798            0 :   if (!vertex_)
     799            0 :     return 0.0f;
     800              : 
     801            0 :   if ( x >= 0 && x <= xSize_ - 1 && z >= 0 && z <= zSize_ - 1) {
     802            0 :     return vertex_[x][z][1];
     803              :   }
     804              : 
     805            0 :   return 0.0f;
     806            0 : }
     807              : 
     808              : //------------------------------------------------------------------------------
     809            0 : int Terrain::getVertexType(const int &x, const int &z) {
     810            0 :   if (!type_)
     811            0 :     return 0;
     812              : 
     813            0 :   if ( x >= 0 && x <= xSize_ - 1 && z >= 0 && z <= zSize_ - 1) {
     814            0 :     return type_[x][z];
     815              :   }
     816              : 
     817            0 :   return 0;
     818            0 : }
     819              : 
     820              : //------------------------------------------------------------------------------
     821            0 : Vector Terrain::getVertexColor(const int &x, const int &z) {
     822            0 :   Vector color;
     823            0 :   color.setVector(0.0f, 0.0f, 0.0f);
     824              : 
     825            0 :   if (!color_)
     826            0 :     return color;
     827              : 
     828            0 :   if ( x >= 0 && x <= xSize_ - 1 && z >= 0 && z <= zSize_ - 1) {
     829            0 :     color.setVector(color_[x][z][0], color_[x][z][1], color_[x][z][2]);
     830            0 :     return color;
     831              :   }
     832              : 
     833            0 :   return color;
     834            0 : }
     835              : 
     836            0 : void Terrain::buildLuaObjectTable(lua_State *L) {
     837            0 :   Object::buildLuaObjectTable(L);
     838            0 : }
     839              : 
     840            0 : void Terrain::transferLuaObjectTable(lua_State *L) {
     841            0 :   Object::transferLuaObjectTable(L);
     842            0 : }
        

Generated by: LCOV version 2.4-0