]> git.tdb.fi Git - libs/gl.git/blobdiff - source/object.cpp
Support the sample sampling qualifier
[libs/gl.git] / source / object.cpp
index fe1690d267ee3e2a433d832dc388e72ae15f66e9..1852f91b50222ead401dfa177605c31d9d1ee21b 100644 (file)
@@ -17,19 +17,26 @@ 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);
 }
@@ -50,15 +57,19 @@ Object::LevelOfDetail &Object::get_lod(unsigned i, const char *caller)
 void Object::set_mesh(unsigned i, const Mesh *m)
 {
        RefPtr<const Mesh> &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);
        ptr = m;
        ptr.keep();
+       lod0_watched = false;
 
        if(i==0 && m)
                if(ResourceManager *rm = m->get_manager())
+               {
                        rm->watch_resource(*m, *this);
+                       lod0_watched = true;
+               }
 
        update_bounding_sphere();
 }
@@ -68,7 +79,7 @@ void Object::update_bounding_sphere()
        vector<Vector3> points;
        for(vector<LevelOfDetail>::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<float, 3>::from_point_cloud(points.begin(), points.end());
 }
 
@@ -118,21 +134,6 @@ 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);
@@ -180,6 +181,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 +202,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 +211,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<float, 3>(Vector3(x, y, z), r);
+}
+
 void Object::Loader::level_of_detail(unsigned i)
 {
        LodLoader ldr(obj, i, coll);