X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fobject.cpp;h=1852f91b50222ead401dfa177605c31d9d1ee21b;hp=dc1f4f3f1a7996bd55008732df21c0c826f27af5;hb=HEAD;hpb=b13f1bced27e0ad3e4661e645f6bafed38359120 diff --git a/source/object.cpp b/source/object.cpp deleted file mode 100644 index dc1f4f3f..00000000 --- a/source/object.cpp +++ /dev/null @@ -1,271 +0,0 @@ -#include -#include -#include "error.h" -#include "material.h" -#include "mesh.h" -#include "object.h" -#include "objectinstance.h" -#include "program.h" -#include "programdata.h" -#include "renderer.h" -#include "resourcemanager.h" -#include "technique.h" -#include "texturing.h" - -using namespace std; - -namespace Msp { -namespace GL { - -Matrix Object::identity_matrix; - -Object::Object(): - lods(1), - lod0_watched(false) -{ } - -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 && lod0_watched) - if(ResourceManager *rm = lods[0].mesh->get_manager()) - rm->unobserve_resource(*lods[0].mesh, *this); -} - -Object::LevelOfDetail &Object::get_lod(unsigned i, const char *caller) -{ - if(i>lods.size()) - throw out_of_range(caller); - if(i>0 && (!lods[0].mesh || !lods[0].technique)) - throw invalid_operation(caller); - - if(i==lods.size()) - lods.push_back(lods.back()); - - return lods[i]; -} - -void Object::set_mesh(unsigned i, const Mesh *m) -{ - RefPtr &ptr = get_lod(i, "Object::set_mesh").mesh; - if(i==0 && ptr && lod0_watched) - if(ResourceManager *rm = ptr->get_manager()) - rm->unobserve_resource(*ptr, *this); - ptr = m; - ptr.keep(); - lod0_watched = false; - - if(i==0 && m) - if(ResourceManager *rm = m->get_manager()) - { - rm->observe_resource(*m, *this); - lod0_watched = true; - } - - update_bounding_sphere(); -} - -void Object::update_bounding_sphere() -{ - vector points; - for(vector::const_iterator i=lods.begin(); i!=lods.end(); ++i) - { - if(!i->mesh || !i->mesh->is_loaded()) - continue; - - const VertexArray &vertices = i->mesh->get_vertices(); - - int offset = vertices.get_format().offset(VERTEX3); - bool three = true; - if(offset<0) - { - offset = vertices.get_format().offset(VERTEX2); - three = false; - if(offset<0) - continue; - } - - unsigned n_vertices = vertices.size(); - points.reserve(points.size()+n_vertices); - for(unsigned j=0; j::from_point_cloud(points.begin(), points.end()); -} - -const Mesh *Object::get_mesh(unsigned i) const -{ - if(i>=lods.size()) - return 0; - - return lods[i].mesh.get(); -} - -void Object::set_technique(unsigned i, const Technique *t) -{ - RefPtr &ptr = get_lod(i, "Object::set_technique").technique; - ptr = t; - ptr.keep(); -} - -const Technique *Object::get_technique(unsigned i) const -{ - if(i>=lods.size()) - return 0; - - return lods[i].technique.get(); -} - -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); - mesh->draw(renderer); - finish_render(renderer, tag); -} - -void Object::render(Renderer &renderer, const ObjectInstance &inst, const Tag &tag) const -{ - unsigned lod = min(inst.get_level_of_detail(renderer), lods.size()-1); - const RenderPass *pass = get_pass(tag, lod); - 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); - mesh->draw(renderer); - inst.finish_render(renderer, tag); - finish_render(renderer, tag); -} - -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"); - return tech->find_pass(tag); -} - -void Object::resource_loaded(Resource &res) -{ - if(&res==lods.front().mesh.get() && bounding_sphere.is_empty()) - 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) -{ - init(); -} - -Object::Loader::Loader(Object &o, Collection &c): - LodLoader(o, 0, &c) -{ - init(); -} - -void Object::Loader::init() -{ - add("bounding_sphere_hint", &Loader::bounding_sphere_hint); - add("level_of_detail", &Loader::level_of_detail); -} - -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); - load_sub_with(ldr); -} - - -Object::LodLoader::LodLoader(Object &o, unsigned i, Collection *c): - DataFile::CollectionObjectLoader(o, c), - index(i), - lod(obj.get_lod(index, "Object::LodLoader::LodLoader")) -{ - add("mesh", &LodLoader::mesh_inline); - add("mesh", &LodLoader::mesh); - add("technique", &LodLoader::technique_inline); - add("technique", &LodLoader::technique); -} - -void Object::LodLoader::mesh(const string &n) -{ - obj.set_mesh(index, &get_collection().get(n)); -} - -void Object::LodLoader::mesh_inline() -{ - RefPtr msh = new Mesh; - load_sub(*msh); - lod.mesh = msh; -} - -void Object::LodLoader::technique(const std::string &n) -{ - obj.set_technique(index, &get_collection().get(n)); -} - -void Object::LodLoader::technique_inline() -{ - RefPtr tech = new Technique; - if(coll) - load_sub(*tech, get_collection()); - else - load_sub(*tech); - lod.technique = tech; -} - -} // namespace GL -} // namespace Msp