/* model/vertexarray.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include "math/mathlib.h" #include "model/vertexarray.h" #include "sys/sys.h" namespace model { VertexArray *VertexArray::vertex_instance = 0 ; VertexArray::VertexArray(size_t size) { vertex_instance = this; vertex_size = size * 1024*1024; // megabytes vertex_size = vertex_size / sizeof(float); // sizeof float vertex_size = vertex_size / 3; // 3 arrays vertex_vertex = (float *) malloc(vertex_size * sizeof(float)); vertex_normal = (float *) malloc(vertex_size * sizeof(float)); vertex_texture = (float *) malloc(vertex_size * sizeof(float)); con_print << "^BInitializing vertex array..." << std::endl; con_print << " " << size << " Mb allocated" << std::endl; clear(); } VertexArray::~VertexArray() { free(vertex_vertex); free(vertex_normal); free(vertex_texture); vertex_instance = 0 ; } void VertexArray::clear() { vertex_index = 0; vertex_overflow = false; memset(vertex_vertex, 0, sizeof(vertex_vertex)); memset(vertex_normal, 0, sizeof(vertex_normal)); memset(vertex_texture, 0, sizeof(vertex_texture)); add_sphere(); } void VertexArray::add_sphere() { // load sphere vertices into the VertexArray // build sin/cos table float *sintable; float *costable; sintable = new float[SPHERESEGMENTS]; costable = new float[SPHERESEGMENTS]; float d = 2 * M_PI / (SPHERESEGMENTS-1); for (int i=0; i < SPHERESEGMENTS; i++) { sintable[i] = sin(d * (float) i); costable[i] = cos(d * (float) i); } // draw body math::Vector3f v; math::Vector3f n; float texx, texy; int quad_count = 0; // add sphere for (int j=0; j < (SPHERESEGMENTS-1) / 2; j++) { float r = sintable[j]; float r1 = sintable[j+1]; for (int i = 0; i < SPHERESEGMENTS; i++) { v = math::Vector3f(r*costable[i], r*sintable[i], costable[j]); n = v; n.normalize(); texx = (float)i/(float)(SPHERESEGMENTS-1); texy = -costable[j]/2 + 0.5f; add_vertex(v, n, texx, texy); v = math::Vector3f(r1*costable[i], r1*sintable[i], costable[j+1]); n = v; n.normalize(); texx = (float)i/(float)(SPHERESEGMENTS-1); texy = -costable[j+1]/2 + 0.5f; add_vertex(v, n, texx, texy); quad_count++; } quad_count--; } // add inside-out sphere for (int j=0; j < (SPHERESEGMENTS-1) / 2; j++) { float r = sintable[j]; float r1 = sintable[j+1]; for (int i = SPHERESEGMENTS -1 ; i >= 0; i--) { v = math::Vector3f(r*costable[i], r*sintable[i], costable[j]); n = v; n.normalize(); texx = 1-(float)i/(float)(SPHERESEGMENTS-1); texy = -costable[j]/2 + 0.5f; add_vertex(v, n, texx, texy); v = math::Vector3f(r1*costable[i], r1*sintable[i], costable[j+1]); n = v; n.normalize(); texx = 1-(float)i/(float)(SPHERESEGMENTS-1); texy = -costable[j+1]/2 + 0.5f; add_vertex(v, n, texx, texy); } } delete[] sintable; delete[] costable; } size_t VertexArray::add_vertex(math::Vector3f const &v, math::Vector3f const &n, float tex_x, float tex_y) { if (vertex_index + 3 >= vertex_size) { if (!vertex_overflow) { con_warn << "VertexArray overflow!" << std::endl; vertex_overflow = true; } return 0; } for (int i = 0; i < 3; i ++) { vertex_vertex[vertex_index+i] = v[i]; vertex_normal[vertex_index+i] = n[i]; } vertex_texture[vertex_index] = tex_x; vertex_texture[vertex_index+1] = tex_y; vertex_texture[vertex_index+2] = 0; vertex_index += 3; return 1; } }