summaryrefslogtreecommitdiff
path: root/scene.cpp
blob: c477345be5a724fdc47b8c8a6004b83df6d9ddb6 (plain)
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;
}