goat3d
diff src/mesh.cc @ 8:cd71f0b92f44
a bit more...
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 21 Aug 2013 05:52:28 +0300 |
parents | e46529a5d057 |
children | f1b4c27382ce |
line diff
1.1 --- a/src/mesh.cc Wed Aug 21 04:00:22 2013 +0300 1.2 +++ b/src/mesh.cc Wed Aug 21 05:52:28 2013 +0300 1.3 @@ -1,973 +1,23 @@ 1.4 -#include <stdio.h> 1.5 -#include <stdlib.h> 1.6 -#include <float.h> 1.7 -#include <assert.h> 1.8 -#include "opengl.h" 1.9 #include "mesh.h" 1.10 -#include "xform_node.h" 1.11 -//#include "logger.h" 1.12 - 1.13 -int Mesh::global_sdr_loc[NUM_MESH_ATTR] = { 0, 1, 2, 3, 4, 5 }; 1.14 -unsigned int Mesh::intersect_mode = ISECT_DEFAULT; 1.15 -float Mesh::vertex_sel_dist = 0.01; 1.16 -float Mesh::vis_vecsize = 1.0; 1.17 1.18 Mesh::Mesh() 1.19 { 1.20 - clear(); 1.21 - 1.22 - glGenBuffers(NUM_MESH_ATTR + 1, buffer_objects); 1.23 - 1.24 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.25 - vattr[i].vbo = buffer_objects[i]; 1.26 - } 1.27 - ibo = buffer_objects[NUM_MESH_ATTR]; 1.28 - wire_ibo = 0; 1.29 + material = 0; 1.30 } 1.31 1.32 -Mesh::~Mesh() 1.33 +Mesh::~Mesh() {} 1.34 + 1.35 +void Mesh::set_material(Material *mat) 1.36 { 1.37 - glDeleteBuffers(NUM_MESH_ATTR + 1, buffer_objects); 1.38 - 1.39 - if(wire_ibo) { 1.40 - glDeleteBuffers(1, &wire_ibo); 1.41 - } 1.42 + material = mat; 1.43 } 1.44 1.45 -void Mesh::set_name(const char *name) 1.46 +Material *Mesh::get_material() 1.47 { 1.48 - this->name = name; 1.49 + return material; 1.50 } 1.51 1.52 -const char *Mesh::get_name() const 1.53 +const Material *Mesh::get_material() const 1.54 { 1.55 - return name.c_str(); 1.56 + return material; 1.57 } 1.58 - 1.59 -bool Mesh::has_attrib(int attr) const 1.60 -{ 1.61 - if(attr < 0 || attr >= NUM_MESH_ATTR) { 1.62 - return false; 1.63 - } 1.64 - 1.65 - // if neither of these is valid, then nobody has set this attribute 1.66 - return vattr[attr].vbo_valid || vattr[attr].data_valid; 1.67 -} 1.68 - 1.69 -void Mesh::clear() 1.70 -{ 1.71 - bones.clear(); 1.72 - 1.73 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.74 - vattr[i].nelem = 0; 1.75 - vattr[i].vbo_valid = false; 1.76 - vattr[i].data_valid = false; 1.77 - //vattr[i].sdr_loc = -1; 1.78 - vattr[i].data.clear(); 1.79 - } 1.80 - ibo_valid = false; 1.81 - idata.clear(); 1.82 - 1.83 - wire_ibo_valid = false; 1.84 - 1.85 - nverts = nfaces = 0; 1.86 - 1.87 - /*bsph_valid = false; 1.88 - aabb_valid = false;*/ 1.89 -} 1.90 - 1.91 -float *Mesh::set_attrib_data(int attrib, int nelem, unsigned int num, const float *data) 1.92 -{ 1.93 - if(attrib < 0 || attrib >= NUM_MESH_ATTR) { 1.94 - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); 1.95 - return 0; 1.96 - } 1.97 - 1.98 - if(nverts && num != nverts) { 1.99 - fprintf(stderr, "%s: attribute count missmatch (%d instead of %d)\n", __FUNCTION__, num, nverts); 1.100 - return 0; 1.101 - } 1.102 - nverts = num; 1.103 - 1.104 - vattr[attrib].data.clear(); 1.105 - vattr[attrib].nelem = nelem; 1.106 - vattr[attrib].data.resize(num * nelem); 1.107 - 1.108 - if(data) { 1.109 - memcpy(&vattr[attrib].data[0], data, num * nelem * sizeof *data); 1.110 - } 1.111 - 1.112 - vattr[attrib].data_valid = true; 1.113 - vattr[attrib].vbo_valid = false; 1.114 - return &vattr[attrib].data[0]; 1.115 -} 1.116 - 1.117 -float *Mesh::get_attrib_data(int attrib) 1.118 -{ 1.119 - if(attrib < 0 || attrib >= NUM_MESH_ATTR) { 1.120 - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); 1.121 - return 0; 1.122 - } 1.123 - 1.124 - vattr[attrib].vbo_valid = false; 1.125 - return (float*)((const Mesh*)this)->get_attrib_data(attrib); 1.126 -} 1.127 - 1.128 -const float *Mesh::get_attrib_data(int attrib) const 1.129 -{ 1.130 - if(attrib < 0 || attrib >= NUM_MESH_ATTR) { 1.131 - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); 1.132 - return 0; 1.133 - } 1.134 - 1.135 - if(!vattr[attrib].data_valid) { 1.136 -#if GL_ES_VERSION_2_0 1.137 - fprintf(stderr, "%s: can't read back attrib data on CrippledGL ES\n", __FUNCTION__); 1.138 - return 0; 1.139 -#else 1.140 - if(!vattr[attrib].vbo_valid) { 1.141 - fprintf(stderr, "%s: unavailable attrib: %d\n", __FUNCTION__, attrib); 1.142 - return 0; 1.143 - } 1.144 - 1.145 - // local data copy is unavailable, grab the data from the vbo 1.146 - Mesh *m = (Mesh*)this; 1.147 - m->vattr[attrib].data.resize(nverts * vattr[attrib].nelem); 1.148 - 1.149 - glBindBuffer(GL_ARRAY_BUFFER, vattr[attrib].vbo); 1.150 - void *data = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); 1.151 - memcpy(&m->vattr[attrib].data[0], data, nverts * vattr[attrib].nelem * sizeof(float)); 1.152 - glUnmapBuffer(GL_ARRAY_BUFFER); 1.153 - 1.154 - vattr[attrib].data_valid = true; 1.155 -#endif 1.156 - } 1.157 - 1.158 - return &vattr[attrib].data[0]; 1.159 -} 1.160 - 1.161 -void Mesh::set_attrib(int attrib, int idx, const Vector4 &v) 1.162 -{ 1.163 - float *data = get_attrib_data(attrib); 1.164 - if(data) { 1.165 - data += idx * vattr[attrib].nelem; 1.166 - for(int i=0; i<vattr[attrib].nelem; i++) { 1.167 - data[i] = v[i]; 1.168 - } 1.169 - } 1.170 -} 1.171 - 1.172 -Vector4 Mesh::get_attrib(int attrib, int idx) const 1.173 -{ 1.174 - Vector4 v(0.0, 0.0, 0.0, 1.0); 1.175 - const float *data = get_attrib_data(attrib); 1.176 - if(data) { 1.177 - data += idx * vattr[attrib].nelem; 1.178 - for(int i=0; i<vattr[attrib].nelem; i++) { 1.179 - v[i] = data[i]; 1.180 - } 1.181 - } 1.182 - return v; 1.183 -} 1.184 - 1.185 -unsigned int *Mesh::set_index_data(int num, const unsigned int *indices) 1.186 -{ 1.187 - int nidx = nfaces * 3; 1.188 - if(nidx && num != nidx) { 1.189 - fprintf(stderr, "%s: index count missmatch (%d instead of %d)\n", __FUNCTION__, num, nidx); 1.190 - return 0; 1.191 - } 1.192 - nfaces = num / 3; 1.193 - 1.194 - idata.clear(); 1.195 - idata.resize(num); 1.196 - 1.197 - if(indices) { 1.198 - memcpy(&idata[0], indices, num * sizeof *indices); 1.199 - } 1.200 - 1.201 - idata_valid = true; 1.202 - ibo_valid = false; 1.203 - 1.204 - return &idata[0]; 1.205 -} 1.206 - 1.207 -unsigned int *Mesh::get_index_data() 1.208 -{ 1.209 - ibo_valid = false; 1.210 - return (unsigned int*)((const Mesh*)this)->get_index_data(); 1.211 -} 1.212 - 1.213 -const unsigned int *Mesh::get_index_data() const 1.214 -{ 1.215 - if(!idata_valid) { 1.216 -#if GL_ES_VERSION_2_0 1.217 - fprintf(stderr, "%s: can't read back index data in CrippledGL ES\n", __FUNCTION__); 1.218 - return 0; 1.219 -#else 1.220 - if(!ibo_valid) { 1.221 - fprintf(stderr, "%s: indices unavailable\n", __FUNCTION__); 1.222 - return 0; 1.223 - } 1.224 - 1.225 - // local data copy is unavailable, gram the data from the ibo 1.226 - Mesh *m = (Mesh*)this; 1.227 - int nidx = nfaces * 3; 1.228 - m->idata.resize(nidx); 1.229 - 1.230 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 1.231 - void *data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); 1.232 - memcpy(&m->idata[0], data, nidx * sizeof(unsigned int)); 1.233 - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); 1.234 - 1.235 - idata_valid = true; 1.236 -#endif 1.237 - } 1.238 - 1.239 - return &idata[0]; 1.240 -} 1.241 - 1.242 -void Mesh::append(const Mesh &mesh) 1.243 -{ 1.244 - unsigned int idxoffs = nverts; 1.245 - 1.246 - nverts += mesh.nverts; 1.247 - nfaces += mesh.nfaces; 1.248 - 1.249 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.250 - if(has_attrib(i) && mesh.has_attrib(i)) { 1.251 - // force validating the data arrays 1.252 - get_attrib_data(i); 1.253 - mesh.get_attrib_data(i); 1.254 - 1.255 - // append the mesh data 1.256 - vattr[i].data.insert(vattr[i].data.end(), mesh.vattr[i].data.begin(), mesh.vattr[i].data.end()); 1.257 - } 1.258 - } 1.259 - 1.260 - if(ibo_valid || idata_valid) { 1.261 - // make index arrays valid 1.262 - get_index_data(); 1.263 - mesh.get_index_data(); 1.264 - 1.265 - size_t orig_sz = idata.size(); 1.266 - 1.267 - idata.insert(idata.end(), mesh.idata.begin(), mesh.idata.end()); 1.268 - 1.269 - // fixup all the new indices 1.270 - for(size_t i=orig_sz; i<idata.size(); i++) { 1.271 - idata[i] += idxoffs; 1.272 - } 1.273 - } 1.274 - 1.275 - // fuck everything 1.276 - wire_ibo_valid = false; 1.277 - /*aabb_valid = false; 1.278 - bsph_valid = false;*/ 1.279 -} 1.280 - 1.281 -// assemble a complete vertex by adding all the useful attributes 1.282 -void Mesh::vertex(float x, float y, float z) 1.283 -{ 1.284 - cur_val[MESH_ATTR_VERTEX] = Vector4(x, y, z, 1.0f); 1.285 - vattr[MESH_ATTR_VERTEX].data_valid = true; 1.286 - vattr[MESH_ATTR_VERTEX].nelem = 3; 1.287 - 1.288 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.289 - if(vattr[i].data_valid) { 1.290 - for(int j=0; j<vattr[MESH_ATTR_VERTEX].nelem; j++) { 1.291 - vattr[i].data.push_back(cur_val[i][j]); 1.292 - } 1.293 - } 1.294 - vattr[i].vbo_valid = false; 1.295 - } 1.296 - 1.297 - if(idata_valid) { 1.298 - idata.clear(); 1.299 - } 1.300 - ibo_valid = idata_valid = false; 1.301 -} 1.302 - 1.303 -void Mesh::normal(float nx, float ny, float nz) 1.304 -{ 1.305 - cur_val[MESH_ATTR_NORMAL] = Vector4(nx, ny, nz, 1.0f); 1.306 - vattr[MESH_ATTR_NORMAL].data_valid = true; 1.307 - vattr[MESH_ATTR_NORMAL].nelem = 3; 1.308 -} 1.309 - 1.310 -void Mesh::tangent(float tx, float ty, float tz) 1.311 -{ 1.312 - cur_val[MESH_ATTR_TANGENT] = Vector4(tx, ty, tz, 1.0f); 1.313 - vattr[MESH_ATTR_TANGENT].data_valid = true; 1.314 - vattr[MESH_ATTR_TANGENT].nelem = 3; 1.315 -} 1.316 - 1.317 -void Mesh::texcoord(float u, float v, float w) 1.318 -{ 1.319 - cur_val[MESH_ATTR_TEXCOORD] = Vector4(u, v, w, 1.0f); 1.320 - vattr[MESH_ATTR_TEXCOORD].data_valid = true; 1.321 - vattr[MESH_ATTR_TEXCOORD].nelem = 3; 1.322 -} 1.323 - 1.324 -void Mesh::boneweights(float w1, float w2, float w3, float w4) 1.325 -{ 1.326 - cur_val[MESH_ATTR_BONEWEIGHTS] = Vector4(w1, w2, w3, w4); 1.327 - vattr[MESH_ATTR_BONEWEIGHTS].data_valid = true; 1.328 - vattr[MESH_ATTR_BONEWEIGHTS].nelem = 4; 1.329 -} 1.330 - 1.331 -void Mesh::boneidx(int idx1, int idx2, int idx3, int idx4) 1.332 -{ 1.333 - cur_val[MESH_ATTR_BONEIDX] = Vector4(idx1, idx2, idx3, idx4); 1.334 - vattr[MESH_ATTR_BONEIDX].data_valid = true; 1.335 - vattr[MESH_ATTR_BONEIDX].nelem = 4; 1.336 -} 1.337 - 1.338 -/// static function 1.339 -void Mesh::set_attrib_location(int attr, int loc) 1.340 -{ 1.341 - if(attr < 0 || attr >= NUM_MESH_ATTR) { 1.342 - return; 1.343 - } 1.344 - Mesh::global_sdr_loc[attr] = loc; 1.345 -} 1.346 - 1.347 -/// static function 1.348 -int Mesh::get_attrib_location(int attr) 1.349 -{ 1.350 - if(attr < 0 || attr >= NUM_MESH_ATTR) { 1.351 - return -1; 1.352 - } 1.353 - return Mesh::global_sdr_loc[attr]; 1.354 -} 1.355 - 1.356 -/// static function 1.357 -void Mesh::clear_attrib_locations() 1.358 -{ 1.359 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.360 - Mesh::global_sdr_loc[i] = -1; 1.361 - } 1.362 -} 1.363 - 1.364 -/// static function 1.365 -void Mesh::set_vis_vecsize(float sz) 1.366 -{ 1.367 - Mesh::vis_vecsize = sz; 1.368 -} 1.369 - 1.370 -float Mesh::get_vis_vecsize() 1.371 -{ 1.372 - return Mesh::vis_vecsize; 1.373 -} 1.374 - 1.375 -void Mesh::apply_xform(const Matrix4x4 &xform) 1.376 -{ 1.377 - Matrix4x4 dir_xform = xform; 1.378 - dir_xform[0][3] = dir_xform[1][3] = dir_xform[2][3] = 0.0f; 1.379 - dir_xform[3][0] = dir_xform[3][1] = dir_xform[3][2] = 0.0f; 1.380 - dir_xform[3][3] = 1.0f; 1.381 - 1.382 - apply_xform(xform, dir_xform); 1.383 -} 1.384 - 1.385 -void Mesh::apply_xform(const Matrix4x4 &xform, const Matrix4x4 &dir_xform) 1.386 -{ 1.387 - for(unsigned int i=0; i<nverts; i++) { 1.388 - Vector4 v = get_attrib(MESH_ATTR_VERTEX, i); 1.389 - set_attrib(MESH_ATTR_VERTEX, i, v.transformed(xform)); 1.390 - 1.391 - if(has_attrib(MESH_ATTR_NORMAL)) { 1.392 - Vector3 n = get_attrib(MESH_ATTR_NORMAL, i); 1.393 - set_attrib(MESH_ATTR_NORMAL, i, n.transformed(dir_xform)); 1.394 - } 1.395 - if(has_attrib(MESH_ATTR_TANGENT)) { 1.396 - Vector3 t = get_attrib(MESH_ATTR_TANGENT, i); 1.397 - set_attrib(MESH_ATTR_TANGENT, i, t.transformed(dir_xform)); 1.398 - } 1.399 - } 1.400 -} 1.401 - 1.402 -int Mesh::add_bone(XFormNode *bone) 1.403 -{ 1.404 - int idx = bones.size(); 1.405 - bones.push_back(bone); 1.406 - return idx; 1.407 -} 1.408 - 1.409 -const XFormNode *Mesh::get_bone(int idx) const 1.410 -{ 1.411 - if(idx < 0 || idx >= (int)bones.size()) { 1.412 - return 0; 1.413 - } 1.414 - return bones[idx]; 1.415 -} 1.416 - 1.417 -int Mesh::get_bones_count() const 1.418 -{ 1.419 - return (int)bones.size(); 1.420 -} 1.421 - 1.422 -void Mesh::draw() const 1.423 -{ 1.424 - ((Mesh*)this)->update_buffers(); 1.425 - 1.426 - if(!vattr[MESH_ATTR_VERTEX].vbo_valid) { 1.427 - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); 1.428 - return; 1.429 - } 1.430 - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { 1.431 - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); 1.432 - return; 1.433 - } 1.434 - 1.435 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.436 - int loc = global_sdr_loc[i]; 1.437 - if(loc >= 0 && vattr[i].vbo_valid) { 1.438 - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); 1.439 - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); 1.440 - glEnableVertexAttribArray(loc); 1.441 - } 1.442 - } 1.443 - glBindBuffer(GL_ARRAY_BUFFER, 0); 1.444 - 1.445 - if(ibo_valid) { 1.446 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 1.447 - glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0); 1.448 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1.449 - } else { 1.450 - glDrawArrays(GL_TRIANGLES, 0, nverts); 1.451 - } 1.452 - 1.453 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.454 - int loc = global_sdr_loc[i]; 1.455 - if(loc >= 0 && vattr[i].vbo_valid) { 1.456 - glDisableVertexAttribArray(loc); 1.457 - } 1.458 - } 1.459 -} 1.460 - 1.461 -void Mesh::draw_wire() const 1.462 -{ 1.463 - ((Mesh*)this)->update_wire_ibo(); 1.464 - 1.465 - if(!vattr[MESH_ATTR_VERTEX].vbo_valid || !wire_ibo_valid) { 1.466 - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); 1.467 - return; 1.468 - } 1.469 - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { 1.470 - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); 1.471 - return; 1.472 - } 1.473 - 1.474 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.475 - int loc = global_sdr_loc[i]; 1.476 - if(loc >= 0 && vattr[i].vbo_valid) { 1.477 - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); 1.478 - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); 1.479 - glEnableVertexAttribArray(loc); 1.480 - } 1.481 - } 1.482 - glBindBuffer(GL_ARRAY_BUFFER, 0); 1.483 - 1.484 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wire_ibo); 1.485 - glDrawElements(GL_LINES, nfaces * 6, GL_UNSIGNED_INT, 0); 1.486 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1.487 - 1.488 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.489 - int loc = global_sdr_loc[i]; 1.490 - if(loc >= 0 && vattr[i].vbo_valid) { 1.491 - glDisableVertexAttribArray(loc); 1.492 - } 1.493 - } 1.494 -} 1.495 - 1.496 -void Mesh::draw_vertices() const 1.497 -{ 1.498 - ((Mesh*)this)->update_buffers(); 1.499 - 1.500 - if(!vattr[MESH_ATTR_VERTEX].vbo_valid) { 1.501 - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); 1.502 - return; 1.503 - } 1.504 - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { 1.505 - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); 1.506 - return; 1.507 - } 1.508 - 1.509 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.510 - int loc = global_sdr_loc[i]; 1.511 - if(loc >= 0 && vattr[i].vbo_valid) { 1.512 - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); 1.513 - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); 1.514 - glEnableVertexAttribArray(loc); 1.515 - } 1.516 - } 1.517 - glBindBuffer(GL_ARRAY_BUFFER, 0); 1.518 - 1.519 - glDrawArrays(GL_POINTS, 0, nverts); 1.520 - 1.521 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.522 - int loc = global_sdr_loc[i]; 1.523 - if(loc >= 0 && vattr[i].vbo_valid) { 1.524 - glDisableVertexAttribArray(loc); 1.525 - } 1.526 - } 1.527 -} 1.528 - 1.529 -void Mesh::draw_normals() const 1.530 -{ 1.531 -#ifdef USE_OLDGL 1.532 - int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX]; 1.533 - Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX); 1.534 - Vector3 *norm = (Vector3*)get_attrib_data(MESH_ATTR_NORMAL); 1.535 - 1.536 - if(!varr || !norm || vert_loc < 0) { 1.537 - return; 1.538 - } 1.539 - 1.540 - glBegin(GL_LINES); 1.541 - for(size_t i=0; i<nverts; i++) { 1.542 - glVertexAttrib3f(vert_loc, varr[i].x, varr[i].y, varr[i].z); 1.543 - Vector3 end = varr[i] + norm[i] * vis_vecsize; 1.544 - glVertexAttrib3f(vert_loc, end.x, end.y, end.z); 1.545 - } 1.546 - glEnd(); 1.547 - 1.548 -#endif // USE_OLDGL 1.549 -} 1.550 - 1.551 -void Mesh::draw_tangents() const 1.552 -{ 1.553 -#ifdef USE_OLDGL 1.554 - int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX]; 1.555 - Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX); 1.556 - Vector3 *tang = (Vector3*)get_attrib_data(MESH_ATTR_TANGENT); 1.557 - 1.558 - if(!varr || !tang || vert_loc < 0) { 1.559 - return; 1.560 - } 1.561 - 1.562 - glBegin(GL_LINES); 1.563 - for(size_t i=0; i<nverts; i++) { 1.564 - glVertexAttrib3f(vert_loc, varr[i].x, varr[i].y, varr[i].z); 1.565 - Vector3 end = varr[i] + tang[i] * vis_vecsize; 1.566 - glVertexAttrib3f(vert_loc, end.x, end.y, end.z); 1.567 - } 1.568 - glEnd(); 1.569 - 1.570 -#endif // USE_OLDGL 1.571 -} 1.572 - 1.573 -#if 0 1.574 -void Mesh::get_aabbox(Vector3 *vmin, Vector3 *vmax) const 1.575 -{ 1.576 - if(!aabb_valid) { 1.577 - ((Mesh*)this)->calc_aabb(); 1.578 - } 1.579 - *vmin = aabb.min; 1.580 - *vmax = aabb.max; 1.581 -} 1.582 - 1.583 -const AABox &Mesh::get_aabbox() const 1.584 -{ 1.585 - if(!aabb_valid) { 1.586 - ((Mesh*)this)->calc_aabb(); 1.587 - } 1.588 - return aabb; 1.589 -} 1.590 - 1.591 -float Mesh::get_bsphere(Vector3 *center, float *rad) const 1.592 -{ 1.593 - if(!bsph_valid) { 1.594 - ((Mesh*)this)->calc_bsph(); 1.595 - } 1.596 - *center = bsph.center; 1.597 - *rad = bsph.radius; 1.598 - return bsph.radius; 1.599 -} 1.600 - 1.601 -const Sphere &Mesh::get_bsphere() const 1.602 -{ 1.603 - if(!bsph_valid) { 1.604 - ((Mesh*)this)->calc_bsph(); 1.605 - } 1.606 - return bsph; 1.607 -} 1.608 - 1.609 -/// static function 1.610 -void Mesh::set_intersect_mode(unsigned int mode) 1.611 -{ 1.612 - Mesh::intersect_mode = mode; 1.613 -} 1.614 - 1.615 -/// static function 1.616 -unsigned int Mesh::get_intersect_mode() 1.617 -{ 1.618 - return Mesh::intersect_mode; 1.619 -} 1.620 - 1.621 -/// static function 1.622 -void Mesh::set_vertex_select_distance(float dist) 1.623 -{ 1.624 - Mesh::vertex_sel_dist = dist; 1.625 -} 1.626 - 1.627 -/// static function 1.628 -float Mesh::get_vertex_select_distance() 1.629 -{ 1.630 - return Mesh::vertex_sel_dist; 1.631 -} 1.632 - 1.633 -/*bool Mesh::intersect(const Ray &ray, HitPoint *hit) const 1.634 -{ 1.635 - assert((Mesh::intersect_mode & (ISECT_VERTICES | ISECT_FACE)) != (ISECT_VERTICES | ISECT_FACE)); 1.636 - 1.637 - const Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX); 1.638 - const Vector3 *narr = (Vector3*)get_attrib_data(MESH_ATTR_NORMAL); 1.639 - if(!varr) { 1.640 - return false; 1.641 - } 1.642 - const unsigned int *idxarr = get_index_data(); 1.643 - 1.644 - // first test with the bounding box 1.645 - AABox box; 1.646 - get_aabbox(&box.min, &box.max); 1.647 - if(!box.intersect(ray)) { 1.648 - return false; 1.649 - } 1.650 - 1.651 - HitPoint nearest_hit; 1.652 - nearest_hit.dist = FLT_MAX; 1.653 - nearest_hit.obj = 0; 1.654 - 1.655 - if(Mesh::intersect_mode & ISECT_VERTICES) { 1.656 - // we asked for "intersections" with the vertices of the mesh 1.657 - long nearest_vidx = -1; 1.658 - float thres_sq = Mesh::vertex_sel_dist * Mesh::vertex_sel_dist; 1.659 - 1.660 - for(unsigned int i=0; i<nverts; i++) { 1.661 - 1.662 - if((Mesh::intersect_mode & ISECT_FRONT) && dot_product(narr[i], ray.dir) > 0) { 1.663 - continue; 1.664 - } 1.665 - 1.666 - // project the vertex onto the ray line 1.667 - float t = dot_product(varr[i] - ray.origin, ray.dir); 1.668 - Vector3 vproj = ray.origin + ray.dir * t; 1.669 - 1.670 - float dist_sq = (vproj - varr[i]).length_sq(); 1.671 - if(dist_sq < thres_sq) { 1.672 - if(!hit) { 1.673 - return true; 1.674 - } 1.675 - if(t < nearest_hit.dist) { 1.676 - nearest_hit.dist = t; 1.677 - nearest_vidx = i; 1.678 - } 1.679 - } 1.680 - } 1.681 - 1.682 - if(nearest_vidx != -1) { 1.683 - hitvert = varr[nearest_vidx]; 1.684 - nearest_hit.obj = &hitvert; 1.685 - } 1.686 - 1.687 - } else { 1.688 - // regular intersection test with polygons 1.689 - 1.690 - for(unsigned int i=0; i<nfaces; i++) { 1.691 - Triangle face(i, varr, idxarr); 1.692 - 1.693 - // ignore back-facing polygons if the mode flags include ISECT_FRONT 1.694 - if((Mesh::intersect_mode & ISECT_FRONT) && dot_product(face.get_normal(), ray.dir) > 0) { 1.695 - continue; 1.696 - } 1.697 - 1.698 - HitPoint fhit; 1.699 - if(face.intersect(ray, hit ? &fhit : 0)) { 1.700 - if(!hit) { 1.701 - return true; 1.702 - } 1.703 - if(fhit.dist < nearest_hit.dist) { 1.704 - nearest_hit = fhit; 1.705 - hitface = face; 1.706 - } 1.707 - } 1.708 - } 1.709 - } 1.710 - 1.711 - if(nearest_hit.obj) { 1.712 - if(hit) { 1.713 - *hit = nearest_hit; 1.714 - 1.715 - // if we are interested in the mesh and not the faces set obj to this 1.716 - if(Mesh::intersect_mode & ISECT_FACE) { 1.717 - hit->obj = &hitface; 1.718 - } else if(Mesh::intersect_mode & ISECT_VERTICES) { 1.719 - hit->obj = &hitvert; 1.720 - } else { 1.721 - hit->obj = this; 1.722 - } 1.723 - } 1.724 - return true; 1.725 - } 1.726 - return false; 1.727 -}*/ 1.728 - 1.729 - 1.730 -// ------ private member functions ------ 1.731 - 1.732 -void Mesh::calc_aabb() 1.733 -{ 1.734 - // the cast is to force calling the const version which doesn't invalidate 1.735 - if(!((const Mesh*)this)->get_attrib_data(MESH_ATTR_VERTEX)) { 1.736 - return; 1.737 - } 1.738 - 1.739 - aabb.min = Vector3(FLT_MAX, FLT_MAX, FLT_MAX); 1.740 - aabb.max = -aabb.min; 1.741 - 1.742 - for(unsigned int i=0; i<nverts; i++) { 1.743 - Vector4 v = get_attrib(MESH_ATTR_VERTEX, i); 1.744 - for(int j=0; j<3; j++) { 1.745 - if(v[j] < aabb.min[j]) { 1.746 - aabb.min[j] = v[j]; 1.747 - } 1.748 - if(v[j] > aabb.max[j]) { 1.749 - aabb.max[j] = v[j]; 1.750 - } 1.751 - } 1.752 - } 1.753 - aabb_valid = true; 1.754 -} 1.755 - 1.756 -void Mesh::calc_bsph() 1.757 -{ 1.758 - // the cast is to force calling the const version which doesn't invalidate 1.759 - if(!((const Mesh*)this)->get_attrib_data(MESH_ATTR_VERTEX)) { 1.760 - return; 1.761 - } 1.762 - 1.763 - Vector3 v; 1.764 - bsph.center = Vector3(0, 0, 0); 1.765 - 1.766 - // first find the center 1.767 - for(unsigned int i=0; i<nverts; i++) { 1.768 - v = get_attrib(MESH_ATTR_VERTEX, i); 1.769 - bsph.center += v; 1.770 - } 1.771 - bsph.center /= (float)nverts; 1.772 - 1.773 - bsph.radius = 0.0f; 1.774 - for(unsigned int i=0; i<nverts; i++) { 1.775 - v = get_attrib(MESH_ATTR_VERTEX, i); 1.776 - float dist_sq = (v - bsph.center).length_sq(); 1.777 - if(dist_sq > bsph.radius) { 1.778 - bsph.radius = dist_sq; 1.779 - } 1.780 - } 1.781 - bsph.radius = sqrt(bsph.radius); 1.782 - 1.783 - bsph_valid = true; 1.784 -} 1.785 -#endif 1.786 - 1.787 -void Mesh::update_buffers() 1.788 -{ 1.789 - for(int i=0; i<NUM_MESH_ATTR; i++) { 1.790 - if(has_attrib(i) && !vattr[i].vbo_valid) { 1.791 - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); 1.792 - glBufferData(GL_ARRAY_BUFFER, nverts * vattr[i].nelem * sizeof(float), &vattr[i].data[0], GL_STATIC_DRAW); 1.793 - vattr[i].vbo_valid = true; 1.794 - } 1.795 - } 1.796 - glBindBuffer(GL_ARRAY_BUFFER, 0); 1.797 - 1.798 - if(idata_valid && !ibo_valid) { 1.799 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 1.800 - glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof(unsigned int), &idata[0], GL_STATIC_DRAW); 1.801 - ibo_valid = true; 1.802 - } 1.803 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1.804 -} 1.805 - 1.806 -void Mesh::update_wire_ibo() 1.807 -{ 1.808 - update_buffers(); 1.809 - 1.810 - if(wire_ibo_valid) { 1.811 - return; 1.812 - } 1.813 - 1.814 - if(!wire_ibo) { 1.815 - glGenBuffers(1, &wire_ibo); 1.816 - } 1.817 - 1.818 - unsigned int *wire_idxarr = new unsigned int[nfaces * 6]; 1.819 - unsigned int *dest = wire_idxarr; 1.820 - 1.821 - if(ibo_valid) { 1.822 - // we're dealing with an indexed mesh 1.823 - const unsigned int *idxarr = ((const Mesh*)this)->get_index_data(); 1.824 - 1.825 - for(unsigned int i=0; i<nfaces; i++) { 1.826 - *dest++ = idxarr[0]; 1.827 - *dest++ = idxarr[1]; 1.828 - *dest++ = idxarr[1]; 1.829 - *dest++ = idxarr[2]; 1.830 - *dest++ = idxarr[2]; 1.831 - *dest++ = idxarr[0]; 1.832 - idxarr += 3; 1.833 - } 1.834 - } else { 1.835 - // not an indexed mesh ... 1.836 - for(unsigned int i=0; i<nfaces; i++) { 1.837 - int vidx = i * 3; 1.838 - *dest++ = vidx; 1.839 - *dest++ = vidx + 1; 1.840 - *dest++ = vidx + 1; 1.841 - *dest++ = vidx + 2; 1.842 - *dest++ = vidx + 2; 1.843 - *dest++ = vidx; 1.844 - } 1.845 - } 1.846 - 1.847 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wire_ibo); 1.848 - glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 6 * sizeof(unsigned int), wire_idxarr, GL_STATIC_DRAW); 1.849 - delete [] wire_idxarr; 1.850 - wire_ibo_valid = true; 1.851 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1.852 -} 1.853 - 1.854 - 1.855 -// ------ class Triangle ------ 1.856 -Triangle::Triangle() 1.857 -{ 1.858 - normal_valid = false; 1.859 - id = -1; 1.860 -} 1.861 - 1.862 -Triangle::Triangle(const Vector3 &v0, const Vector3 &v1, const Vector3 &v2) 1.863 -{ 1.864 - v[0] = v0; 1.865 - v[1] = v1; 1.866 - v[2] = v2; 1.867 - normal_valid = false; 1.868 - id = -1; 1.869 -} 1.870 - 1.871 -Triangle::Triangle(int n, const Vector3 *varr, const unsigned int *idxarr) 1.872 -{ 1.873 - if(idxarr) { 1.874 - v[0] = varr[idxarr[n * 3]]; 1.875 - v[1] = varr[idxarr[n * 3 + 1]]; 1.876 - v[2] = varr[idxarr[n * 3 + 2]]; 1.877 - } else { 1.878 - v[0] = varr[n * 3]; 1.879 - v[1] = varr[n * 3 + 1]; 1.880 - v[2] = varr[n * 3 + 2]; 1.881 - } 1.882 - normal_valid = false; 1.883 - id = n; 1.884 -} 1.885 - 1.886 -void Triangle::calc_normal() 1.887 -{ 1.888 - normal = cross_product(v[1] - v[0], v[2] - v[0]).normalized(); 1.889 - normal_valid = true; 1.890 -} 1.891 - 1.892 -const Vector3 &Triangle::get_normal() const 1.893 -{ 1.894 - if(!normal_valid) { 1.895 - ((Triangle*)this)->calc_normal(); 1.896 - } 1.897 - return normal; 1.898 -} 1.899 - 1.900 -void Triangle::transform(const Matrix4x4 &xform) 1.901 -{ 1.902 - v[0].transform(xform); 1.903 - v[1].transform(xform); 1.904 - v[2].transform(xform); 1.905 - normal_valid = false; 1.906 -} 1.907 - 1.908 -void Triangle::draw() const 1.909 -{ 1.910 - Vector3 n[3]; 1.911 - n[0] = get_normal(); 1.912 - n[1] = get_normal(); 1.913 - n[2] = get_normal(); 1.914 - 1.915 - int vloc = Mesh::get_attrib_location(MESH_ATTR_VERTEX); 1.916 - int nloc = Mesh::get_attrib_location(MESH_ATTR_NORMAL); 1.917 - 1.918 - glEnableVertexAttribArray(vloc); 1.919 - glVertexAttribPointer(vloc, 3, GL_FLOAT, GL_FALSE, 0, &v[0].x); 1.920 - glVertexAttribPointer(nloc, 3, GL_FLOAT, GL_FALSE, 0, &n[0].x); 1.921 - 1.922 - glDrawArrays(GL_TRIANGLES, 0, 3); 1.923 - 1.924 - glDisableVertexAttribArray(vloc); 1.925 - glDisableVertexAttribArray(nloc); 1.926 - CHECKGLERR; 1.927 -} 1.928 - 1.929 -void Triangle::draw_wire() const 1.930 -{ 1.931 - static const int idxarr[] = {0, 1, 1, 2, 2, 0}; 1.932 - int vloc = Mesh::get_attrib_location(MESH_ATTR_VERTEX); 1.933 - 1.934 - glEnableVertexAttribArray(vloc); 1.935 - glVertexAttribPointer(vloc, 3, GL_FLOAT, GL_FALSE, 0, &v[0].x); 1.936 - 1.937 - glDrawElements(GL_LINES, 6, GL_UNSIGNED_INT, idxarr); 1.938 - 1.939 - glDisableVertexAttribArray(vloc); 1.940 - CHECKGLERR; 1.941 -} 1.942 - 1.943 -Vector3 Triangle::calc_barycentric(const Vector3 &pos) const 1.944 -{ 1.945 - Vector3 norm = get_normal(); 1.946 - 1.947 - float area_sq = fabs(dot_product(cross_product(v[1] - v[0], v[2] - v[0]), norm)); 1.948 - if(area_sq < 1e-5) { 1.949 - return Vector3(0, 0, 0); 1.950 - } 1.951 - 1.952 - float asq0 = fabs(dot_product(cross_product(v[1] - pos, v[2] - pos), norm)); 1.953 - float asq1 = fabs(dot_product(cross_product(v[2] - pos, v[0] - pos), norm)); 1.954 - float asq2 = fabs(dot_product(cross_product(v[0] - pos, v[1] - pos), norm)); 1.955 - 1.956 - return Vector3(asq0 / area_sq, asq1 / area_sq, asq2 / area_sq); 1.957 -} 1.958 - 1.959 -/*bool Triangle::intersect(const Ray &ray, HitPoint *hit) const 1.960 -{ 1.961 - Vector3 normal = get_normal(); 1.962 - 1.963 - float ndotdir = dot_product(ray.dir, normal); 1.964 - if(fabs(ndotdir) < 1e-4) { 1.965 - return false; 1.966 - } 1.967 - 1.968 - Vector3 vertdir = v[0] - ray.origin; 1.969 - float t = dot_product(normal, vertdir) / ndotdir; 1.970 - 1.971 - Vector3 pos = ray.origin + ray.dir * t; 1.972 - Vector3 bary = calc_barycentric(pos); 1.973 - 1.974 - if(bary.x + bary.y + bary.z > 1.00001) { 1.975 - return false; 1.976 - } 1.977 - 1.978 - if(hit) { 1.979 - hit->dist = t; 1.980 - hit->pos = ray.origin + ray.dir * t; 1.981 - hit->normal = normal; 1.982 - hit->obj = this; 1.983 - } 1.984 - return true; 1.985 -}*/