1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#include "scene.h"
#include <SDL_image.h>
#include <SDL_opengl.h>
#include <cmath>
#define inrange(a, b, c) ((a) >= (b) && (a) <= (c))
Scene::Scene() {
SDL_Surface *hm = IMG_Load("heightmap10.png");
float *heightmap = new float[hm->w * hm->h];
for(int x = 0; x < hm->w; x++) {
for(int y = 0; y < hm->h; y++) {
Uint8 *p = (Uint8*)hm->pixels + y * hm->pitch + x * hm->format->BytesPerPixel;
heightmap[y*hm->w + x] = ((float)(*p) / 256) * 20;
}
}
int w = hm->w;
int h = hm->h;
SDL_FreeSurface(hm);
qt = new Quadtree(w, h, heightmap, 3);
}
Scene::~Scene() {
if(qt)
delete qt;
}
void Scene::lookat() {
/* calculate cartesian coordinates for the center vector where yaw is Φ and pitch is θ
* x = cos Φ sin θ
* y = cos θ
* z = sin Φ sin θ
*/
Vector3 center(sinf(pitch) * cosf(yaw), cosf(pitch), sinf(pitch) * sinf(yaw));
center += pos;
center.y += 1;
//Vector3 up(cosf(yaw) * cosf(pitch), sinf(pitch), sinf(yaw) * cosf(pitch));
Vector3 up(-cosf(pitch) * cosf(yaw), sinf(pitch), -cosf(pitch) * sinf(yaw));
gluLookAt(pos.x, pos.y+1, pos.z,
center.x, center.y, center.z,
up.x, up.y, up.z);
}
void Scene::move(float forward, float right, int steps) {
Vector2 dir;
dir.x += forward*cosf(yaw);
dir.y += forward*sinf(yaw);
dir.x += right*cosf(yaw+M_PI_2);
dir.y += right*sinf(yaw+M_PI_2);
// ensure that the vector length is 1.0
dir /= dir.length();
dir *= 0.005;
dir *= steps;
float x = pos.x + dir.x;
//if(inrange(x, -2, 2))
pos.x = x;
float z = pos.z + dir.y;
//if(inrange(z, -2, 2))
pos.z = z;
//pos.x += dir.x;
//pos.z += dir.y;
}
bool Scene::select(int x, int y, float& px, float& py, float& pz) {
GLint view[4] = {0};
GLdouble mvmatrix[16] = {0}, projmatrix[16] = {0};
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
glGetIntegerv(GL_VIEWPORT, view);
y = view[3] - y - 1;
float z;
glReadBuffer(GL_BACK);
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
GLdouble _px, _py, _pz;
if(gluUnProject(x, y, z, mvmatrix, projmatrix, view, &_px, &_py, &_pz) == GLU_TRUE) {
px = _px;
py = _py;
pz = _pz;
return true;
}
return false;
}
|