Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/importer/height_map.cc @ 7467

Last change on this file since 7467 was 7467, checked in by patrick, 18 years ago

orxonox: auto reformat of the height map source file.

  • Property svn:executable set to *
File size: 15.5 KB
RevLine 
[5942]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
[6956]12   main-programmer: bottac@ee.ethz.ch
[5942]13*/
14
15#include "height_map.h"
16#include "model.h"
[5967]17#include "texture.h"
18#include "vector.h"
[6956]19#include "material.h"
20#include "p_node.h"
21#include "state.h"
[7193]22#include "util/loading/resource_manager.h"
[5967]23#include "debug.h"
24
25// INCLUDING SDL_Image
26#ifdef HAVE_SDL_IMAGE_H
27#include <SDL_image.h>
28#else
29#include <SDL/SDL_image.h>
30#endif
31
[7467]32
[7014]33Tile::Tile(int i1, int j1, int i2, int j2, HeightMap* hm )
[5942]34{
[7467]35  PRINTF(0)("Tile Constructor\n");
36  highResModel = new VertexArrayModel();
37  lowResModel  = new VertexArrayModel();
[6956]38
[7467]39  this->load(i1,j1,i2,j2,hm,highResModel,4);
40  this->load(i1,j1,i2,j2,hm,lowResModel, 8);
[6956]41}
42
43Tile::~Tile()
44{
[7467]45  delete highResModel;
46  delete lowResModel;
[6956]47}
48
49void Tile::draw()
50{
[7467]51  // This Draws the LOD's
52  //FIXME
53  float cameraDistance = (State::getCameraNode()->getAbsCoor() - Vector(this->x, hmref->offsetY , this->z) ).len();
54  if(cameraDistance < 0)
55    cameraDistance = -cameraDistance;
56  if(cameraDistance > 5000 )
57  {
58    return;
59  }
60  else if (cameraDistance >= 1000 )
61  {
62    this->drawLowRes();
63  }
64  else
65  {
66    this->drawHighRes();
67  }
[6956]68}
69
70void Tile::drawHighRes()
71{
[7467]72  highResModel->draw();
[6956]73}
74
75void Tile::drawLowRes()
76{
[7467]77  lowResModel->draw();
[6956]78}
79
80/*
81*/
82void Tile::load(int i1, int j1, int i2, int j2, HeightMap* hm, VertexArrayModel* model, int Res)
83{
84
[7467]85#define heightMap hm->heightMap
[7014]86        #define colours   hm->colours
87        #define scaleX hm->scaleX
88        #define scaleY hm->scaleY
89        #define scaleZ hm->scaleZ
90        #define shiftX hm->shiftX
91        #define shiftY hm->shiftY
92        #define shiftZ hm->shiftZ
93        #define normalVectorField hm->normalVectorField
[6956]94
[7467]95  hmref = hm; // FIXME
[7014]96
[7467]97  this->x = hm->offsetX + (heightMap->h - ((i1+i2)/2))*scaleX;
98  this->z = hm->offsetZ + ((j1 + j2 )/2 ) * scaleZ;
[7014]99
[7467]100  int sampleRate = Res;
[7014]101
[7467]102  float height = 0;
103  int offset = 0;
[7014]104
[7467]105  float r = 0.0;
106  float g = 0.0;
107  float b = 0.0;
[7014]108
109
110
111
[7467]112  if(heightMap != NULL && heightMap->format->BitsPerPixel == 8 )
[6956]113
[7467]114    SDL_LockSurface(heightMap);
115  SDL_LockSurface(hm->colourMap);
[6956]116
[7467]117  for(int i = i1 ; i <= i2  ; i +=sampleRate)
118  {
119    int w = 0;
[6956]120
121
122
[7467]123    if(hm->hasColourMap)
124    {
125      r = colours[(3*w+2 + 3*i*(heightMap->w )) ];
126      g = colours[(3*w+1 + 3*i*(heightMap->w)) ];
127      b = colours[(3*w+0 + 3*i*(heightMap->w))];
128    }
[7014]129
[7467]130    w = j1;
131    model->addVertex(scaleX*(heightMap->h -i)+ shiftX,shiftY,scaleZ*(w)+ shiftZ); // Top Right
132    model->addNormal(normalVectorField[i % heightMap->h][w % heightMap->w].y,normalVectorField[i % heightMap->h][w % heightMap->w].z,normalVectorField[i % heightMap->h][w % heightMap->w].x);
133    model->addTexCoor((float)(j1-sampleRate) /(texRate), (float)(i %heightMap->h)/(texRate));
[7014]134
[7467]135    model->addColor(r/255.0,g/255.0,b/255.0);
[7014]136
[7467]137    for(int j = j1  ; j <= j2    ;  j += sampleRate)
138    {
[7014]139
140
[7467]141      // To be fixed
142      if(hm->hasColourMap)
143      {
144        r = colours[(3*j+2 + 3*i*(heightMap->w )) ];
145        g =  colours[(3*j+1 + 3*i*(heightMap->w)) ];
146        b =  colours[(3*j+0 + 3*i*(heightMap->w))];
147      }
148      height = (float)(unsigned char) hm->heights[(j +sampleRate+ i*(heightMap->w )) ];
149      height += (float)(unsigned char) hm->heights[(j+ 1 + sampleRate + (i+1)*(heightMap->w )) ];
150      height +=  (float) (unsigned char) hm->heights[(j -1+ sampleRate   + (i+1)*(heightMap->w ))];
151      height +=  (float)(unsigned char)hm->heights[(j +sampleRate+ (i+2)*(heightMap->w )) ];
152      height +=  (float)(unsigned char)hm->heights[(j+sampleRate + (i)*(heightMap->w )) ];
153      height=height/5.0;
[7014]154
[7467]155      model->addVertex(scaleX*(heightMap->h -i) + shiftX ,((double)(height)*scaleY) + shiftY ,scaleZ*(j) + shiftZ); // Top Right
156      model->addNormal(normalVectorField[i % heightMap->h][j % heightMap->w].y,normalVectorField[i % heightMap->h][j % heightMap->w].z,normalVectorField[i % heightMap->h][j % heightMap->w].x);
157      model->addTexCoor((float)(j) /(texRate), (float)(i %heightMap->h)/(texRate));
[7014]158
[7467]159      //PRINTF(0)("TexCoord:  %f %f \n",(float)j / 100.0, (float)(i %heightMap->h)/100.0);
[7014]160
[7467]161      model->addColor(r/255.0,g/255.0,b/255.0);
162      w = j;
163    }
[7014]164
165
[7467]166    model->addVertex(scaleX*(heightMap->h -i)+ shiftX,shiftY,scaleZ*(w)+ shiftZ); // Top Right
167    model->addNormal(normalVectorField[i % heightMap->h][w % heightMap->w].y,normalVectorField[i % heightMap->h][w % heightMap->w].z,normalVectorField[i% heightMap->h][w % heightMap->w].x);
168    model->addTexCoor((float)(j2+sampleRate) /(texRate), (float)(i %heightMap->h)/(texRate));
169    model->addColor(r/255.0,g/255.0,b/255.0);
[7014]170
[7467]171  }
[7014]172
173
174
175
176
[7467]177  SDL_UnlockSurface(heightMap);
178  int cnt = 0;
179  for(int i = i1   ; i < i2  ; i +=sampleRate)
180  {
[7014]181
[7467]182    for(int j = j1-sampleRate  ; j < j2  + 2*sampleRate  ;  j += sampleRate)
183    {
[7014]184
[7467]185      model->addIndice(cnt);
186      model->addIndice(cnt  + (j2 -j1 + 3* sampleRate  )/ sampleRate );
187      cnt++;
[7014]188
[7467]189    }
[7014]190
191
192
[7467]193    model->newStripe();
[7014]194
195
[7467]196  }
197  cnt += (j2 -j1 + 3* sampleRate)/ sampleRate;
[7014]198
[7467]199  for(int j = j1 ; j <= j2    ;  j += sampleRate)
200  {
201    int i = i1;
[7014]202
[7467]203    // To be fixed
204    if(hm->hasColourMap)
205    {
206      r = (float)colours[(3*j+2 + 3*i*(heightMap->w )) ];
207      g = (float)colours[(3*j+1 + 3*i*(heightMap->w)) ];
208      b = (float)colours[(3*j+0 + 3*i*(heightMap->w))];
209    }
[7014]210
[7467]211    model->addVertex(scaleX*(heightMap->h -i) + shiftX , shiftY ,scaleZ*(j) + shiftZ); // Top Right
212    model->addNormal(normalVectorField[i % heightMap->h][j % heightMap->w].y,normalVectorField[i % heightMap->h][j % heightMap->w].z,normalVectorField[i % heightMap->h][j % heightMap->w].x);
213    model->addTexCoor((float)j /(texRate), (float)((i - sampleRate) %heightMap->h)/(texRate));
214    model->addColor(r/255.0,g/255.0,b/255.0);
[7014]215
[7467]216  }
[7014]217
[7467]218  for(int j = j1  ; j <= j2    ;  j += sampleRate)
219  {
220    int i = i1;
221    height = (float)(unsigned char) hm->heights[(j +sampleRate+ i*(heightMap->w )) ];
222    height += (float)(unsigned char) hm->heights[(j+ 1 + sampleRate + (i+1)*(heightMap->w )) ];
223    height +=  (float) (unsigned char) hm->heights[(j -1+ sampleRate   + (i+1)*(heightMap->w ))];
224    height +=  (float)(unsigned char)hm->heights[(j +sampleRate+ (i+2)*(heightMap->w )) ];
225    height +=  (float)(unsigned char)hm->heights[(j+sampleRate + (i)*(heightMap->w )) ];
226    height=height/5.0;
[7014]227
[7467]228    model->addVertex(scaleX*(heightMap->h -i) + shiftX , ((double)(height)*scaleY) +shiftY ,scaleZ*(j) + shiftZ); // Top Right
229    model->addNormal(normalVectorField[i % heightMap->h][j % heightMap->w].y,normalVectorField[i % heightMap->h][j% heightMap->w].z,normalVectorField[i%heightMap->h][j%heightMap->w].x);
230    model->addTexCoor((float)j /(texRate), (float)(i %heightMap->h)/(texRate));
231    model->addColor(r/255.0,g/255.0,b/255.0);
[7014]232
[7467]233  }
[7014]234
235
236
[7467]237  for(int j = j1  ; j <= j2    ;  j += sampleRate)
238  {
239    int i = i2;
[7014]240
[7467]241    // To be fixed
242    if(hm->hasColourMap)
243    {
244      r = (float)colours[3*j+2 + 3*i*(heightMap->w )];
245      g = (float)colours[3*j+1 + 3*i*(heightMap->w)];
246      b = (float)colours[3*j+0 + 3*i*(heightMap->w)];
247    }
[7014]248
[7467]249    model->addVertex(scaleX*(heightMap->h -i) + shiftX , shiftY ,scaleZ*(j) + shiftZ); // Top Right
250    model->addNormal(normalVectorField[i%heightMap->h][j%heightMap->w].y,normalVectorField[i%heightMap->h][j%heightMap->w].z,normalVectorField[i%heightMap->h][j%heightMap->w].x);
251    model->addTexCoor((float)j /(texRate), (float)((i+ sampleRate) %heightMap->h)/(texRate));
252    model->addColor(r/255.0,g/255.0,b/255.0);
[7014]253
[7467]254  }
[7014]255
256
[7467]257  for(int j = j1 ; j <= j2    ;  j += sampleRate)
258  {
259    int i = i2;
260    height = (float)(unsigned char) hm->heights[(j +sampleRate+ i*(heightMap->w )) ];
261    height += (float)(unsigned char) hm->heights[(j+ 1 + sampleRate + (i+1)*(heightMap->w )) ];
262    height +=  (float) (unsigned char) hm->heights[(j -1+ sampleRate   + (i+1)*(heightMap->w ))];
263    height +=  (float)(unsigned char)hm->heights[(j +sampleRate+ (i+2)*(heightMap->w ))];
264    height +=  (float)(unsigned char)hm->heights[(j+sampleRate + (i)*(heightMap->w )) ];
265    height=height/5.0;
266    model->addVertex(scaleX*(heightMap->h -i) + shiftX , ((double)(height)*scaleY) +shiftY ,scaleZ*(j) + shiftZ); // Top Right
267    model->addNormal(normalVectorField[i%heightMap->h][j%heightMap->w].y,normalVectorField[i%heightMap->h][j%heightMap->w].z,normalVectorField[i%heightMap->h][j%heightMap->w].x);
268    model->addTexCoor((float)j /(texRate), (float)(i %heightMap->h)/(texRate));
269    model->addColor(r/255.0,g/255.0,b/255.0);
[7014]270
[7467]271  }
[7014]272
273
274
275
[7467]276  // link Boarder Stripe
277  for(int j = j1-sampleRate  ; j < j2    ;  j += sampleRate)
278  {
[7014]279
[7467]280    model->addIndice(cnt);
281    model->addIndice(cnt  + (j2 -j1 +  sampleRate  )/ sampleRate );
282    cnt++;
[7014]283
[7467]284  }
[7014]285
[7467]286  cnt++;
[7014]287
[7467]288  model->newStripe();
[7014]289
290
291
292
293
[7467]294  cnt += (j2-j1)/ sampleRate;
[7014]295
[7467]296  // link 2nd BoarderStripe
297  for(int j = j1-sampleRate  ; j < j2    ;  j += sampleRate)
298  {
[7014]299
[7467]300    model->addIndice(cnt);
301    model->addIndice(cnt  + (j2 -j1 +  sampleRate  )/ sampleRate );
302    cnt++;
[7014]303
[7467]304  }
[7014]305
306
[7467]307  SDL_UnlockSurface(hm->colourMap);
[7014]308
[7467]309  model->finalize();
[7014]310
311
312
313
[7467]314#undef heightMap
[7014]315        #undef colours
316        #undef scaleX
317        #undef scaleY
318        #undef scaleZ
319        #undef shiftX
320        #undef shiftY
321        #undef shiftZ
322        #undef normalVectorField
323
[5942]324}
325
[6956]326HeightMap::HeightMap()
[5967]327{
[6956]328}
329
[7221]330HeightMap::HeightMap(const std::string& height_map_name = "")
[7467]331    : VertexArrayModel()
[6956]332{
[7467]333  this->setClassID(CL_HEIGHT_MAP, "HeightMap");
334  heightMap =  IMG_Load(height_map_name.c_str());
335  if(heightMap!=NULL)
336  {
[6956]337
[7467]338    PRINTF(0)("loading Image %s\n", height_map_name.c_str());
339    PRINTF(0)("width : %i\n", heightMap->w);
340    PRINTF(0)("height : %i\n", heightMap->h);
341    PRINTF(0)("%i Byte(s) per Pixel \n", heightMap->format->BytesPerPixel);
342    PRINTF(0)("Rshift : %i\n", heightMap->format->Rshift);
343    PRINTF(0)("Bshift: %i\n", heightMap->format->Bshift);
344    PRINTF(0)("Gshift: %i\n", heightMap->format->Gshift);
345    PRINTF(0)("Rmask: %i\n", heightMap->format->Rmask);
346    PRINTF(0)("Gmask: %i\n", heightMap->format->Gmask);
347  }
[6956]348
[7467]349  else
350    PRINTF(4)("oops! couldn't load %s for some reason.\n", height_map_name.c_str());
[6956]351
[7014]352
[6956]353  generateNormalVectorField();
354
355  shiftX = 0;
356  shiftY = 0;
357  shiftZ = 0;
358
359}
360
[7221]361HeightMap::HeightMap(const std::string& height_map_name = NULL, const std::string& colour_map_name = NULL)
[7467]362    : VertexArrayModel()
[6956]363{
[7467]364  this->setClassID(CL_HEIGHT_MAP, "HeightMap");
[6956]365
[7467]366  heightMap =  IMG_Load(height_map_name.c_str());
367  if(heightMap!=NULL)
368  {
[6956]369
[7467]370    PRINTF(0)("loading Image %s\n", height_map_name.c_str());
371    PRINTF(0)("width : %i\n", heightMap->w);
372    PRINTF(0)("height : %i\n", heightMap->h);
373    PRINTF(0)("%i Byte(s) per Pixel \n", heightMap->format->BytesPerPixel);
374    PRINTF(0)("Rshift : %i\n", heightMap->format->Rshift);
375    PRINTF(0)("Bshift: %i\n", heightMap->format->Bshift);
376    PRINTF(0)("Gshift: %i\n", heightMap->format->Gshift);
377    PRINTF(0)("Rmask: %i\n", heightMap->format->Rmask);
378    PRINTF(0)("Gmask: %i\n", heightMap->format->Gmask);
379  }
[6956]380
[7467]381  else
382    PRINTF(4)("oops! couldn't load %s for some reason.\n", height_map_name.c_str());
[6956]383
384
[7467]385  generateNormalVectorField();
[6956]386
387  colourMap=NULL;
[7221]388  if(colour_map_name != "")
[6956]389  {
[7221]390    colourMap = IMG_Load(colour_map_name.c_str());
[6956]391  }
[7014]392
[6956]393  if(colourMap != NULL)
[7467]394  {
395    PRINTF(0)("loading Image %s\n", colour_map_name.c_str());
396    PRINTF(0)("width : %i\n", colourMap->w);
397    PRINTF(0)("height : %i\n", colourMap->h);
398    PRINTF(0)("%i Byte(s) per Pixel \n", colourMap->format->BytesPerPixel);
399    PRINTF(0)("Rshift : %i\n", colourMap->format->Rshift);
400    PRINTF(0)("Bshift: %i\n", colourMap->format->Bshift);
401    PRINTF(0)("Gshift: %i\n", colourMap->format->Gshift);
402    PRINTF(0)("Rmask: %i\n", colourMap->format->Rmask);
403    PRINTF(0)("Gmask: %i\n", colourMap->format->Gmask);
404  }
405  else
406    PRINTF(0)("oops! couldn't load colorMap for some reason.\n");
[6956]407
[7014]408
409
[6956]410  if(colourMap != NULL)
411  {
[7467]412    colours = (unsigned char *) colourMap->pixels;
413    hasColourMap = true;
[6956]414  }
[7467]415  else
416    hasColourMap = false;
[7014]417
418
[6956]419  heights  = (unsigned char*) heightMap->pixels;
420  shiftX = 0;
421  shiftY = 0;
422  shiftZ = 0;
[5967]423}
424
425
426HeightMap::~HeightMap()
427{
[7467]428  delete heightMap;
429  delete colourMap;
[6956]430
431
[7467]432  for(int i=0;i <    heightMap->h/tileSize ; i++)
433  {
434    for(int j = 0; j < heightMap->w/ tileSize; j++)
435    {
436      delete tiles [i][j];
437    }
438  }
439  for(int i=0;i <    heightMap->h/tileSize ; i++)
440    delete[] tiles[i];
441  delete[] tiles;
[6956]442
[7014]443
444
445
446
[7467]447  for(int i=0;i<heightMap->h;i++)
448    delete[] normalVectorField [i];
449  delete[] normalVectorField;
[6956]450
451
452
453
[7014]454
455
456
[5967]457}
458
[5942]459void HeightMap::load()
460{
[5993]461
[7467]462  //Create a Dynamicly sized 2D-Array for Tiles
463  tiles =  new Tile** [heightMap->h/tileSize];
464  for(int i=0;i <    heightMap->h/tileSize ; i++)
465    tiles [i]= new (Tile* [heightMap->w /tileSize ]);
[5967]466
[7467]467  //SetUp Arrays
468  for(int i = 0; i < (heightMap->)/ tileSize; i ++)
469  {
470    for(int j = 0; j < (heightMap->w )/ tileSize; j ++)
471    {
[7014]472
[7467]473      tiles[i][j] =    new Tile( i*tileSize ,  j*tileSize , (i+1)*tileSize, (j+1)*tileSize , this ) ;
474    }
475  }
[5980]476
[6956]477}
[5993]478
479
[7014]480void HeightMap::draw()
[6956]481{
[7467]482  const PNode* camera = State::getCameraNode();
483  Vector v = camera->getAbsCoor();
[6956]484
[7467]485  int i_min = 0;
486  int i_max = (heightMap->h )/ tileSize;
487  int j_min = 0;
488  int j_max= (heightMap->) / tileSize;
[6956]489
490
491
[7467]492  for(int i = 0; i <  i_max        ; i ++)
493  {
494    for(int j = 0; j < j_max ; j++)
495    {
496      tiles[i][j]->draw();
497    }
498  }
[5980]499
[6956]500}
501void HeightMap::generateNormalVectorField()
502{
[7467]503  int delta = 1;
504  heights  = (unsigned char*) heightMap->pixels;
[6956]505
[7467]506  //Create a Dynamicly sized 2D-Array to store our normals
507  normalVectorField =  new Vector* [heightMap->h];
508  for(int i=0;i<heightMap->h;i++)
509    normalVectorField [i]= new (Vector [heightMap->w]);
[6956]510
511
512
513
[7467]514  // Initialize
515  for(int i=0; i< heightMap->h; i++)
516  {
517    for(int j = 0; j> heightMap->w; j++)
518    {
519      Vector v = Vector(0.0, 1.0, 0.0);
520      normalVectorField[i][j] = v;
521    }
522  }
[5967]523
[7467]524  // !!! Does not yet calculate the normals of some border points!!!!!
[5990]525
[7467]526  if(heightMap != NULL && heightMap->format->BitsPerPixel == 8 )
527  {
528    SDL_LockSurface(heightMap);
529    for(int i = 0 ; i < heightMap->h - 1  ; i ++)
530    {
531      for(int j = 0; j < heightMap->- 1  ;  j ++)
532      {
[5942]533
534
[7467]535        delta = (int)heights[j + (i+1)*(heightMap->w )] -  (int) heights[j + i*(heightMap->w )];
536        Vector a =  Vector(-scaleX,(float)delta*scaleY  ,0.0f);
[5942]537
[7467]538        delta = (int)heights[j+1 + i*(heightMap->w )] - (int)heights[j + i*(heightMap->w )];
539        Vector b =  Vector(0.0f,(float) delta*scaleY ,scaleZ);
[5942]540
[6956]541
[7467]542        normalVectorField[i][j] = b.cross(a);
543        normalVectorField[i][j].normalize();
[5942]544
[7467]545      }
546    }
547    SDL_UnlockSurface(heightMap);
[7014]548
[7467]549  }
[5942]550
[6956]551
552
[7014]553
[5942]554}
[6956]555
556
557void HeightMap::scale(Vector v)
558{
[7467]559  scaleX = v.x;
560  scaleY = v.y;
561  scaleZ = v.z;
562  generateNormalVectorField();
[6956]563}
564
565void HeightMap::setAbsCoor(Vector v)
566{
[7467]567  offsetX = v.x;
568  offsetY = v.y;
569  offsetZ  = v.z;
[6956]570}
571
572
[7014]573float HeightMap::getHeight(float x, float y)
[6956]574{
575
[7467]576  x -= offsetX;
577  y -= offsetZ;
[7014]578
579
[7467]580  int xInt = (int)x / scaleX;
581  x -= (float)((int)x);
582  xInt = heightMap->h - xInt;
583  int yInt = (int)y / scaleZ;
584  y -= (float) ((int) y); /*yInt = heightMap->w - yInt;*/
[7014]585
[7467]586  //PRINTF(0)("xInt: %i, yInt: %i, x: %f, y: %f\n", xInt, yInt, x, y);
[7014]587
[7467]588  if(xInt <= 0 || xInt >= heightMap->h || yInt <= 0 || yInt >= heightMap->)
589    return 0;
590  if( y >= 0.5*x)
591  {
592    // Check for ...
593  }
[6956]594
[7467]595  float height = heights[yInt + (xInt)*heightMap->w]*scaleY;
[7014]596
597
[7467]598  float a = normalVectorField[(xInt)][yInt].x;
599  float b = normalVectorField [(xInt)][yInt].z;
600  float c = normalVectorField [(xInt)][yInt].y;
[7014]601
[7467]602  PRINTF(0)("a: %f \n" ,a);
[6956]603  PRINTF(0)("b: %f \n" ,b);
[7467]604  PRINTF(0)("c: %f \n" ,c);
[7014]605
[7467]606  height -= ( (a/c)*(x) + (b/c)*(y));
[7014]607
[7467]608  PRINTF(0)("height: %f \n" ,height );
609  return (height + offsetZ);
[6956]610}
Note: See TracBrowser for help on using the repository browser.