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