goat3d
changeset 8:cd71f0b92f44
a bit more...
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 21 Aug 2013 05:52:28 +0300 |
parents | 97139303348c |
children | 04bb114fcf05 |
files | src/camera.cc src/camera.h src/chunk.h src/goat3d.cc src/light.cc src/light.h src/material.h src/mesh.cc src/mesh.h src/node.cc src/node.h src/object.cc src/object.h src/opengl.cc src/opengl.h src/xform_node.h |
diffstat | 16 files changed, 277 insertions(+), 1418 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/camera.cc Wed Aug 21 05:52:28 2013 +0300 1.3 @@ -0,0 +1,13 @@ 1.4 +#include "camera.h" 1.5 + 1.6 +Camera::Camera() 1.7 +{ 1.8 + near_clip = 0.5; 1.9 + far_clip = 500.0; 1.10 +} 1.11 + 1.12 +TargetCamera::TargetCamera() 1.13 + : target(0, 0, 0), up(0, 1, 0) 1.14 +{ 1.15 + pos = Vector3(0, 0, 10); 1.16 +}
2.1 --- a/src/camera.h Wed Aug 21 04:00:22 2013 +0300 2.2 +++ b/src/camera.h Wed Aug 21 05:52:28 2013 +0300 2.3 @@ -1,8 +1,20 @@ 2.4 #ifndef CAMERA_H_ 2.5 #define CAMERA_H_ 2.6 2.7 -class Camera { 2.8 - // TODO 2.9 +#include "object.h" 2.10 + 2.11 +class Camera : public Object { 2.12 +public: 2.13 + float near_clip, far_clip; 2.14 + 2.15 + Camera(); 2.16 +}; 2.17 + 2.18 +class TargetCamera : public Camera { 2.19 +public: 2.20 + Vector3 target, up; 2.21 + 2.22 + TargetCamera(); 2.23 }; 2.24 2.25 #endif // CAMERA_H_
3.1 --- a/src/chunk.h Wed Aug 21 04:00:22 2013 +0300 3.2 +++ b/src/chunk.h Wed Aug 21 05:52:28 2013 +0300 3.3 @@ -57,6 +57,10 @@ 3.4 CNK_MESH_SKINMATRIX_LIST, // has a series of CNK_INT4 chunks (4 matrix indices) 3.5 CNK_MESH_COLOR_LIST, // has a series of CNK_FLOAT4 chunks 3.6 CNK_MESH_BONES_LIST, // has a series of CNK_INT or CNK_STRING chunks identifying the bone nodes 3.7 + CNK_MESH_FACE_LIST, // has a series of CNK_FACE chunks 3.8 + 3.9 + // child of CNK_MESH_FACE_LIST 3.10 + CNK_MESH_FACE, // has three CNK_INT chunks 3.11 3.12 // children of CNK_LIGHT 3.13 CNK_LIGHT_NAME, // has a single CNK_STRING
4.1 --- a/src/goat3d.cc Wed Aug 21 04:00:22 2013 +0300 4.2 +++ b/src/goat3d.cc Wed Aug 21 05:52:28 2013 +0300 4.3 @@ -1,8 +1,6 @@ 4.4 #include "goat3d.h" 4.5 #include "goat3d_impl.h" 4.6 4.7 -static void delete_node_tree(Node *n); 4.8 - 4.9 Scene::Scene() 4.10 : name("unnamed"), ambient(0.05, 0.05, 0.05) 4.11 { 4.12 @@ -43,14 +41,6 @@ 4.13 name = "unnamed"; 4.14 } 4.15 4.16 -static void delete_node_tree(Node *n) 4.17 -{ 4.18 - for(int i=0; i<n->get_num_children(); i++) { 4.19 - delete_node_tree(n->get_child(i)); 4.20 - } 4.21 - delete n; 4.22 -} 4.23 - 4.24 void Scene::set_name(const char *name) 4.25 { 4.26 this->name = name; 4.27 @@ -60,3 +50,123 @@ 4.28 { 4.29 return name.c_str(); 4.30 } 4.31 + 4.32 +void Scene::set_ambient(const Vector3 &amb) 4.33 +{ 4.34 + ambient = amb; 4.35 +} 4.36 + 4.37 +const Vector3 &Scene::get_ambient() const 4.38 +{ 4.39 + return ambient; 4.40 +} 4.41 + 4.42 +void Scene::add_material(Material *mat) 4.43 +{ 4.44 + materials.push_back(mat); 4.45 +} 4.46 + 4.47 +Material *Scene::get_material(int idx) const 4.48 +{ 4.49 + return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0; 4.50 +} 4.51 + 4.52 +Material *Scene::get_material(const char *name) const 4.53 +{ 4.54 + for(size_t i=0; i<materials.size(); i++) { 4.55 + if(materials[i]->name == std::string(name)) { 4.56 + return materials[i]; 4.57 + } 4.58 + } 4.59 + return 0; 4.60 +} 4.61 + 4.62 +void Scene::add_mesh(Mesh *mesh) 4.63 +{ 4.64 + meshes.push_back(mesh); 4.65 +} 4.66 + 4.67 +Mesh *Scene::get_mesh(int idx) const 4.68 +{ 4.69 + return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0; 4.70 +} 4.71 + 4.72 +Mesh *Scene::get_mesh(const char *name) const 4.73 +{ 4.74 + for(size_t i=0; i<meshes.size(); i++) { 4.75 + if(meshes[i]->name == std::string(name)) { 4.76 + return meshes[i]; 4.77 + } 4.78 + } 4.79 + return 0; 4.80 +} 4.81 + 4.82 +void Scene::add_light(Light *light) 4.83 +{ 4.84 + lights.push_back(light); 4.85 +} 4.86 + 4.87 +Light *Scene::get_light(int idx) const 4.88 +{ 4.89 + return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0; 4.90 +} 4.91 + 4.92 +Light *Scene::get_light(const char *name) const 4.93 +{ 4.94 + for(size_t i=0; i<lights.size(); i++) { 4.95 + if(lights[i]->name == std::string(name)) { 4.96 + return lights[i]; 4.97 + } 4.98 + } 4.99 + return 0; 4.100 +} 4.101 + 4.102 +void Scene::add_camera(Camera *cam) 4.103 +{ 4.104 + cameras.push_back(cam); 4.105 +} 4.106 + 4.107 +Camera *Scene::get_camera(int idx) const 4.108 +{ 4.109 + return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0; 4.110 +} 4.111 + 4.112 +Camera *Scene::get_camera(const char *name) const 4.113 +{ 4.114 + for(size_t i=0; i<cameras.size(); i++) { 4.115 + if(cameras[i]->name == std::string(name)) { 4.116 + return cameras[i]; 4.117 + } 4.118 + } 4.119 + return 0; 4.120 +} 4.121 + 4.122 +void Scene::add_node(Node *node) 4.123 +{ 4.124 + nodes.push_back(node); 4.125 +} 4.126 + 4.127 +Node *Scene::get_node(int idx) const 4.128 +{ 4.129 + return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0; 4.130 +} 4.131 + 4.132 +Node *Scene::get_node(const char *name) const 4.133 +{ 4.134 + for(size_t i=0; i<nodes.size(); i++) { 4.135 + if(strcmp(nodes[i]->get_name(), name) == 0) { 4.136 + return nodes[i]; 4.137 + } 4.138 + } 4.139 + return 0; 4.140 +} 4.141 + 4.142 +bool Scene::load(goat3d_io *io) 4.143 +{ 4.144 + return false; 4.145 +} 4.146 + 4.147 +bool Scene::save(goat3d_io *io) const 4.148 +{ 4.149 + return false; 4.150 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/light.cc Wed Aug 21 05:52:28 2013 +0300 5.3 @@ -0,0 +1,18 @@ 5.4 +#include "light.h" 5.5 + 5.6 +Light::Light() 5.7 + : color(1, 1, 1), attenuation(1, 0, 0) 5.8 +{ 5.9 + max_dist = 0.0; 5.10 +} 5.11 + 5.12 +DirLight::DirLight() 5.13 + : dir(0, 0, 1) 5.14 +{ 5.15 +} 5.16 + 5.17 +SpotLight::SpotLight() 5.18 +{ 5.19 + inner_cone = DEG_TO_RAD(30); 5.20 + outer_cone = DEG_TO_RAD(45); 5.21 +}
6.1 --- a/src/light.h Wed Aug 21 04:00:22 2013 +0300 6.2 +++ b/src/light.h Wed Aug 21 05:52:28 2013 +0300 6.3 @@ -1,8 +1,30 @@ 6.4 #ifndef LIGHT_H_ 6.5 #define LIGHT_H_ 6.6 6.7 -class Light { 6.8 - // TODO 6.9 +#include <vmath/vmath.h> 6.10 +#include "object.h" 6.11 + 6.12 +class Light : public Object { 6.13 +public: 6.14 + Vector3 color; 6.15 + Vector3 attenuation; 6.16 + float max_dist; 6.17 + 6.18 + Light(); 6.19 +}; 6.20 + 6.21 +class DirLight : public Light { 6.22 +public: 6.23 + Vector3 dir; 6.24 + 6.25 + DirLight(); 6.26 +}; 6.27 + 6.28 +class SpotLight : public DirLight { 6.29 +public: 6.30 + float inner_cone, outer_cone; 6.31 + 6.32 + SpotLight(); 6.33 }; 6.34 6.35 #endif // LIGHT_H_
7.1 --- a/src/material.h Wed Aug 21 04:00:22 2013 +0300 7.2 +++ b/src/material.h Wed Aug 21 05:52:28 2013 +0300 7.3 @@ -26,6 +26,8 @@ 7.4 std::map<std::string, MaterialAttrib> attrib; 7.5 7.6 public: 7.7 + std::string name; 7.8 + 7.9 MaterialAttrib &operator [](const std::string &name) 7.10 { 7.11 return attrib[name];
8.1 --- a/src/mesh.cc Wed Aug 21 04:00:22 2013 +0300 8.2 +++ b/src/mesh.cc Wed Aug 21 05:52:28 2013 +0300 8.3 @@ -1,973 +1,23 @@ 8.4 -#include <stdio.h> 8.5 -#include <stdlib.h> 8.6 -#include <float.h> 8.7 -#include <assert.h> 8.8 -#include "opengl.h" 8.9 #include "mesh.h" 8.10 -#include "xform_node.h" 8.11 -//#include "logger.h" 8.12 - 8.13 -int Mesh::global_sdr_loc[NUM_MESH_ATTR] = { 0, 1, 2, 3, 4, 5 }; 8.14 -unsigned int Mesh::intersect_mode = ISECT_DEFAULT; 8.15 -float Mesh::vertex_sel_dist = 0.01; 8.16 -float Mesh::vis_vecsize = 1.0; 8.17 8.18 Mesh::Mesh() 8.19 { 8.20 - clear(); 8.21 - 8.22 - glGenBuffers(NUM_MESH_ATTR + 1, buffer_objects); 8.23 - 8.24 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.25 - vattr[i].vbo = buffer_objects[i]; 8.26 - } 8.27 - ibo = buffer_objects[NUM_MESH_ATTR]; 8.28 - wire_ibo = 0; 8.29 + material = 0; 8.30 } 8.31 8.32 -Mesh::~Mesh() 8.33 +Mesh::~Mesh() {} 8.34 + 8.35 +void Mesh::set_material(Material *mat) 8.36 { 8.37 - glDeleteBuffers(NUM_MESH_ATTR + 1, buffer_objects); 8.38 - 8.39 - if(wire_ibo) { 8.40 - glDeleteBuffers(1, &wire_ibo); 8.41 - } 8.42 + material = mat; 8.43 } 8.44 8.45 -void Mesh::set_name(const char *name) 8.46 +Material *Mesh::get_material() 8.47 { 8.48 - this->name = name; 8.49 + return material; 8.50 } 8.51 8.52 -const char *Mesh::get_name() const 8.53 +const Material *Mesh::get_material() const 8.54 { 8.55 - return name.c_str(); 8.56 + return material; 8.57 } 8.58 - 8.59 -bool Mesh::has_attrib(int attr) const 8.60 -{ 8.61 - if(attr < 0 || attr >= NUM_MESH_ATTR) { 8.62 - return false; 8.63 - } 8.64 - 8.65 - // if neither of these is valid, then nobody has set this attribute 8.66 - return vattr[attr].vbo_valid || vattr[attr].data_valid; 8.67 -} 8.68 - 8.69 -void Mesh::clear() 8.70 -{ 8.71 - bones.clear(); 8.72 - 8.73 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.74 - vattr[i].nelem = 0; 8.75 - vattr[i].vbo_valid = false; 8.76 - vattr[i].data_valid = false; 8.77 - //vattr[i].sdr_loc = -1; 8.78 - vattr[i].data.clear(); 8.79 - } 8.80 - ibo_valid = false; 8.81 - idata.clear(); 8.82 - 8.83 - wire_ibo_valid = false; 8.84 - 8.85 - nverts = nfaces = 0; 8.86 - 8.87 - /*bsph_valid = false; 8.88 - aabb_valid = false;*/ 8.89 -} 8.90 - 8.91 -float *Mesh::set_attrib_data(int attrib, int nelem, unsigned int num, const float *data) 8.92 -{ 8.93 - if(attrib < 0 || attrib >= NUM_MESH_ATTR) { 8.94 - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); 8.95 - return 0; 8.96 - } 8.97 - 8.98 - if(nverts && num != nverts) { 8.99 - fprintf(stderr, "%s: attribute count missmatch (%d instead of %d)\n", __FUNCTION__, num, nverts); 8.100 - return 0; 8.101 - } 8.102 - nverts = num; 8.103 - 8.104 - vattr[attrib].data.clear(); 8.105 - vattr[attrib].nelem = nelem; 8.106 - vattr[attrib].data.resize(num * nelem); 8.107 - 8.108 - if(data) { 8.109 - memcpy(&vattr[attrib].data[0], data, num * nelem * sizeof *data); 8.110 - } 8.111 - 8.112 - vattr[attrib].data_valid = true; 8.113 - vattr[attrib].vbo_valid = false; 8.114 - return &vattr[attrib].data[0]; 8.115 -} 8.116 - 8.117 -float *Mesh::get_attrib_data(int attrib) 8.118 -{ 8.119 - if(attrib < 0 || attrib >= NUM_MESH_ATTR) { 8.120 - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); 8.121 - return 0; 8.122 - } 8.123 - 8.124 - vattr[attrib].vbo_valid = false; 8.125 - return (float*)((const Mesh*)this)->get_attrib_data(attrib); 8.126 -} 8.127 - 8.128 -const float *Mesh::get_attrib_data(int attrib) const 8.129 -{ 8.130 - if(attrib < 0 || attrib >= NUM_MESH_ATTR) { 8.131 - fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib); 8.132 - return 0; 8.133 - } 8.134 - 8.135 - if(!vattr[attrib].data_valid) { 8.136 -#if GL_ES_VERSION_2_0 8.137 - fprintf(stderr, "%s: can't read back attrib data on CrippledGL ES\n", __FUNCTION__); 8.138 - return 0; 8.139 -#else 8.140 - if(!vattr[attrib].vbo_valid) { 8.141 - fprintf(stderr, "%s: unavailable attrib: %d\n", __FUNCTION__, attrib); 8.142 - return 0; 8.143 - } 8.144 - 8.145 - // local data copy is unavailable, grab the data from the vbo 8.146 - Mesh *m = (Mesh*)this; 8.147 - m->vattr[attrib].data.resize(nverts * vattr[attrib].nelem); 8.148 - 8.149 - glBindBuffer(GL_ARRAY_BUFFER, vattr[attrib].vbo); 8.150 - void *data = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); 8.151 - memcpy(&m->vattr[attrib].data[0], data, nverts * vattr[attrib].nelem * sizeof(float)); 8.152 - glUnmapBuffer(GL_ARRAY_BUFFER); 8.153 - 8.154 - vattr[attrib].data_valid = true; 8.155 -#endif 8.156 - } 8.157 - 8.158 - return &vattr[attrib].data[0]; 8.159 -} 8.160 - 8.161 -void Mesh::set_attrib(int attrib, int idx, const Vector4 &v) 8.162 -{ 8.163 - float *data = get_attrib_data(attrib); 8.164 - if(data) { 8.165 - data += idx * vattr[attrib].nelem; 8.166 - for(int i=0; i<vattr[attrib].nelem; i++) { 8.167 - data[i] = v[i]; 8.168 - } 8.169 - } 8.170 -} 8.171 - 8.172 -Vector4 Mesh::get_attrib(int attrib, int idx) const 8.173 -{ 8.174 - Vector4 v(0.0, 0.0, 0.0, 1.0); 8.175 - const float *data = get_attrib_data(attrib); 8.176 - if(data) { 8.177 - data += idx * vattr[attrib].nelem; 8.178 - for(int i=0; i<vattr[attrib].nelem; i++) { 8.179 - v[i] = data[i]; 8.180 - } 8.181 - } 8.182 - return v; 8.183 -} 8.184 - 8.185 -unsigned int *Mesh::set_index_data(int num, const unsigned int *indices) 8.186 -{ 8.187 - int nidx = nfaces * 3; 8.188 - if(nidx && num != nidx) { 8.189 - fprintf(stderr, "%s: index count missmatch (%d instead of %d)\n", __FUNCTION__, num, nidx); 8.190 - return 0; 8.191 - } 8.192 - nfaces = num / 3; 8.193 - 8.194 - idata.clear(); 8.195 - idata.resize(num); 8.196 - 8.197 - if(indices) { 8.198 - memcpy(&idata[0], indices, num * sizeof *indices); 8.199 - } 8.200 - 8.201 - idata_valid = true; 8.202 - ibo_valid = false; 8.203 - 8.204 - return &idata[0]; 8.205 -} 8.206 - 8.207 -unsigned int *Mesh::get_index_data() 8.208 -{ 8.209 - ibo_valid = false; 8.210 - return (unsigned int*)((const Mesh*)this)->get_index_data(); 8.211 -} 8.212 - 8.213 -const unsigned int *Mesh::get_index_data() const 8.214 -{ 8.215 - if(!idata_valid) { 8.216 -#if GL_ES_VERSION_2_0 8.217 - fprintf(stderr, "%s: can't read back index data in CrippledGL ES\n", __FUNCTION__); 8.218 - return 0; 8.219 -#else 8.220 - if(!ibo_valid) { 8.221 - fprintf(stderr, "%s: indices unavailable\n", __FUNCTION__); 8.222 - return 0; 8.223 - } 8.224 - 8.225 - // local data copy is unavailable, gram the data from the ibo 8.226 - Mesh *m = (Mesh*)this; 8.227 - int nidx = nfaces * 3; 8.228 - m->idata.resize(nidx); 8.229 - 8.230 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 8.231 - void *data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); 8.232 - memcpy(&m->idata[0], data, nidx * sizeof(unsigned int)); 8.233 - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); 8.234 - 8.235 - idata_valid = true; 8.236 -#endif 8.237 - } 8.238 - 8.239 - return &idata[0]; 8.240 -} 8.241 - 8.242 -void Mesh::append(const Mesh &mesh) 8.243 -{ 8.244 - unsigned int idxoffs = nverts; 8.245 - 8.246 - nverts += mesh.nverts; 8.247 - nfaces += mesh.nfaces; 8.248 - 8.249 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.250 - if(has_attrib(i) && mesh.has_attrib(i)) { 8.251 - // force validating the data arrays 8.252 - get_attrib_data(i); 8.253 - mesh.get_attrib_data(i); 8.254 - 8.255 - // append the mesh data 8.256 - vattr[i].data.insert(vattr[i].data.end(), mesh.vattr[i].data.begin(), mesh.vattr[i].data.end()); 8.257 - } 8.258 - } 8.259 - 8.260 - if(ibo_valid || idata_valid) { 8.261 - // make index arrays valid 8.262 - get_index_data(); 8.263 - mesh.get_index_data(); 8.264 - 8.265 - size_t orig_sz = idata.size(); 8.266 - 8.267 - idata.insert(idata.end(), mesh.idata.begin(), mesh.idata.end()); 8.268 - 8.269 - // fixup all the new indices 8.270 - for(size_t i=orig_sz; i<idata.size(); i++) { 8.271 - idata[i] += idxoffs; 8.272 - } 8.273 - } 8.274 - 8.275 - // fuck everything 8.276 - wire_ibo_valid = false; 8.277 - /*aabb_valid = false; 8.278 - bsph_valid = false;*/ 8.279 -} 8.280 - 8.281 -// assemble a complete vertex by adding all the useful attributes 8.282 -void Mesh::vertex(float x, float y, float z) 8.283 -{ 8.284 - cur_val[MESH_ATTR_VERTEX] = Vector4(x, y, z, 1.0f); 8.285 - vattr[MESH_ATTR_VERTEX].data_valid = true; 8.286 - vattr[MESH_ATTR_VERTEX].nelem = 3; 8.287 - 8.288 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.289 - if(vattr[i].data_valid) { 8.290 - for(int j=0; j<vattr[MESH_ATTR_VERTEX].nelem; j++) { 8.291 - vattr[i].data.push_back(cur_val[i][j]); 8.292 - } 8.293 - } 8.294 - vattr[i].vbo_valid = false; 8.295 - } 8.296 - 8.297 - if(idata_valid) { 8.298 - idata.clear(); 8.299 - } 8.300 - ibo_valid = idata_valid = false; 8.301 -} 8.302 - 8.303 -void Mesh::normal(float nx, float ny, float nz) 8.304 -{ 8.305 - cur_val[MESH_ATTR_NORMAL] = Vector4(nx, ny, nz, 1.0f); 8.306 - vattr[MESH_ATTR_NORMAL].data_valid = true; 8.307 - vattr[MESH_ATTR_NORMAL].nelem = 3; 8.308 -} 8.309 - 8.310 -void Mesh::tangent(float tx, float ty, float tz) 8.311 -{ 8.312 - cur_val[MESH_ATTR_TANGENT] = Vector4(tx, ty, tz, 1.0f); 8.313 - vattr[MESH_ATTR_TANGENT].data_valid = true; 8.314 - vattr[MESH_ATTR_TANGENT].nelem = 3; 8.315 -} 8.316 - 8.317 -void Mesh::texcoord(float u, float v, float w) 8.318 -{ 8.319 - cur_val[MESH_ATTR_TEXCOORD] = Vector4(u, v, w, 1.0f); 8.320 - vattr[MESH_ATTR_TEXCOORD].data_valid = true; 8.321 - vattr[MESH_ATTR_TEXCOORD].nelem = 3; 8.322 -} 8.323 - 8.324 -void Mesh::boneweights(float w1, float w2, float w3, float w4) 8.325 -{ 8.326 - cur_val[MESH_ATTR_BONEWEIGHTS] = Vector4(w1, w2, w3, w4); 8.327 - vattr[MESH_ATTR_BONEWEIGHTS].data_valid = true; 8.328 - vattr[MESH_ATTR_BONEWEIGHTS].nelem = 4; 8.329 -} 8.330 - 8.331 -void Mesh::boneidx(int idx1, int idx2, int idx3, int idx4) 8.332 -{ 8.333 - cur_val[MESH_ATTR_BONEIDX] = Vector4(idx1, idx2, idx3, idx4); 8.334 - vattr[MESH_ATTR_BONEIDX].data_valid = true; 8.335 - vattr[MESH_ATTR_BONEIDX].nelem = 4; 8.336 -} 8.337 - 8.338 -/// static function 8.339 -void Mesh::set_attrib_location(int attr, int loc) 8.340 -{ 8.341 - if(attr < 0 || attr >= NUM_MESH_ATTR) { 8.342 - return; 8.343 - } 8.344 - Mesh::global_sdr_loc[attr] = loc; 8.345 -} 8.346 - 8.347 -/// static function 8.348 -int Mesh::get_attrib_location(int attr) 8.349 -{ 8.350 - if(attr < 0 || attr >= NUM_MESH_ATTR) { 8.351 - return -1; 8.352 - } 8.353 - return Mesh::global_sdr_loc[attr]; 8.354 -} 8.355 - 8.356 -/// static function 8.357 -void Mesh::clear_attrib_locations() 8.358 -{ 8.359 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.360 - Mesh::global_sdr_loc[i] = -1; 8.361 - } 8.362 -} 8.363 - 8.364 -/// static function 8.365 -void Mesh::set_vis_vecsize(float sz) 8.366 -{ 8.367 - Mesh::vis_vecsize = sz; 8.368 -} 8.369 - 8.370 -float Mesh::get_vis_vecsize() 8.371 -{ 8.372 - return Mesh::vis_vecsize; 8.373 -} 8.374 - 8.375 -void Mesh::apply_xform(const Matrix4x4 &xform) 8.376 -{ 8.377 - Matrix4x4 dir_xform = xform; 8.378 - dir_xform[0][3] = dir_xform[1][3] = dir_xform[2][3] = 0.0f; 8.379 - dir_xform[3][0] = dir_xform[3][1] = dir_xform[3][2] = 0.0f; 8.380 - dir_xform[3][3] = 1.0f; 8.381 - 8.382 - apply_xform(xform, dir_xform); 8.383 -} 8.384 - 8.385 -void Mesh::apply_xform(const Matrix4x4 &xform, const Matrix4x4 &dir_xform) 8.386 -{ 8.387 - for(unsigned int i=0; i<nverts; i++) { 8.388 - Vector4 v = get_attrib(MESH_ATTR_VERTEX, i); 8.389 - set_attrib(MESH_ATTR_VERTEX, i, v.transformed(xform)); 8.390 - 8.391 - if(has_attrib(MESH_ATTR_NORMAL)) { 8.392 - Vector3 n = get_attrib(MESH_ATTR_NORMAL, i); 8.393 - set_attrib(MESH_ATTR_NORMAL, i, n.transformed(dir_xform)); 8.394 - } 8.395 - if(has_attrib(MESH_ATTR_TANGENT)) { 8.396 - Vector3 t = get_attrib(MESH_ATTR_TANGENT, i); 8.397 - set_attrib(MESH_ATTR_TANGENT, i, t.transformed(dir_xform)); 8.398 - } 8.399 - } 8.400 -} 8.401 - 8.402 -int Mesh::add_bone(XFormNode *bone) 8.403 -{ 8.404 - int idx = bones.size(); 8.405 - bones.push_back(bone); 8.406 - return idx; 8.407 -} 8.408 - 8.409 -const XFormNode *Mesh::get_bone(int idx) const 8.410 -{ 8.411 - if(idx < 0 || idx >= (int)bones.size()) { 8.412 - return 0; 8.413 - } 8.414 - return bones[idx]; 8.415 -} 8.416 - 8.417 -int Mesh::get_bones_count() const 8.418 -{ 8.419 - return (int)bones.size(); 8.420 -} 8.421 - 8.422 -void Mesh::draw() const 8.423 -{ 8.424 - ((Mesh*)this)->update_buffers(); 8.425 - 8.426 - if(!vattr[MESH_ATTR_VERTEX].vbo_valid) { 8.427 - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); 8.428 - return; 8.429 - } 8.430 - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { 8.431 - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); 8.432 - return; 8.433 - } 8.434 - 8.435 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.436 - int loc = global_sdr_loc[i]; 8.437 - if(loc >= 0 && vattr[i].vbo_valid) { 8.438 - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); 8.439 - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); 8.440 - glEnableVertexAttribArray(loc); 8.441 - } 8.442 - } 8.443 - glBindBuffer(GL_ARRAY_BUFFER, 0); 8.444 - 8.445 - if(ibo_valid) { 8.446 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 8.447 - glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, 0); 8.448 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 8.449 - } else { 8.450 - glDrawArrays(GL_TRIANGLES, 0, nverts); 8.451 - } 8.452 - 8.453 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.454 - int loc = global_sdr_loc[i]; 8.455 - if(loc >= 0 && vattr[i].vbo_valid) { 8.456 - glDisableVertexAttribArray(loc); 8.457 - } 8.458 - } 8.459 -} 8.460 - 8.461 -void Mesh::draw_wire() const 8.462 -{ 8.463 - ((Mesh*)this)->update_wire_ibo(); 8.464 - 8.465 - if(!vattr[MESH_ATTR_VERTEX].vbo_valid || !wire_ibo_valid) { 8.466 - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); 8.467 - return; 8.468 - } 8.469 - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { 8.470 - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); 8.471 - return; 8.472 - } 8.473 - 8.474 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.475 - int loc = global_sdr_loc[i]; 8.476 - if(loc >= 0 && vattr[i].vbo_valid) { 8.477 - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); 8.478 - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); 8.479 - glEnableVertexAttribArray(loc); 8.480 - } 8.481 - } 8.482 - glBindBuffer(GL_ARRAY_BUFFER, 0); 8.483 - 8.484 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wire_ibo); 8.485 - glDrawElements(GL_LINES, nfaces * 6, GL_UNSIGNED_INT, 0); 8.486 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 8.487 - 8.488 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.489 - int loc = global_sdr_loc[i]; 8.490 - if(loc >= 0 && vattr[i].vbo_valid) { 8.491 - glDisableVertexAttribArray(loc); 8.492 - } 8.493 - } 8.494 -} 8.495 - 8.496 -void Mesh::draw_vertices() const 8.497 -{ 8.498 - ((Mesh*)this)->update_buffers(); 8.499 - 8.500 - if(!vattr[MESH_ATTR_VERTEX].vbo_valid) { 8.501 - fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__); 8.502 - return; 8.503 - } 8.504 - if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { 8.505 - fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); 8.506 - return; 8.507 - } 8.508 - 8.509 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.510 - int loc = global_sdr_loc[i]; 8.511 - if(loc >= 0 && vattr[i].vbo_valid) { 8.512 - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); 8.513 - glVertexAttribPointer(loc, vattr[i].nelem, GL_FLOAT, GL_FALSE, 0, 0); 8.514 - glEnableVertexAttribArray(loc); 8.515 - } 8.516 - } 8.517 - glBindBuffer(GL_ARRAY_BUFFER, 0); 8.518 - 8.519 - glDrawArrays(GL_POINTS, 0, nverts); 8.520 - 8.521 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.522 - int loc = global_sdr_loc[i]; 8.523 - if(loc >= 0 && vattr[i].vbo_valid) { 8.524 - glDisableVertexAttribArray(loc); 8.525 - } 8.526 - } 8.527 -} 8.528 - 8.529 -void Mesh::draw_normals() const 8.530 -{ 8.531 -#ifdef USE_OLDGL 8.532 - int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX]; 8.533 - Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX); 8.534 - Vector3 *norm = (Vector3*)get_attrib_data(MESH_ATTR_NORMAL); 8.535 - 8.536 - if(!varr || !norm || vert_loc < 0) { 8.537 - return; 8.538 - } 8.539 - 8.540 - glBegin(GL_LINES); 8.541 - for(size_t i=0; i<nverts; i++) { 8.542 - glVertexAttrib3f(vert_loc, varr[i].x, varr[i].y, varr[i].z); 8.543 - Vector3 end = varr[i] + norm[i] * vis_vecsize; 8.544 - glVertexAttrib3f(vert_loc, end.x, end.y, end.z); 8.545 - } 8.546 - glEnd(); 8.547 - 8.548 -#endif // USE_OLDGL 8.549 -} 8.550 - 8.551 -void Mesh::draw_tangents() const 8.552 -{ 8.553 -#ifdef USE_OLDGL 8.554 - int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX]; 8.555 - Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX); 8.556 - Vector3 *tang = (Vector3*)get_attrib_data(MESH_ATTR_TANGENT); 8.557 - 8.558 - if(!varr || !tang || vert_loc < 0) { 8.559 - return; 8.560 - } 8.561 - 8.562 - glBegin(GL_LINES); 8.563 - for(size_t i=0; i<nverts; i++) { 8.564 - glVertexAttrib3f(vert_loc, varr[i].x, varr[i].y, varr[i].z); 8.565 - Vector3 end = varr[i] + tang[i] * vis_vecsize; 8.566 - glVertexAttrib3f(vert_loc, end.x, end.y, end.z); 8.567 - } 8.568 - glEnd(); 8.569 - 8.570 -#endif // USE_OLDGL 8.571 -} 8.572 - 8.573 -#if 0 8.574 -void Mesh::get_aabbox(Vector3 *vmin, Vector3 *vmax) const 8.575 -{ 8.576 - if(!aabb_valid) { 8.577 - ((Mesh*)this)->calc_aabb(); 8.578 - } 8.579 - *vmin = aabb.min; 8.580 - *vmax = aabb.max; 8.581 -} 8.582 - 8.583 -const AABox &Mesh::get_aabbox() const 8.584 -{ 8.585 - if(!aabb_valid) { 8.586 - ((Mesh*)this)->calc_aabb(); 8.587 - } 8.588 - return aabb; 8.589 -} 8.590 - 8.591 -float Mesh::get_bsphere(Vector3 *center, float *rad) const 8.592 -{ 8.593 - if(!bsph_valid) { 8.594 - ((Mesh*)this)->calc_bsph(); 8.595 - } 8.596 - *center = bsph.center; 8.597 - *rad = bsph.radius; 8.598 - return bsph.radius; 8.599 -} 8.600 - 8.601 -const Sphere &Mesh::get_bsphere() const 8.602 -{ 8.603 - if(!bsph_valid) { 8.604 - ((Mesh*)this)->calc_bsph(); 8.605 - } 8.606 - return bsph; 8.607 -} 8.608 - 8.609 -/// static function 8.610 -void Mesh::set_intersect_mode(unsigned int mode) 8.611 -{ 8.612 - Mesh::intersect_mode = mode; 8.613 -} 8.614 - 8.615 -/// static function 8.616 -unsigned int Mesh::get_intersect_mode() 8.617 -{ 8.618 - return Mesh::intersect_mode; 8.619 -} 8.620 - 8.621 -/// static function 8.622 -void Mesh::set_vertex_select_distance(float dist) 8.623 -{ 8.624 - Mesh::vertex_sel_dist = dist; 8.625 -} 8.626 - 8.627 -/// static function 8.628 -float Mesh::get_vertex_select_distance() 8.629 -{ 8.630 - return Mesh::vertex_sel_dist; 8.631 -} 8.632 - 8.633 -/*bool Mesh::intersect(const Ray &ray, HitPoint *hit) const 8.634 -{ 8.635 - assert((Mesh::intersect_mode & (ISECT_VERTICES | ISECT_FACE)) != (ISECT_VERTICES | ISECT_FACE)); 8.636 - 8.637 - const Vector3 *varr = (Vector3*)get_attrib_data(MESH_ATTR_VERTEX); 8.638 - const Vector3 *narr = (Vector3*)get_attrib_data(MESH_ATTR_NORMAL); 8.639 - if(!varr) { 8.640 - return false; 8.641 - } 8.642 - const unsigned int *idxarr = get_index_data(); 8.643 - 8.644 - // first test with the bounding box 8.645 - AABox box; 8.646 - get_aabbox(&box.min, &box.max); 8.647 - if(!box.intersect(ray)) { 8.648 - return false; 8.649 - } 8.650 - 8.651 - HitPoint nearest_hit; 8.652 - nearest_hit.dist = FLT_MAX; 8.653 - nearest_hit.obj = 0; 8.654 - 8.655 - if(Mesh::intersect_mode & ISECT_VERTICES) { 8.656 - // we asked for "intersections" with the vertices of the mesh 8.657 - long nearest_vidx = -1; 8.658 - float thres_sq = Mesh::vertex_sel_dist * Mesh::vertex_sel_dist; 8.659 - 8.660 - for(unsigned int i=0; i<nverts; i++) { 8.661 - 8.662 - if((Mesh::intersect_mode & ISECT_FRONT) && dot_product(narr[i], ray.dir) > 0) { 8.663 - continue; 8.664 - } 8.665 - 8.666 - // project the vertex onto the ray line 8.667 - float t = dot_product(varr[i] - ray.origin, ray.dir); 8.668 - Vector3 vproj = ray.origin + ray.dir * t; 8.669 - 8.670 - float dist_sq = (vproj - varr[i]).length_sq(); 8.671 - if(dist_sq < thres_sq) { 8.672 - if(!hit) { 8.673 - return true; 8.674 - } 8.675 - if(t < nearest_hit.dist) { 8.676 - nearest_hit.dist = t; 8.677 - nearest_vidx = i; 8.678 - } 8.679 - } 8.680 - } 8.681 - 8.682 - if(nearest_vidx != -1) { 8.683 - hitvert = varr[nearest_vidx]; 8.684 - nearest_hit.obj = &hitvert; 8.685 - } 8.686 - 8.687 - } else { 8.688 - // regular intersection test with polygons 8.689 - 8.690 - for(unsigned int i=0; i<nfaces; i++) { 8.691 - Triangle face(i, varr, idxarr); 8.692 - 8.693 - // ignore back-facing polygons if the mode flags include ISECT_FRONT 8.694 - if((Mesh::intersect_mode & ISECT_FRONT) && dot_product(face.get_normal(), ray.dir) > 0) { 8.695 - continue; 8.696 - } 8.697 - 8.698 - HitPoint fhit; 8.699 - if(face.intersect(ray, hit ? &fhit : 0)) { 8.700 - if(!hit) { 8.701 - return true; 8.702 - } 8.703 - if(fhit.dist < nearest_hit.dist) { 8.704 - nearest_hit = fhit; 8.705 - hitface = face; 8.706 - } 8.707 - } 8.708 - } 8.709 - } 8.710 - 8.711 - if(nearest_hit.obj) { 8.712 - if(hit) { 8.713 - *hit = nearest_hit; 8.714 - 8.715 - // if we are interested in the mesh and not the faces set obj to this 8.716 - if(Mesh::intersect_mode & ISECT_FACE) { 8.717 - hit->obj = &hitface; 8.718 - } else if(Mesh::intersect_mode & ISECT_VERTICES) { 8.719 - hit->obj = &hitvert; 8.720 - } else { 8.721 - hit->obj = this; 8.722 - } 8.723 - } 8.724 - return true; 8.725 - } 8.726 - return false; 8.727 -}*/ 8.728 - 8.729 - 8.730 -// ------ private member functions ------ 8.731 - 8.732 -void Mesh::calc_aabb() 8.733 -{ 8.734 - // the cast is to force calling the const version which doesn't invalidate 8.735 - if(!((const Mesh*)this)->get_attrib_data(MESH_ATTR_VERTEX)) { 8.736 - return; 8.737 - } 8.738 - 8.739 - aabb.min = Vector3(FLT_MAX, FLT_MAX, FLT_MAX); 8.740 - aabb.max = -aabb.min; 8.741 - 8.742 - for(unsigned int i=0; i<nverts; i++) { 8.743 - Vector4 v = get_attrib(MESH_ATTR_VERTEX, i); 8.744 - for(int j=0; j<3; j++) { 8.745 - if(v[j] < aabb.min[j]) { 8.746 - aabb.min[j] = v[j]; 8.747 - } 8.748 - if(v[j] > aabb.max[j]) { 8.749 - aabb.max[j] = v[j]; 8.750 - } 8.751 - } 8.752 - } 8.753 - aabb_valid = true; 8.754 -} 8.755 - 8.756 -void Mesh::calc_bsph() 8.757 -{ 8.758 - // the cast is to force calling the const version which doesn't invalidate 8.759 - if(!((const Mesh*)this)->get_attrib_data(MESH_ATTR_VERTEX)) { 8.760 - return; 8.761 - } 8.762 - 8.763 - Vector3 v; 8.764 - bsph.center = Vector3(0, 0, 0); 8.765 - 8.766 - // first find the center 8.767 - for(unsigned int i=0; i<nverts; i++) { 8.768 - v = get_attrib(MESH_ATTR_VERTEX, i); 8.769 - bsph.center += v; 8.770 - } 8.771 - bsph.center /= (float)nverts; 8.772 - 8.773 - bsph.radius = 0.0f; 8.774 - for(unsigned int i=0; i<nverts; i++) { 8.775 - v = get_attrib(MESH_ATTR_VERTEX, i); 8.776 - float dist_sq = (v - bsph.center).length_sq(); 8.777 - if(dist_sq > bsph.radius) { 8.778 - bsph.radius = dist_sq; 8.779 - } 8.780 - } 8.781 - bsph.radius = sqrt(bsph.radius); 8.782 - 8.783 - bsph_valid = true; 8.784 -} 8.785 -#endif 8.786 - 8.787 -void Mesh::update_buffers() 8.788 -{ 8.789 - for(int i=0; i<NUM_MESH_ATTR; i++) { 8.790 - if(has_attrib(i) && !vattr[i].vbo_valid) { 8.791 - glBindBuffer(GL_ARRAY_BUFFER, vattr[i].vbo); 8.792 - glBufferData(GL_ARRAY_BUFFER, nverts * vattr[i].nelem * sizeof(float), &vattr[i].data[0], GL_STATIC_DRAW); 8.793 - vattr[i].vbo_valid = true; 8.794 - } 8.795 - } 8.796 - glBindBuffer(GL_ARRAY_BUFFER, 0); 8.797 - 8.798 - if(idata_valid && !ibo_valid) { 8.799 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 8.800 - glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 3 * sizeof(unsigned int), &idata[0], GL_STATIC_DRAW); 8.801 - ibo_valid = true; 8.802 - } 8.803 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 8.804 -} 8.805 - 8.806 -void Mesh::update_wire_ibo() 8.807 -{ 8.808 - update_buffers(); 8.809 - 8.810 - if(wire_ibo_valid) { 8.811 - return; 8.812 - } 8.813 - 8.814 - if(!wire_ibo) { 8.815 - glGenBuffers(1, &wire_ibo); 8.816 - } 8.817 - 8.818 - unsigned int *wire_idxarr = new unsigned int[nfaces * 6]; 8.819 - unsigned int *dest = wire_idxarr; 8.820 - 8.821 - if(ibo_valid) { 8.822 - // we're dealing with an indexed mesh 8.823 - const unsigned int *idxarr = ((const Mesh*)this)->get_index_data(); 8.824 - 8.825 - for(unsigned int i=0; i<nfaces; i++) { 8.826 - *dest++ = idxarr[0]; 8.827 - *dest++ = idxarr[1]; 8.828 - *dest++ = idxarr[1]; 8.829 - *dest++ = idxarr[2]; 8.830 - *dest++ = idxarr[2]; 8.831 - *dest++ = idxarr[0]; 8.832 - idxarr += 3; 8.833 - } 8.834 - } else { 8.835 - // not an indexed mesh ... 8.836 - for(unsigned int i=0; i<nfaces; i++) { 8.837 - int vidx = i * 3; 8.838 - *dest++ = vidx; 8.839 - *dest++ = vidx + 1; 8.840 - *dest++ = vidx + 1; 8.841 - *dest++ = vidx + 2; 8.842 - *dest++ = vidx + 2; 8.843 - *dest++ = vidx; 8.844 - } 8.845 - } 8.846 - 8.847 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wire_ibo); 8.848 - glBufferData(GL_ELEMENT_ARRAY_BUFFER, nfaces * 6 * sizeof(unsigned int), wire_idxarr, GL_STATIC_DRAW); 8.849 - delete [] wire_idxarr; 8.850 - wire_ibo_valid = true; 8.851 - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 8.852 -} 8.853 - 8.854 - 8.855 -// ------ class Triangle ------ 8.856 -Triangle::Triangle() 8.857 -{ 8.858 - normal_valid = false; 8.859 - id = -1; 8.860 -} 8.861 - 8.862 -Triangle::Triangle(const Vector3 &v0, const Vector3 &v1, const Vector3 &v2) 8.863 -{ 8.864 - v[0] = v0; 8.865 - v[1] = v1; 8.866 - v[2] = v2; 8.867 - normal_valid = false; 8.868 - id = -1; 8.869 -} 8.870 - 8.871 -Triangle::Triangle(int n, const Vector3 *varr, const unsigned int *idxarr) 8.872 -{ 8.873 - if(idxarr) { 8.874 - v[0] = varr[idxarr[n * 3]]; 8.875 - v[1] = varr[idxarr[n * 3 + 1]]; 8.876 - v[2] = varr[idxarr[n * 3 + 2]]; 8.877 - } else { 8.878 - v[0] = varr[n * 3]; 8.879 - v[1] = varr[n * 3 + 1]; 8.880 - v[2] = varr[n * 3 + 2]; 8.881 - } 8.882 - normal_valid = false; 8.883 - id = n; 8.884 -} 8.885 - 8.886 -void Triangle::calc_normal() 8.887 -{ 8.888 - normal = cross_product(v[1] - v[0], v[2] - v[0]).normalized(); 8.889 - normal_valid = true; 8.890 -} 8.891 - 8.892 -const Vector3 &Triangle::get_normal() const 8.893 -{ 8.894 - if(!normal_valid) { 8.895 - ((Triangle*)this)->calc_normal(); 8.896 - } 8.897 - return normal; 8.898 -} 8.899 - 8.900 -void Triangle::transform(const Matrix4x4 &xform) 8.901 -{ 8.902 - v[0].transform(xform); 8.903 - v[1].transform(xform); 8.904 - v[2].transform(xform); 8.905 - normal_valid = false; 8.906 -} 8.907 - 8.908 -void Triangle::draw() const 8.909 -{ 8.910 - Vector3 n[3]; 8.911 - n[0] = get_normal(); 8.912 - n[1] = get_normal(); 8.913 - n[2] = get_normal(); 8.914 - 8.915 - int vloc = Mesh::get_attrib_location(MESH_ATTR_VERTEX); 8.916 - int nloc = Mesh::get_attrib_location(MESH_ATTR_NORMAL); 8.917 - 8.918 - glEnableVertexAttribArray(vloc); 8.919 - glVertexAttribPointer(vloc, 3, GL_FLOAT, GL_FALSE, 0, &v[0].x); 8.920 - glVertexAttribPointer(nloc, 3, GL_FLOAT, GL_FALSE, 0, &n[0].x); 8.921 - 8.922 - glDrawArrays(GL_TRIANGLES, 0, 3); 8.923 - 8.924 - glDisableVertexAttribArray(vloc); 8.925 - glDisableVertexAttribArray(nloc); 8.926 - CHECKGLERR; 8.927 -} 8.928 - 8.929 -void Triangle::draw_wire() const 8.930 -{ 8.931 - static const int idxarr[] = {0, 1, 1, 2, 2, 0}; 8.932 - int vloc = Mesh::get_attrib_location(MESH_ATTR_VERTEX); 8.933 - 8.934 - glEnableVertexAttribArray(vloc); 8.935 - glVertexAttribPointer(vloc, 3, GL_FLOAT, GL_FALSE, 0, &v[0].x); 8.936 - 8.937 - glDrawElements(GL_LINES, 6, GL_UNSIGNED_INT, idxarr); 8.938 - 8.939 - glDisableVertexAttribArray(vloc); 8.940 - CHECKGLERR; 8.941 -} 8.942 - 8.943 -Vector3 Triangle::calc_barycentric(const Vector3 &pos) const 8.944 -{ 8.945 - Vector3 norm = get_normal(); 8.946 - 8.947 - float area_sq = fabs(dot_product(cross_product(v[1] - v[0], v[2] - v[0]), norm)); 8.948 - if(area_sq < 1e-5) { 8.949 - return Vector3(0, 0, 0); 8.950 - } 8.951 - 8.952 - float asq0 = fabs(dot_product(cross_product(v[1] - pos, v[2] - pos), norm)); 8.953 - float asq1 = fabs(dot_product(cross_product(v[2] - pos, v[0] - pos), norm)); 8.954 - float asq2 = fabs(dot_product(cross_product(v[0] - pos, v[1] - pos), norm)); 8.955 - 8.956 - return Vector3(asq0 / area_sq, asq1 / area_sq, asq2 / area_sq); 8.957 -} 8.958 - 8.959 -/*bool Triangle::intersect(const Ray &ray, HitPoint *hit) const 8.960 -{ 8.961 - Vector3 normal = get_normal(); 8.962 - 8.963 - float ndotdir = dot_product(ray.dir, normal); 8.964 - if(fabs(ndotdir) < 1e-4) { 8.965 - return false; 8.966 - } 8.967 - 8.968 - Vector3 vertdir = v[0] - ray.origin; 8.969 - float t = dot_product(normal, vertdir) / ndotdir; 8.970 - 8.971 - Vector3 pos = ray.origin + ray.dir * t; 8.972 - Vector3 bary = calc_barycentric(pos); 8.973 - 8.974 - if(bary.x + bary.y + bary.z > 1.00001) { 8.975 - return false; 8.976 - } 8.977 - 8.978 - if(hit) { 8.979 - hit->dist = t; 8.980 - hit->pos = ray.origin + ray.dir * t; 8.981 - hit->normal = normal; 8.982 - hit->obj = this; 8.983 - } 8.984 - return true; 8.985 -}*/
9.1 --- a/src/mesh.h Wed Aug 21 04:00:22 2013 +0300 9.2 +++ b/src/mesh.h Wed Aug 21 05:52:28 2013 +0300 9.3 @@ -1,213 +1,40 @@ 9.4 #ifndef MESH_H_ 9.5 #define MESH_H_ 9.6 9.7 -#include <string> 9.8 #include <vector> 9.9 -#include <vmath/vmath.h> 9.10 -//#include "geom.h" 9.11 +#include "object.h" 9.12 +#include "material.h" 9.13 9.14 -enum { 9.15 - MESH_ATTR_VERTEX, 9.16 - MESH_ATTR_NORMAL, 9.17 - MESH_ATTR_TANGENT, 9.18 - MESH_ATTR_TEXCOORD, 9.19 - MESH_ATTR_COLOR, 9.20 - MESH_ATTR_BONEWEIGHTS, 9.21 - MESH_ATTR_BONEIDX, 9.22 +class Node; 9.23 9.24 - NUM_MESH_ATTR 9.25 +struct Face { 9.26 + int v[3]; 9.27 }; 9.28 9.29 -// intersection mode flags 9.30 -enum { 9.31 - ISECT_DEFAULT = 0, // default (whole mesh, all intersections) 9.32 - ISECT_FRONT = 1, // front-faces only 9.33 - ISECT_FACE = 2, // return intersected face pointer instead of mesh 9.34 - ISECT_VERTICES = 4 // return (?) TODO 9.35 +struct Int4 { 9.36 + int x, y, z, w; 9.37 }; 9.38 9.39 -class XFormNode; 9.40 +class Mesh : public Object { 9.41 +public: 9.42 + Material *material; 9.43 9.44 + std::vector<Vector3> vertices; 9.45 + std::vector<Vector3> normals; 9.46 + std::vector<Vector3> tangents; 9.47 + std::vector<Vector3> texcoords; 9.48 + std::vector<Vector4> skin_weights; 9.49 + std::vector<Int4> skin_matrices; 9.50 + std::vector<Vector4> colors; 9.51 + std::vector<Node*> bones; 9.52 + std::vector<Face> faces; 9.53 9.54 -class Triangle { 9.55 -public: 9.56 - Vector3 v[3]; 9.57 - Vector3 normal; 9.58 - bool normal_valid; 9.59 - int id; 9.60 + Mesh(); 9.61 + virtual ~Mesh(); 9.62 9.63 - Triangle(); 9.64 - Triangle(const Vector3 &v0, const Vector3 &v1, const Vector3 &v2); 9.65 - Triangle(int n, const Vector3 *varr, const unsigned int *idxarr = 0); 9.66 - 9.67 - /// calculate normal (quite expensive) 9.68 - void calc_normal(); 9.69 - const Vector3 &get_normal() const; 9.70 - 9.71 - void transform(const Matrix4x4 &xform); 9.72 - 9.73 - void draw() const; 9.74 - void draw_wire() const; 9.75 - 9.76 - /// calculate barycentric coordinates of a point 9.77 - Vector3 calc_barycentric(const Vector3 &pos) const; 9.78 - 9.79 - //bool intersect(const Ray &ray, HitPoint *hit = 0) const; 9.80 + virtual void set_material(Material *mat); 9.81 + virtual Material *get_material(); 9.82 + virtual const Material *get_material() const; 9.83 }; 9.84 9.85 - 9.86 -class Mesh { 9.87 -private: 9.88 - std::string name; 9.89 - unsigned int nverts, nfaces; 9.90 - 9.91 - // current value for each attribute for the immedate mode 9.92 - // interface. 9.93 - Vector4 cur_val[NUM_MESH_ATTR]; 9.94 - 9.95 - unsigned int buffer_objects[NUM_MESH_ATTR + 1]; 9.96 - 9.97 - // vertex attribute data and buffer objects 9.98 - struct { 9.99 - int nelem; // number of elements per attribute range: [1, 4] 9.100 - std::vector<float> data; 9.101 - unsigned int vbo; 9.102 - mutable bool vbo_valid; // if this is false, the vbo needs updating from the data 9.103 - mutable bool data_valid; // if this is false, the data needs to be pulled from the vbo 9.104 - //int sdr_loc; 9.105 - } vattr[NUM_MESH_ATTR]; 9.106 - 9.107 - static int global_sdr_loc[NUM_MESH_ATTR]; 9.108 - 9.109 - std::vector<XFormNode*> bones; // bones affecting this mesh 9.110 - 9.111 - // index data and buffer object 9.112 - std::vector<unsigned int> idata; 9.113 - unsigned int ibo; 9.114 - mutable bool ibo_valid; 9.115 - mutable bool idata_valid; 9.116 - 9.117 - // index buffer object for wireframe rendering (constructed on demand) 9.118 - unsigned int wire_ibo; 9.119 - mutable bool wire_ibo_valid; 9.120 - 9.121 - // axis-aligned bounding box 9.122 - /*mutable AABox aabb; 9.123 - mutable bool aabb_valid; 9.124 - 9.125 - // bounding sphere 9.126 - mutable Sphere bsph; 9.127 - mutable bool bsph_valid;*/ 9.128 - 9.129 - // keeps the last intersected face 9.130 - mutable Triangle hitface; 9.131 - // keeps the last intersected vertex position 9.132 - mutable Vector3 hitvert; 9.133 - 9.134 - void calc_aabb(); 9.135 - void calc_bsph(); 9.136 - 9.137 - static unsigned int intersect_mode; 9.138 - static float vertex_sel_dist; 9.139 - 9.140 - static float vis_vecsize; 9.141 - 9.142 - /// update the VBOs after data has changed (invalid vbo/ibo) 9.143 - void update_buffers(); 9.144 - /// construct/update the wireframe index buffer (called from draw_wire). 9.145 - void update_wire_ibo(); 9.146 - 9.147 - 9.148 -public: 9.149 - Mesh(); 9.150 - ~Mesh(); 9.151 - 9.152 - void set_name(const char *name); 9.153 - const char *get_name() const; 9.154 - 9.155 - bool has_attrib(int attr) const; 9.156 - 9.157 - // clears everything about this mesh, and returns to the newly constructed state 9.158 - void clear(); 9.159 - 9.160 - // access the vertex attribute data 9.161 - // if vdata == 0, space is just allocated 9.162 - float *set_attrib_data(int attrib, int nelem, unsigned int num, const float *vdata = 0); // invalidates vbo 9.163 - float *get_attrib_data(int attrib); // invalidates vbo 9.164 - const float *get_attrib_data(int attrib) const; 9.165 - 9.166 - // simple access to any particular attribute 9.167 - void set_attrib(int attrib, int idx, const Vector4 &v); // invalidates vbo 9.168 - Vector4 get_attrib(int attrib, int idx) const; 9.169 - 9.170 - // ... same for index data 9.171 - unsigned int *set_index_data(int num, const unsigned int *indices = 0); // invalidates ibo 9.172 - unsigned int *get_index_data(); // invalidates ibo 9.173 - const unsigned int *get_index_data() const; 9.174 - 9.175 - void append(const Mesh &mesh); 9.176 - 9.177 - // immediate-mode style mesh construction interface 9.178 - void vertex(float x, float y, float z); 9.179 - void normal(float nx, float ny, float nz); 9.180 - void tangent(float tx, float ty, float tz); 9.181 - void texcoord(float u, float v, float w); 9.182 - void boneweights(float w1, float w2, float w3, float w4); 9.183 - void boneidx(int idx1, int idx2, int idx3, int idx4); 9.184 - 9.185 - /* apply a transformation to the vertices and its inverse-transpose 9.186 - * to the normals and tangents. 9.187 - */ 9.188 - void apply_xform(const Matrix4x4 &xform); 9.189 - void apply_xform(const Matrix4x4 &xform, const Matrix4x4 &dir_xform); 9.190 - 9.191 - // adds a bone and returns its index 9.192 - int add_bone(XFormNode *bone); 9.193 - const XFormNode *get_bone(int idx) const; 9.194 - int get_bones_count() const; 9.195 - 9.196 - // access the shader attribute locations 9.197 - static void set_attrib_location(int attr, int loc); 9.198 - static int get_attrib_location(int attr); 9.199 - static void clear_attrib_locations(); 9.200 - 9.201 - static void set_vis_vecsize(float sz); 9.202 - static float get_vis_vecsize(); 9.203 - 9.204 - void draw() const; 9.205 - void draw_wire() const; 9.206 - void draw_vertices() const; 9.207 - void draw_normals() const; 9.208 - void draw_tangents() const; 9.209 - 9.210 -#if 0 9.211 - /** get the bounding box in local space. The result will be cached, and subsequent 9.212 - * calls will return the same box. The cache gets invalidated by any functions that can affect 9.213 - * the vertex data (non-const variant of get_attrib_data(MESH_ATTR_VERTEX, ...) included). 9.214 - * @{ */ 9.215 - void get_aabbox(Vector3 *vmin, Vector3 *vmax) const; 9.216 - const AABox &get_aabbox() const; 9.217 - /// @} 9.218 - 9.219 - /** get the bounding sphere in local space. The result will be cached, and subsequent 9.220 - * calls will return the same box. The cache gets invalidated by any functions that can affect 9.221 - * the vertex data (non-const variant of get_attrib_data(MESH_ATTR_VERTEX, ...) included). 9.222 - * @{ */ 9.223 - float get_bsphere(Vector3 *center, float *rad) const; 9.224 - const Sphere &get_bsphere() const; 9.225 - 9.226 - static void set_intersect_mode(unsigned int mode); 9.227 - static unsigned int get_intersect_mode(); 9.228 - static void set_vertex_select_distance(float dist); 9.229 - static float get_vertex_select_distance(); 9.230 - 9.231 - /** Find the intersection between the mesh and a ray. 9.232 - * XXX Brute force at the moment, not intended to be used for anything other than picking in tools. 9.233 - * If you intend to use it in a speed-critical part of the code, you'll *have* to optimize it! 9.234 - */ 9.235 - bool intersect(const Ray &ray, HitPoint *hit = 0) const; 9.236 -#endif 9.237 -}; 9.238 - 9.239 - 9.240 #endif // MESH_H_
10.1 --- a/src/node.cc Wed Aug 21 04:00:22 2013 +0300 10.2 +++ b/src/node.cc Wed Aug 21 05:52:28 2013 +0300 10.3 @@ -4,92 +4,28 @@ 10.4 10.5 Node::Node() 10.6 { 10.7 - parent = 0; 10.8 + obj = 0; 10.9 } 10.10 10.11 -Node::~Node() 10.12 +void Node::set_object(Object *obj) 10.13 { 10.14 + this->obj = obj; 10.15 } 10.16 10.17 -void Node::set_name(const char *name) 10.18 +Object *Node::get_object() 10.19 { 10.20 - this->name = name; 10.21 + return obj; 10.22 } 10.23 10.24 -const char *Node::get_name() const 10.25 +const Object *Node::get_object() const 10.26 { 10.27 - return name.c_str(); 10.28 + return obj; 10.29 } 10.30 10.31 -void Node::add_child(Node *c) 10.32 +void delete_node_tree(Node *n) 10.33 { 10.34 - // make sure we don't add it twice 10.35 - if(std::find(children.begin(), children.end(), c) != children.end()) { 10.36 - return; 10.37 + for(int i=0; i<n->get_children_count(); i++) { 10.38 + delete_node_tree((Node*)n->get_child(i)); 10.39 } 10.40 - children.push_back(c); 10.41 - c->parent = this; 10.42 + delete n; 10.43 } 10.44 - 10.45 -int Node::get_num_children() const 10.46 -{ 10.47 - return (int)children.size(); 10.48 -} 10.49 - 10.50 -Node *Node::get_child(int idx) const 10.51 -{ 10.52 - if(idx < 0 || idx >= get_num_children()) { 10.53 - return 0; 10.54 - } 10.55 - return children[idx]; 10.56 -} 10.57 - 10.58 -Node *Node::get_child(const char *name) const 10.59 -{ 10.60 - for(size_t i=0; i<children.size(); i++) { 10.61 - if(strcmp(children[i]->get_name(), name) == 0) { 10.62 - return children[i]; 10.63 - } 10.64 - } 10.65 - return 0; 10.66 -} 10.67 - 10.68 -Node *Node::get_descendant(const char *name) const 10.69 -{ 10.70 - Node *c = get_child(name); 10.71 - if(c) { 10.72 - return c; 10.73 - } 10.74 - 10.75 - // depth first search might not be ideal in this case, but it's the simplest 10.76 - for(size_t i=0; i<children.size(); i++) { 10.77 - if((c = children[i]->get_descendant(name))) { 10.78 - return c; 10.79 - } 10.80 - } 10.81 - return 0; 10.82 -} 10.83 - 10.84 -Node *Node::get_parent() const 10.85 -{ 10.86 - return parent; 10.87 -} 10.88 - 10.89 -Node *Node::get_ancestor(const char *name) const 10.90 -{ 10.91 - Node *n = (Node*)this; 10.92 - 10.93 - if(!name) { 10.94 - // just return the root 10.95 - while(n->parent) { 10.96 - n = n->parent; 10.97 - } 10.98 - return n; 10.99 - } 10.100 - 10.101 - // otherwise we're looking for a specific ancestor 10.102 - while(n && strcmp(n->get_name(), name) != 0) { 10.103 - n = n->parent; 10.104 - } 10.105 - return n; 10.106 -}
11.1 --- a/src/node.h Wed Aug 21 04:00:22 2013 +0300 11.2 +++ b/src/node.h Wed Aug 21 05:52:28 2013 +0300 11.3 @@ -1,9 +1,8 @@ 11.4 #ifndef NODE_H_ 11.5 #define NODE_H_ 11.6 11.7 -#include <string> 11.8 -#include <vector> 11.9 #include "xform_node.h" 11.10 +#include "object.h" 11.11 11.12 class Node : public XFormNode { 11.13 private: 11.14 @@ -11,11 +10,12 @@ 11.15 11.16 public: 11.17 Node(); 11.18 - virtual ~Node(); 11.19 11.20 void set_object(Object *obj); 11.21 Object *get_object(); 11.22 const Object *get_object() const; 11.23 }; 11.24 11.25 +void delete_node_tree(Node *n); 11.26 + 11.27 #endif // NODE_H_
12.1 --- a/src/object.cc Wed Aug 21 04:00:22 2013 +0300 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,27 +0,0 @@ 12.4 -#include "object.h" 12.5 - 12.6 -Object::Object() 12.7 -{ 12.8 - material = 0; 12.9 - mesh = 0; 12.10 -} 12.11 - 12.12 -void Object::set_mesh(Mesh *mesh) 12.13 -{ 12.14 - this->mesh = mesh; 12.15 -} 12.16 - 12.17 -Mesh *Object::get_mesh() const 12.18 -{ 12.19 - return mesh; 12.20 -} 12.21 - 12.22 -void Object::set_material(Material *mtl) 12.23 -{ 12.24 - material = mtl; 12.25 -} 12.26 - 12.27 -Material *Object::get_material() const 12.28 -{ 12.29 - return material; 12.30 -}
13.1 --- a/src/object.h Wed Aug 21 04:00:22 2013 +0300 13.2 +++ b/src/object.h Wed Aug 21 05:52:28 2013 +0300 13.3 @@ -1,23 +1,15 @@ 13.4 #ifndef OBJECT_H_ 13.5 #define OBJECT_H_ 13.6 13.7 -#include "node.h" 13.8 -#include "mesh.h" 13.9 -#include "material.h" 13.10 +#include <string> 13.11 +#include <vmath/vmath.h> 13.12 13.13 -class Object : public Node { 13.14 -private: 13.15 - Material *material; 13.16 - Mesh *mesh; 13.17 +class Object { 13.18 +public: 13.19 + std::string name; 13.20 13.21 -public: 13.22 - Object(); 13.23 - 13.24 - void set_mesh(Mesh *mesh); 13.25 - Mesh *get_mesh() const; 13.26 - 13.27 - void set_material(Material *mtl); 13.28 - Material *get_material() const; 13.29 + Vector3 pos; 13.30 + Quaternion rot; 13.31 }; 13.32 13.33 #endif // OBJECT_H_
14.1 --- a/src/opengl.cc Wed Aug 21 04:00:22 2013 +0300 14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3 @@ -1,29 +0,0 @@ 14.4 -#include "opengl.h" 14.5 - 14.6 -void init_opengl() 14.7 -{ 14.8 -#ifdef __GLEW_H__ 14.9 - glewInit(); 14.10 -#endif 14.11 -} 14.12 - 14.13 -const char *strglerr(int err) 14.14 -{ 14.15 - static const char *errnames[] = { 14.16 - "GL_INVALID_ENUM", 14.17 - "GL_INVALID_VALUE", 14.18 - "GL_INVALID_OPERATION", 14.19 - "GL_STACK_OVERFLOW", 14.20 - "GL_STACK_UNDERFLOW", 14.21 - "GL_OUT_OF_MEMORY", 14.22 - "GL_INVALID_FRAMEBUFFER_OPERATION" 14.23 - }; 14.24 - 14.25 - if(!err) { 14.26 - return "GL_NO_ERROR"; 14.27 - } 14.28 - if(err < GL_INVALID_ENUM || err > GL_OUT_OF_MEMORY) { 14.29 - return "<invalid gl error>"; 14.30 - } 14.31 - return errnames[err - GL_INVALID_ENUM]; 14.32 -}
15.1 --- a/src/opengl.h Wed Aug 21 04:00:22 2013 +0300 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,71 +0,0 @@ 15.4 -#ifndef OPENGL_H_ 15.5 -#define OPENGL_H_ 15.6 - 15.7 -#include <stdlib.h> 15.8 - 15.9 -#ifdef __APPLE__ 15.10 -#include "TargetConditionals.h" 15.11 - 15.12 -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR 15.13 -/* iOS */ 15.14 -#include <OpenGLES/ES2/gl.h> 15.15 -#include <OpenGLES/ES2/glext.h> 15.16 - 15.17 -#define GL_CLAMP GL_CLAMP_TO_EDGE 15.18 -#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES 15.19 - 15.20 -#undef USE_OLDGL 15.21 - 15.22 -#define GL_WRITE_ONLY GL_WRITE_ONLY_OES 15.23 -#define glMapBuffer glMapBufferOES 15.24 -#define glUnmapBuffer glUnmapBufferOES 15.25 - 15.26 -#else 15.27 -/* MacOS X */ 15.28 -#include <GL/glew.h> 15.29 -#include <GLUT/glut.h> 15.30 - 15.31 -#define USE_OLDGL 15.32 -#endif 15.33 - 15.34 -#else 15.35 -/* UNIX or Windows */ 15.36 -#include <GL/glew.h> 15.37 -#include <GL/glut.h> 15.38 - 15.39 -#define USE_OLDGL 15.40 -#endif 15.41 - 15.42 -#ifndef GL_RGB16F 15.43 -#define GL_RGB16F 0x881b 15.44 -#endif 15.45 -#ifndef GL_RGBA16F 15.46 -#define GL_RGBA16F 0x881a 15.47 -#endif 15.48 -#ifndef GL_RGB32F 15.49 -#define GL_RGB32F 0x8815 15.50 -#endif 15.51 -#ifndef GL_RGBA32F 15.52 -#define GL_RGBA32F 0x8814 15.53 -#endif 15.54 -#ifndef GL_LUMINANCE16F 15.55 -#define GL_LUMINANCE16F 0x881e 15.56 -#endif 15.57 -#ifndef GL_LUMINANCE32F 15.58 -#define GL_LUMINANCE32F 0x8818 15.59 -#endif 15.60 - 15.61 -#define CHECKGLERR \ 15.62 - do { \ 15.63 - int err = glGetError(); \ 15.64 - if(err) { \ 15.65 - fprintf(stderr, "%s:%d: OpenGL error 0x%x: %s\n", __FILE__, __LINE__, err, strglerr(err)); \ 15.66 - abort(); \ 15.67 - } \ 15.68 - } while(0) 15.69 - 15.70 -void init_opengl(); 15.71 - 15.72 -const char *strglerr(int err); 15.73 - 15.74 -#endif // OPENGL_H_
16.1 --- a/src/xform_node.h Wed Aug 21 04:00:22 2013 +0300 16.2 +++ b/src/xform_node.h Wed Aug 21 05:52:28 2013 +0300 16.3 @@ -35,53 +35,53 @@ 16.4 XFormNode(); 16.5 virtual ~XFormNode(); 16.6 16.7 - void set_name(const char *name); 16.8 - const char *get_name() const; 16.9 + virtual void set_name(const char *name); 16.10 + virtual const char *get_name() const; 16.11 16.12 - void set_interpolator(Interp in); 16.13 - Interp get_interpolator() const; 16.14 - void set_extrapolator(Extrap ex); 16.15 - Extrap get_extrapolator() const; 16.16 + virtual void set_interpolator(Interp in); 16.17 + virtual Interp get_interpolator() const; 16.18 + virtual void set_extrapolator(Extrap ex); 16.19 + virtual Extrap get_extrapolator() const; 16.20 16.21 // children management 16.22 - void add_child(XFormNode *child); 16.23 - void remove_child(XFormNode *child); 16.24 + virtual void add_child(XFormNode *child); 16.25 + virtual void remove_child(XFormNode *child); 16.26 16.27 - int get_children_count() const; 16.28 - XFormNode *get_child(int idx); 16.29 - const XFormNode *get_child(int idx) const; 16.30 + virtual int get_children_count() const; 16.31 + virtual XFormNode *get_child(int idx); 16.32 + virtual const XFormNode *get_child(int idx) const; 16.33 16.34 16.35 - void set_position(const Vector3 &pos, long tmsec = 0); 16.36 - Vector3 get_node_position(long tmsec = 0) const; 16.37 + virtual void set_position(const Vector3 &pos, long tmsec = 0); 16.38 + virtual Vector3 get_node_position(long tmsec = 0) const; 16.39 16.40 - void set_rotation(const Quaternion &quat, long tmsec = 0); 16.41 - Quaternion get_node_rotation(long tmsec = 0) const; 16.42 + virtual void set_rotation(const Quaternion &quat, long tmsec = 0); 16.43 + virtual Quaternion get_node_rotation(long tmsec = 0) const; 16.44 16.45 - void set_scaling(const Vector3 &pos, long tmsec = 0); 16.46 - Vector3 get_node_scaling(long tmsec = 0) const; 16.47 + virtual void set_scaling(const Vector3 &pos, long tmsec = 0); 16.48 + virtual Vector3 get_node_scaling(long tmsec = 0) const; 16.49 16.50 // these take hierarchy into account 16.51 - Vector3 get_position(long tmsec = 0) const; 16.52 - Quaternion get_rotation(long tmsec = 0) const; 16.53 - Vector3 get_scaling(long tmsec = 0) const; 16.54 + virtual Vector3 get_position(long tmsec = 0) const; 16.55 + virtual Quaternion get_rotation(long tmsec = 0) const; 16.56 + virtual Vector3 get_scaling(long tmsec = 0) const; 16.57 16.58 - void set_pivot(const Vector3 &pivot); 16.59 - Vector3 get_pivot() const; 16.60 + virtual void set_pivot(const Vector3 &pivot); 16.61 + virtual Vector3 get_pivot() const; 16.62 16.63 // the local matrix is concatenated with the regular node/anim matrix 16.64 - void set_local_matrix(const Matrix4x4 &mat); 16.65 - const Matrix4x4 &get_local_matrix() const; 16.66 + virtual void set_local_matrix(const Matrix4x4 &mat); 16.67 + virtual const Matrix4x4 &get_local_matrix() const; 16.68 16.69 // for bone nodes, the transformation of the bone in bind position 16.70 - void set_bone_matrix(const Matrix4x4 &bmat); 16.71 - const Matrix4x4 &get_bone_matrix() const; 16.72 + virtual void set_bone_matrix(const Matrix4x4 &bmat); 16.73 + virtual const Matrix4x4 &get_bone_matrix() const; 16.74 16.75 // node transformation alone 16.76 - void get_node_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const; 16.77 + virtual void get_node_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const; 16.78 16.79 // node transformation taking hierarchy into account 16.80 - void get_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const; 16.81 + virtual void get_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat = 0) const; 16.82 }; 16.83 16.84