conworlds

diff src/object.cc @ 13:283cdfa7dda2

added a crapload of code from goat3dgfx
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 24 Aug 2014 09:41:24 +0300
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/object.cc	Sun Aug 24 09:41:24 2014 +0300
     1.3 @@ -0,0 +1,285 @@
     1.4 +#include <float.h>
     1.5 +#include "object.h"
     1.6 +#include "opengl.h"
     1.7 +#include "unistate.h"
     1.8 +#include "logger.h"
     1.9 +
    1.10 +
    1.11 +static void destroy_all_rec(XFormNode *node);
    1.12 +static void get_all_meshes_rec(XFormNode *node, std::list<Mesh*> *reslist);
    1.13 +
    1.14 +DrawMode Object::draw_mode = DRAW_DEFAULT;
    1.15 +
    1.16 +Object::Object()
    1.17 +{
    1.18 +	mesh = 0;
    1.19 +}
    1.20 +
    1.21 +void Object::destroy_all()
    1.22 +{
    1.23 +	destroy_all_rec(this);
    1.24 +}
    1.25 +
    1.26 +static void destroy_all_rec(XFormNode *node)
    1.27 +{
    1.28 +	if(!node) {
    1.29 +		return;
    1.30 +	}
    1.31 +
    1.32 +	for(int i=0; i<node->get_children_count(); i++) {
    1.33 +		destroy_all_rec(node->get_child(i));
    1.34 +	}
    1.35 +	delete node;
    1.36 +}
    1.37 +
    1.38 +void Object::set_mesh(Mesh *m)
    1.39 +{
    1.40 +	mesh = m;
    1.41 +}
    1.42 +
    1.43 +Mesh *Object::get_mesh()
    1.44 +{
    1.45 +	return mesh;
    1.46 +}
    1.47 +
    1.48 +const Mesh *Object::get_mesh() const
    1.49 +{
    1.50 +	return mesh;
    1.51 +}
    1.52 +
    1.53 +std::list<Mesh*> Object::get_all_meshes()
    1.54 +{
    1.55 +	std::list<Mesh*> meshes;
    1.56 +	get_all_meshes_rec(this, &meshes);
    1.57 +	return meshes;
    1.58 +}
    1.59 +
    1.60 +std::list<const Mesh*> Object::get_all_meshes() const
    1.61 +{
    1.62 +	std::list<const Mesh*> meshes;
    1.63 +	get_all_meshes_rec((Object*)this, (std::list<Mesh*>*)&meshes);
    1.64 +	return meshes;
    1.65 +}
    1.66 +
    1.67 +static void get_all_meshes_rec(XFormNode *node, std::list<Mesh*> *reslist)
    1.68 +{
    1.69 +	if(!node) {
    1.70 +		return;
    1.71 +	}
    1.72 +
    1.73 +	Object *obj = dynamic_cast<Object*>(node);
    1.74 +	if(obj) {
    1.75 +		Mesh *mesh = obj->get_mesh();
    1.76 +		if(mesh) {
    1.77 +			reslist->push_back(mesh);
    1.78 +		}
    1.79 +	}
    1.80 +
    1.81 +	for(int i=0; i<node->get_children_count(); i++) {
    1.82 +		get_all_meshes_rec(node->get_child(i), reslist);
    1.83 +	}
    1.84 +}
    1.85 +
    1.86 +AABox Object::get_aabbox() const
    1.87 +{
    1.88 +	AABox box;
    1.89 +
    1.90 +	if(mesh) {
    1.91 +		box = mesh->get_aabbox();
    1.92 +	} else {
    1.93 +		box.min = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
    1.94 +		box.max = -box.min;
    1.95 +	}
    1.96 +
    1.97 +	int num_children = get_children_count();
    1.98 +	for(int i=0; i<num_children; i++) {
    1.99 +		const Object *obj = dynamic_cast<const Object*>(get_child(i));
   1.100 +		if(obj) {
   1.101 +			AABox child_box = obj->get_aabbox();
   1.102 +			box.set_union(&box, &child_box);
   1.103 +		}
   1.104 +	}
   1.105 +	return box;
   1.106 +}
   1.107 +
   1.108 +Sphere Object::get_bsphere() const
   1.109 +{
   1.110 +	Sphere sph;
   1.111 +	bool valid = false;
   1.112 +
   1.113 +	if(mesh) {
   1.114 +		sph = mesh->get_bsphere();
   1.115 +		valid = true;
   1.116 +	} else {
   1.117 +		sph.radius = 0.0;
   1.118 +	}
   1.119 +
   1.120 +	int num_children = get_children_count();
   1.121 +	for(int i=0; i<num_children; i++) {
   1.122 +		const Object *obj = dynamic_cast<const Object*>(get_child(i));
   1.123 +		if(obj) {
   1.124 +			Sphere child_sph = obj->get_bsphere();
   1.125 +			if(valid) {
   1.126 +				sph.set_union(&sph, &child_sph);
   1.127 +			} else {
   1.128 +				sph = child_sph;
   1.129 +				valid = true;
   1.130 +			}
   1.131 +		}
   1.132 +	}
   1.133 +
   1.134 +	return sph;
   1.135 +}
   1.136 +
   1.137 +/*static const char *attr_name[] = {
   1.138 +	"attr_vertex",
   1.139 +	"attr_normal",
   1.140 +	"attr_tangent",
   1.141 +	"attr_texcoord",
   1.142 +	"attr_boneweights",
   1.143 +	"attr_boneidx"
   1.144 +};*/
   1.145 +
   1.146 +void Object::draw(long msec) const
   1.147 +{
   1.148 +	Matrix4x4 xform;
   1.149 +	get_xform(msec, &xform);
   1.150 +
   1.151 +	set_world_matrix(xform);
   1.152 +
   1.153 +	if(mesh) {
   1.154 +		/*unsigned int prog = sdrprog;
   1.155 +
   1.156 +		if(mesh->get_bones_count() > 0) {
   1.157 +			prog = sdrprog_skin;
   1.158 +		}
   1.159 +
   1.160 +		glUseProgram(prog);
   1.161 +		// get all the attribute locations
   1.162 +		for(int i=0; i<NUM_MESH_ATTR; i++) {
   1.163 +			int loc = glGetAttribLocation(prog, attr_name[i]);
   1.164 +			if(loc != -1) {
   1.165 +				Mesh::set_attrib_location(i, loc);
   1.166 +			}
   1.167 +		}
   1.168 +
   1.169 +		setup_bones(msec);
   1.170 +
   1.171 +		glUseProgram(prog);*/
   1.172 +
   1.173 +		material.setup();
   1.174 +		setup_unistate();	// set all state uniforms
   1.175 +
   1.176 +		switch(Object::draw_mode) {
   1.177 +		case DRAW_WIREFRAME:
   1.178 +			mesh->draw_wire();
   1.179 +			break;
   1.180 +
   1.181 +		case DRAW_VERTICES:
   1.182 +			mesh->draw_vertices();
   1.183 +			break;
   1.184 +
   1.185 +		case DRAW_DEFAULT:
   1.186 +		default:
   1.187 +			mesh->draw();
   1.188 +		}
   1.189 +	}
   1.190 +
   1.191 +	int num_children = get_children_count();
   1.192 +	for(int i=0; i<num_children; i++) {
   1.193 +		const Object *obj = dynamic_cast<const Object*>(get_child(i));
   1.194 +		if(obj) {
   1.195 +			obj->draw(msec);
   1.196 +		}
   1.197 +	}
   1.198 +}
   1.199 +
   1.200 +
   1.201 +bool Object::intersect(const Ray &inray, HitPoint *hit) const
   1.202 +{
   1.203 +	Ray ray = inray;
   1.204 +	Matrix4x4 xform, inv_xform;
   1.205 +	get_xform(ray.time, &xform/*, &inv_xform*/);
   1.206 +	ray.transform(xform.inverse());	// TODO find out what's wrong with get_xform's inv_xform and use that
   1.207 +
   1.208 +	HitPoint nearest_hit;
   1.209 +	nearest_hit.dist = FLT_MAX;
   1.210 +	nearest_hit.obj = 0;
   1.211 +
   1.212 +	if(mesh) {
   1.213 +		if(mesh->intersect(ray, hit ? &nearest_hit : 0)) {
   1.214 +			if(!hit) {
   1.215 +				return true;
   1.216 +			}
   1.217 +
   1.218 +			if(Mesh::get_intersect_mode() & ISECT_FACE) {
   1.219 +				Triangle *face = (Triangle*)nearest_hit.obj;
   1.220 +				face->transform(xform);
   1.221 +			} else if(Mesh::get_intersect_mode() & ISECT_VERTICES) {
   1.222 +				Vector3 *v = (Vector3*)nearest_hit.obj;
   1.223 +				v->transform(xform);
   1.224 +			} else {
   1.225 +				nearest_hit.obj = this;
   1.226 +			}
   1.227 +		}
   1.228 +	}
   1.229 +
   1.230 +	int num_children = get_children_count();
   1.231 +	for(int i=0; i<num_children; i++) {
   1.232 +		const Object *obj = dynamic_cast<const Object*>(get_child(i));
   1.233 +
   1.234 +		HitPoint chit;
   1.235 +		if(obj && obj->intersect(inray, hit ? &chit : 0)) {
   1.236 +			if(!hit) {
   1.237 +				return true;
   1.238 +			}
   1.239 +
   1.240 +			if(chit.dist < nearest_hit.dist) {
   1.241 +				nearest_hit = chit;
   1.242 +			}
   1.243 +		}
   1.244 +	}
   1.245 +
   1.246 +	if(nearest_hit.obj) {
   1.247 +		if(hit) {
   1.248 +			*hit = nearest_hit;
   1.249 +		}
   1.250 +		return true;
   1.251 +	}
   1.252 +	return false;
   1.253 +}
   1.254 +
   1.255 +
   1.256 +bool Object::setup_bones(long msec) const
   1.257 +{
   1.258 +	int num_bones;
   1.259 +	if(!mesh || !(num_bones = mesh->get_bones_count())) {
   1.260 +		return false;
   1.261 +	}
   1.262 +
   1.263 +	/*char uniname[32];
   1.264 +
   1.265 +	for(int i=0; i<num_bones; i++) {
   1.266 +		const XFormNode *bone = mesh->get_bone(i);
   1.267 +
   1.268 +		Matrix4x4 xform;
   1.269 +		bone->get_xform(msec, &xform);
   1.270 +
   1.271 +		xform = xform * bone->get_bone_matrix();
   1.272 +
   1.273 +		sprintf(uniname, "bone_xform[%d]", i);
   1.274 +		int loc = glGetUniformLocation(sdrprog_skin, uniname);
   1.275 +		if(loc == -1) {
   1.276 +			return false;
   1.277 +		}
   1.278 +		glUniformMatrix4fv(loc, 1, GL_TRUE, xform[0]);
   1.279 +	}*/
   1.280 +	return true;
   1.281 +}
   1.282 +
   1.283 +DrawMode Object::set_draw_mode(DrawMode mode)
   1.284 +{
   1.285 +	DrawMode prev = Object::draw_mode;
   1.286 +	Object::draw_mode = mode;
   1.287 +	return prev;
   1.288 +}