From 6fdbdea4e65b75ac9ebda91320deb656655d3af5 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Wed, 1 Jun 2011 19:31:19 +0200 Subject: A bunch of network-related changes. --- terrain.cpp | 107 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 40 deletions(-) (limited to 'terrain.cpp') diff --git a/terrain.cpp b/terrain.cpp index f3f573d..4035a89 100644 --- a/terrain.cpp +++ b/terrain.cpp @@ -47,19 +47,19 @@ float Terrain::Node::distance(float px, float pz) { void Terrain::Node::fill() { vertex_array[0] = x; - vertex_array[1] = chunk->heights[(int)floorf((x)*(chunk->h_height)+y)]; + vertex_array[1] = chunk->heights[(int)floorf((x + 1)*(chunk->h_height) + (y + 1))]; vertex_array[2] = y; vertex_array[3] = x; - vertex_array[4] = chunk->heights[(int)floorf((x)*(chunk->h_height) + (y + 1))]; + vertex_array[4] = chunk->heights[(int)floorf((x + 1)*(chunk->h_height) + (y + 2))]; vertex_array[5] = y + 1; vertex_array[6] = x + 1; - vertex_array[7] = chunk->heights[(int)floorf((x + 1)*(chunk->h_height) + (y + 1))]; + vertex_array[7] = chunk->heights[(int)floorf((x + 2)*(chunk->h_height) + (y + 2))]; vertex_array[8] = y + 1; vertex_array[9] = x + 1; - vertex_array[10] = chunk->heights[(int)floorf((x + 1)*(chunk->h_height) + y)]; + vertex_array[10] = chunk->heights[(int)floorf((x + 2)*(chunk->h_height) + (y + 1))]; vertex_array[11] = y; } @@ -92,11 +92,12 @@ void Terrain::Node::draw_grid() { void Terrain::Node::draw_normal() { glNormal3f(0, 1, 0); glColor3f(1, 0, 0); - int i = (int)(x*(chunk->h_height) + y); + int i = (int)(x*(chunk->n_height) + y); + int i2 = (int)((x + 1) * (chunk->h_height) + (y + 1)); glBegin(GL_LINES); Vector3 N = chunk->normals[i]; - glVertex3f(chunk->x + x, chunk->heights[i], chunk->y + y); - glVertex3f(chunk->x + x + N.x, chunk->heights[i] + N.y, chunk->y + y + N.z); + glVertex3f(chunk->x + x, chunk->heights[i2], chunk->y + y); + glVertex3f(chunk->x + x + N.x, chunk->heights[i2] + N.y, chunk->y + y + N.z); glEnd(); } @@ -119,18 +120,21 @@ float Terrain::Node::get_height(float px, float py) { /* Chunk */ -Terrain::Chunk::Chunk(Terrain *terrain, float x, float y, float width, float height) : cache_obj(terrain->tc->get_chunk(x, y, width+1, height+1)) { +Terrain::Chunk::Chunk(Terrain *terrain, float x, float y) : cache_obj(terrain->tc->get_chunk(x, y, Terrain::chunk_size_total, Terrain::chunk_size_total)) { this->terrain = terrain; this->x = x; this->y = y; - this->width = width; - this->height = height; - this->h_width = width+1; - this->h_height = height+1; + this->width = Terrain::chunk_size; + this->height = Terrain::chunk_size; + this->h_width = Terrain::chunk_size_total; + this->h_height = Terrain::chunk_size_total; + this->n_width = width+1; + this->n_height = height+1; this->vbo_object = this->node_count = this->vertices = 0; this->nodes = NULL; + this->need_normals = true; heights = cache_obj->heights; - normals = new Vector3[(int)((h_width)*(h_height))]; + normals = new Vector3[(int)((n_width)*(n_height))]; calc_normals(); @@ -141,7 +145,9 @@ Terrain::Chunk::Chunk(Terrain *terrain, float x, float y, float width, float hei nodes[j*(int)height + i] = new Node(this, j, i); } } - make_vbo(); + + if(!need_normals) + make_vbo(); } Terrain::Chunk::~Chunk() { @@ -236,10 +242,10 @@ void Terrain::Chunk::make_vbo() { float *n = buffer + vertices_size + normal_chunk_size*index; - Vector3 bl = normals[(int)((node->x+1)*(h_height) + node->y)]; - Vector3 br = normals[(int)((node->x)*(h_height) + node->y)]; - Vector3 tr = normals[(int)((node->x)*(h_height) + node->y+1)]; - Vector3 tl = normals[(int)((node->x+1)*(h_height) + node->y+1)]; + Vector3 bl = normals[(int)((node->x+1)*(n_height) + node->y)]; + Vector3 br = normals[(int)((node->x)*(n_height) + node->y)]; + Vector3 tr = normals[(int)((node->x)*(n_height) + node->y+1)]; + Vector3 tl = normals[(int)((node->x+1)*(n_height) + node->y+1)]; n[0] = n[9] = br.x; n[1] = n[10] = br.y; @@ -271,7 +277,7 @@ Terrain::Node* Terrain::Chunk::find(float x, float y) { void Terrain::Chunk::calc_normals() { float *right, *left, *up, *down; - TerrainCacheObject::p right_ob = terrain->tc->get_chunk(this->x - chunk_size, this->y, h_width, h_height), + /*TerrainCacheObject::p right_ob = terrain->tc->get_chunk(this->x - chunk_size, this->y, h_width, h_height), left_ob = terrain->tc->get_chunk(this->x + chunk_size, this->y, h_width, h_height), up_ob = terrain->tc->get_chunk(this->x, this->y + chunk_size, h_width, h_height), down_ob = terrain->tc->get_chunk(this->x, this->y - chunk_size, h_width, h_height); @@ -279,68 +285,75 @@ void Terrain::Chunk::calc_normals() { right = right_ob->heights; left = left_ob->heights; up = up_ob->heights; - down = down_ob->heights; + down = down_ob->heights;*/ + + if(!right || !left || !up || !down) { + need_normals = true; + return; + } - for(int x = 0; x < h_width; x++) { - for(int y = 0; y < h_height; y++) { + for(int x = 1; x < h_width-1; x++) { + for(int y = 1; y < h_height-1; y++) { Vector3 p(x, heights[x*h_height + y], y); Vector3 N, U, V; float h; // right - if(x == 0) + /*if(x == 0) h = right[(chunk_size-1)*(int)(h_height) + y]; - else + else*/ h = heights[(x-1)*h_height + y]; U = Vector3(x-1, h, y) - p; // down - if(y == 0) + /*if(y == 0) h = down[x*(int)(h_height) + chunk_size - 1]; - else + else*/ h = heights[x*h_height + y - 1]; V = Vector3(x, h, y-1) - p; N += V.cross(U); // up - if(y == h_height-1) + /*if(y == h_height-1) h = up[x*(int)(h_height) + 1]; // y == 1 - else + else*/ h = heights[x*h_height + y + 1]; V = Vector3(x, h, y+1) - p; N += U.cross(V); // left - if(x == h_width-1) + /*if(x == h_width-1) h = left[h_height + y]; // x == 1 - else + else*/ h = heights[(x+1)*h_height + y]; U = Vector3(x+1, h, y) - p; //down - if(y == 0) + /*if(y == 0) h = down[x*(int)(h_height) + chunk_size - 1]; - else + else*/ h = heights[x*h_height + y - 1]; V = Vector3(x, h, y-1) - p; N += U.cross(V); // up - if(y == h_height-1) + /*if(y == h_height-1) h = up[x*(int)(h_height) + 1]; // y == 1 - else + else*/ h = heights[x*h_height + y + 1]; V = Vector3(x, h, y+1) - p; N += V.cross(U); N /= N.length(); - normals[x*h_height + y] = N; + normals[(x-1)*n_height + y - 1] = N; } } + + need_normals = false; } Terrain::Terrain() { - tc = new TerrainCache(0, "map", 120); + tc = new TerrainCache("map", 120); } Terrain::~Terrain() { @@ -351,6 +364,7 @@ Terrain::~Terrain() { } void Terrain::raise(float x, float z, float radius, float focus, float strength, bool up) { + // TODO: fix // TODO: fix setting heights on unloaded chunks std::set changed_chunks; @@ -441,19 +455,32 @@ void Terrain::update(float x, float z) { chunk_indices.insert(std::pair(i, j)); } } + for(std::list::iterator it = chunks.begin(); it != chunks.end(); it++) { - std::set >::iterator ind_it = chunk_indices.find(std::pair((*it)->x, (*it)->y)); + Chunk *chunk = *it; + std::set >::iterator ind_it = chunk_indices.find(std::pair(chunk->x, chunk->y)); if(ind_it != chunk_indices.end()) { chunk_indices.erase(ind_it); } - if((*it)->distance(x, z) > chunk_dist_threshold) { + if(chunk->distance(x, z) > chunk_dist_threshold) { delete *it; it = chunks.erase(it); + } else if((*it)->need_normals) { + chunk->calc_normals(); + chunk->make_vbo(); } } + for(std::set >::iterator it = chunk_indices.begin(); it != chunk_indices.end(); it++) { - Chunk *chunk = new Chunk(this, it->first, it->second, chunk_size, chunk_size); - chunks.push_back(chunk); + if(tc->tl->has_chunk(it->first, it->second)) { + Chunk *chunk = NULL; + try { + chunk = new Chunk(this, it->first, it->second); + } catch(...) { + } + if(chunk) + chunks.push_back(chunk); + } } } -- cgit v1.2.3