X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fobject.cpp;h=dc1f4f3f1a7996bd55008732df21c0c826f27af5;hb=bec07999d95b76f4b47cffcc564d0cd0afc0435e;hp=fe1690d267ee3e2a433d832dc388e72ae15f66e9;hpb=5b532dcb2a4a2d15d0b6607374284c979ece36a8;p=libs%2Fgl.git diff --git a/source/object.cpp b/source/object.cpp index fe1690d2..dc1f4f3f 100644 --- a/source/object.cpp +++ b/source/object.cpp @@ -17,21 +17,28 @@ using namespace std; namespace Msp { namespace GL { +Matrix Object::identity_matrix; + Object::Object(): - lods(1) + lods(1), + lod0_watched(false) { } -Object::Object(const Mesh *m, const Technique *t) +Object::Object(const Mesh *m, const Technique *t): + lods(1), + lod0_watched(false) { set_mesh(m); set_technique(t); } +// TODO should have copy-c'tor to set watch on lod0 mesh if necessary + Object::~Object() { - if(lods[0].mesh) + if(lods[0].mesh && lod0_watched) if(ResourceManager *rm = lods[0].mesh->get_manager()) - rm->unwatch_resource(*lods[0].mesh, *this); + rm->unobserve_resource(*lods[0].mesh, *this); } Object::LevelOfDetail &Object::get_lod(unsigned i, const char *caller) @@ -50,15 +57,19 @@ Object::LevelOfDetail &Object::get_lod(unsigned i, const char *caller) void Object::set_mesh(unsigned i, const Mesh *m) { RefPtr &ptr = get_lod(i, "Object::set_mesh").mesh; - if(i==0 && ptr) + if(i==0 && ptr && lod0_watched) if(ResourceManager *rm = ptr->get_manager()) - rm->unwatch_resource(*ptr, *this); + rm->unobserve_resource(*ptr, *this); ptr = m; ptr.keep(); + lod0_watched = false; if(i==0 && m) if(ResourceManager *rm = m->get_manager()) - rm->watch_resource(*m, *this); + { + rm->observe_resource(*m, *this); + lod0_watched = true; + } update_bounding_sphere(); } @@ -68,7 +79,7 @@ void Object::update_bounding_sphere() vector points; for(vector::const_iterator i=lods.begin(); i!=lods.end(); ++i) { - if(!i->mesh) + if(!i->mesh || !i->mesh->is_loaded()) continue; const VertexArray &vertices = i->mesh->get_vertices(); @@ -92,6 +103,11 @@ void Object::update_bounding_sphere() } } + /* Don't touch the bounding sphere if we had no vertices to avoid + overwriting a possible hint. */ + if(points.empty()) + return; + bounding_sphere = Geometry::BoundingSphere::from_point_cloud(points.begin(), points.end()); } @@ -118,32 +134,21 @@ const Technique *Object::get_technique(unsigned i) const return lods[i].technique.get(); } -void Object::render(const Tag &tag) const -{ - const RenderPass *pass = get_pass(tag, 0); - if(!pass) - return; - - Bind bind_shader(pass->get_shader_program()); - if(pass->get_shader_data()) - pass->get_shader_data()->apply(); - Bind bind_material(pass->get_material()); - Bind bind_texturing(pass->get_texturing()); - - lods.front().mesh->draw(); -} - void Object::render(Renderer &renderer, const Tag &tag) const { const RenderPass *pass = get_pass(tag, 0); if(!pass) return; + const Mesh *mesh = lods.front().mesh.get(); + if (!mesh) + throw logic_error("no mesh"); + Renderer::Push push(renderer); pass->apply(renderer); setup_render(renderer, tag); - lods.front().mesh->draw(renderer); + mesh->draw(renderer); finish_render(renderer, tag); } @@ -154,12 +159,16 @@ void Object::render(Renderer &renderer, const ObjectInstance &inst, const Tag &t if(!pass) return; + const Mesh *mesh = lods[lod].mesh.get(); + if (!mesh) + throw logic_error("no mesh"); + Renderer::Push push(renderer); pass->apply(renderer); setup_render(renderer, tag); inst.setup_render(renderer, tag); - lods[lod].mesh->draw(renderer); + mesh->draw(renderer); inst.finish_render(renderer, tag); finish_render(renderer, tag); } @@ -169,9 +178,7 @@ const RenderPass *Object::get_pass(const Tag &tag, unsigned lod) const const Technique *tech = lods[lod].technique.get(); if(!tech) throw logic_error("no technique"); - if(!tech->has_pass(tag)) - return 0; - return &tech->get_pass(tag); + return tech->find_pass(tag); } void Object::resource_loaded(Resource &res) @@ -180,6 +187,12 @@ void Object::resource_loaded(Resource &res) update_bounding_sphere(); } +void Object::resource_removed(Resource &res) +{ + if(&res==lods.front().mesh.get()) + lod0_watched = false; +} + Object::Loader::Loader(Object &o): LodLoader(o, 0, 0) @@ -195,6 +208,7 @@ Object::Loader::Loader(Object &o, Collection &c): void Object::Loader::init() { + add("bounding_sphere_hint", &Loader::bounding_sphere_hint); add("level_of_detail", &Loader::level_of_detail); } @@ -203,6 +217,11 @@ void Object::Loader::finish() obj.update_bounding_sphere(); } +void Object::Loader::bounding_sphere_hint(float x, float y, float z, float r) +{ + obj.bounding_sphere = Geometry::BoundingSphere(Vector3(x, y, z), r); +} + void Object::Loader::level_of_detail(unsigned i) { LodLoader ldr(obj, i, coll);