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