Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox: reading through the code and adjusting here and there, whatever dropps in to my eye

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