nuclear@0: #include nuclear@0: #include "object.h" nuclear@0: #include "opengl.h" nuclear@0: #include "unistate.h" nuclear@0: #include "logger.h" nuclear@0: nuclear@15: using namespace goatgfx; nuclear@15: nuclear@0: static void destroy_all_rec(XFormNode *node); nuclear@0: static void get_all_meshes_rec(XFormNode *node, std::list *reslist); nuclear@0: nuclear@0: DrawMode Object::draw_mode = DRAW_DEFAULT; nuclear@0: nuclear@0: Object::Object() nuclear@0: { nuclear@0: mesh = 0; nuclear@0: } nuclear@0: nuclear@0: void Object::destroy_all() nuclear@0: { nuclear@0: destroy_all_rec(this); nuclear@0: } nuclear@0: nuclear@0: static void destroy_all_rec(XFormNode *node) nuclear@0: { nuclear@0: if(!node) { nuclear@0: return; nuclear@0: } nuclear@0: nuclear@0: for(int i=0; iget_children_count(); i++) { nuclear@0: destroy_all_rec(node->get_child(i)); nuclear@0: } nuclear@0: delete node; nuclear@0: } nuclear@0: nuclear@0: void Object::set_mesh(Mesh *m) nuclear@0: { nuclear@0: mesh = m; nuclear@0: } nuclear@0: nuclear@0: Mesh *Object::get_mesh() nuclear@0: { nuclear@0: return mesh; nuclear@0: } nuclear@0: nuclear@0: const Mesh *Object::get_mesh() const nuclear@0: { nuclear@0: return mesh; nuclear@0: } nuclear@0: nuclear@0: std::list Object::get_all_meshes() nuclear@0: { nuclear@0: std::list meshes; nuclear@0: get_all_meshes_rec(this, &meshes); nuclear@0: return meshes; nuclear@0: } nuclear@0: nuclear@0: std::list Object::get_all_meshes() const nuclear@0: { nuclear@0: std::list meshes; nuclear@0: get_all_meshes_rec((Object*)this, (std::list*)&meshes); nuclear@0: return meshes; nuclear@0: } nuclear@0: nuclear@0: static void get_all_meshes_rec(XFormNode *node, std::list *reslist) nuclear@0: { nuclear@0: if(!node) { nuclear@0: return; nuclear@0: } nuclear@0: nuclear@0: Object *obj = dynamic_cast(node); nuclear@0: if(obj) { nuclear@0: Mesh *mesh = obj->get_mesh(); nuclear@0: if(mesh) { nuclear@0: reslist->push_back(mesh); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: for(int i=0; iget_children_count(); i++) { nuclear@0: get_all_meshes_rec(node->get_child(i), reslist); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: AABox Object::get_aabbox() const nuclear@0: { nuclear@0: AABox box; nuclear@0: nuclear@0: if(mesh) { nuclear@0: box = mesh->get_aabbox(); nuclear@0: } else { nuclear@0: box.min = Vector3(FLT_MAX, FLT_MAX, FLT_MAX); nuclear@0: box.max = -box.min; nuclear@0: } nuclear@0: nuclear@0: int num_children = get_children_count(); nuclear@0: for(int i=0; i(get_child(i)); nuclear@0: if(obj) { nuclear@0: AABox child_box = obj->get_aabbox(); nuclear@0: box.set_union(&box, &child_box); nuclear@0: } nuclear@0: } nuclear@0: return box; nuclear@0: } nuclear@0: nuclear@0: Sphere Object::get_bsphere() const nuclear@0: { nuclear@0: Sphere sph; nuclear@0: bool valid = false; nuclear@0: nuclear@0: if(mesh) { nuclear@0: sph = mesh->get_bsphere(); nuclear@0: valid = true; nuclear@0: } else { nuclear@0: sph.radius = 0.0; nuclear@0: } nuclear@0: nuclear@0: int num_children = get_children_count(); nuclear@0: for(int i=0; i(get_child(i)); nuclear@0: if(obj) { nuclear@0: Sphere child_sph = obj->get_bsphere(); nuclear@0: if(valid) { nuclear@0: sph.set_union(&sph, &child_sph); nuclear@0: } else { nuclear@0: sph = child_sph; nuclear@0: valid = true; nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: return sph; nuclear@0: } nuclear@0: nuclear@0: /*static const char *attr_name[] = { nuclear@0: "attr_vertex", nuclear@0: "attr_normal", nuclear@0: "attr_tangent", nuclear@0: "attr_texcoord", nuclear@0: "attr_boneweights", nuclear@0: "attr_boneidx" nuclear@0: };*/ nuclear@0: nuclear@0: void Object::draw(long msec) const nuclear@0: { nuclear@0: Matrix4x4 xform; nuclear@0: get_xform(msec, &xform); nuclear@0: nuclear@0: set_world_matrix(xform); nuclear@0: nuclear@0: if(mesh) { nuclear@0: /*unsigned int prog = sdrprog; nuclear@0: nuclear@0: if(mesh->get_bones_count() > 0) { nuclear@0: prog = sdrprog_skin; nuclear@0: } nuclear@0: nuclear@0: glUseProgram(prog); nuclear@0: // get all the attribute locations nuclear@0: for(int i=0; idraw_wire(); nuclear@0: break; nuclear@0: nuclear@0: case DRAW_VERTICES: nuclear@0: mesh->draw_vertices(); nuclear@0: break; nuclear@0: nuclear@0: case DRAW_DEFAULT: nuclear@0: default: nuclear@0: mesh->draw(); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: int num_children = get_children_count(); nuclear@0: for(int i=0; i(get_child(i)); nuclear@0: if(obj) { nuclear@0: obj->draw(msec); nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: nuclear@0: bool Object::intersect(const Ray &inray, HitPoint *hit) const nuclear@0: { nuclear@0: Ray ray = inray; nuclear@0: Matrix4x4 xform, inv_xform; nuclear@0: get_xform(ray.time, &xform/*, &inv_xform*/); nuclear@0: ray.transform(xform.inverse()); // TODO find out what's wrong with get_xform's inv_xform and use that nuclear@0: nuclear@0: HitPoint nearest_hit; nuclear@0: nearest_hit.dist = FLT_MAX; nuclear@0: nearest_hit.obj = 0; nuclear@0: nuclear@0: if(mesh) { nuclear@0: if(mesh->intersect(ray, hit ? &nearest_hit : 0)) { nuclear@0: if(!hit) { nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: if(Mesh::get_intersect_mode() & ISECT_FACE) { nuclear@0: Triangle *face = (Triangle*)nearest_hit.obj; nuclear@0: face->transform(xform); nuclear@0: } else if(Mesh::get_intersect_mode() & ISECT_VERTICES) { nuclear@0: Vector3 *v = (Vector3*)nearest_hit.obj; nuclear@0: v->transform(xform); nuclear@0: } else { nuclear@0: nearest_hit.obj = this; nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: int num_children = get_children_count(); nuclear@0: for(int i=0; i(get_child(i)); nuclear@0: nuclear@0: HitPoint chit; nuclear@0: if(obj && obj->intersect(inray, hit ? &chit : 0)) { nuclear@0: if(!hit) { nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: if(chit.dist < nearest_hit.dist) { nuclear@0: nearest_hit = chit; nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: if(nearest_hit.obj) { nuclear@0: if(hit) { nuclear@0: *hit = nearest_hit; nuclear@0: } nuclear@0: return true; nuclear@0: } nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: bool Object::setup_bones(long msec) const nuclear@0: { nuclear@0: int num_bones; nuclear@0: if(!mesh || !(num_bones = mesh->get_bones_count())) { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: /*char uniname[32]; nuclear@0: nuclear@0: for(int i=0; iget_bone(i); nuclear@0: nuclear@0: Matrix4x4 xform; nuclear@0: bone->get_xform(msec, &xform); nuclear@0: nuclear@0: xform = xform * bone->get_bone_matrix(); nuclear@0: nuclear@0: sprintf(uniname, "bone_xform[%d]", i); nuclear@0: int loc = glGetUniformLocation(sdrprog_skin, uniname); nuclear@0: if(loc == -1) { nuclear@0: return false; nuclear@0: } nuclear@0: glUniformMatrix4fv(loc, 1, GL_TRUE, xform[0]); nuclear@0: }*/ nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: DrawMode Object::set_draw_mode(DrawMode mode) nuclear@0: { nuclear@0: DrawMode prev = Object::draw_mode; nuclear@0: Object::draw_mode = mode; nuclear@0: return prev; nuclear@0: }