#include "scene.h" #include #include #include #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; }