/* render/model.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "sys/sys.h" #include "auxiliary/functions.h" #include "model/model.h" #include "model/asefile.h" #include "model/mapfile.h" #include "model/objfile.h" #include "model/vertexarray.h" namespace model { // static model registry Model::Registry Model::model_registry; Model::Model(const std::string & name) : model_enginecolor(1.0f, 0.0f, 0.0f), model_name(name) { model_radius = 0.5f; model_enginesound = 0; model_impulsesound = 0; model_tris_detail_count = 0; model_tris_count = 0; model_quad_detail_count = 0; model_quad_count = 0; model_collisionmodel = 0; } Model::~Model() { // delete all fragment groups for (Groups::iterator git = model_groups.begin(); git != model_groups.end(); ++git) { delete(*git); } model_groups.clear(); // delete all slots for (Slots::iterator slit = model_slots.begin(); slit != model_slots.end(); ++slit) { delete(*slit); } model_slots.clear(); // delete all particle systems for (Model::ParticleSystems::iterator pit = model_particles.begin(); pit != model_particles.end(); ++pit) { delete(*pit); } model_particles.clear(); // delete all lights for (Lights::iterator lit = model_lights.begin(); lit != model_lights.end(); ++lit) { delete(*lit); } model_lights.clear(); // delete all flares for (Flares::iterator flit = model_flares.begin(); flit != model_flares.end(); ++flit) { delete(*flit); } model_flares.clear(); // delete all sound tags for (Sounds::iterator sit = model_sounds.begin(); sit != model_sounds.end(); ++sit) { delete (*sit); } model_sounds.clear(); } void Model::set_collisionmodel(CollisionModel *collisionmodel) { model_collisionmodel = collisionmodel; } void Model::set_origin(const math::Vector3f &origin) { model_origin.assign(origin); } void Model::set_radius(const float radius) { model_radius = radius; } void Model::add_particles(Particles *particles) { model_particles.push_back(particles); } void Model::add_group(FragmentGroup *group) { model_groups.push_back(group); } void Model::add_light(Light *light) { model_lights.push_back(light); } void Model::add_flare(Flare *flare) { model_flares.push_back(flare); } void Model::add_sound(Sound *sound) { model_sounds.push_back(sound); } void Model::add_slot(Slot *slot) { model_slots.push_back(slot); } void Model::print() const { } bool compare_tag_location(const Tag *first, const Tag *second) { if (!first) { return true; } else if (!second) { return true; } if (first->location().x() > second->location().x()) { return true; } else if (first->location().x() < second->location().x()) { return false; } else if (first->location().y() > second->location().y()) { return true; } else if (first->location().y() < second->location().y()) { return false; } else if (first->location().z() < second->location().z()) { return false; } else { return true; } } bool compare_tag_location_front(const Tag *first, const Tag *second) { if (!first) { return true; } else if (!second) { return true; } if (first->location().x() > second->location().x()) { return true; } else if (first->location().x() < second->location().x()) { return false; } else if (first->location().y() > second->location().y()) { return false; } else if (first->location().y() < second->location().y()) { return true; } else if (first->location().z() < second->location().z()) { return false; } else { return true; } } void Model::sort() { model_slots.sort(compare_tag_location_front); model_particles.sort(compare_tag_location); model_lights.sort(compare_tag_location); model_flares.sort(compare_tag_location); model_sounds.sort(compare_tag_location); } Model *Model::find(const std::string & name) { Registry::iterator it = model_registry.find(name); if (it == model_registry.end()) return 0; else return (*it).second; } Model *Model::search(const std::string & searchname) { std::string strsearchkey(aux::lowercase(searchname)); std::stringstream str(strsearchkey); if (strsearchkey.size() < 3) { return 0; } for (Registry::iterator it = model_registry.begin(); it != model_registry.end(); ++it) { std::string label((*it).first); Model *model= (*it).second; if (label.size() && (label.find(strsearchkey) != std::string::npos)) { return model; } } return 0; } Model *Model::load(const std::string & name) { Model *model = find(name); if (!model) { // try loading the .map model model = MapFile::load(name); } if (!model) { // if it can't be found, try the ase model model = ASEFile::load(name); } if (!model) { // if it can't be found, try the obj model model = OBJFile::load(name); } if (!model) { con_warn << "Could not open model " << name << std::endl; } else { // sort model tags model->sort(); // add model to registry model_registry[model->name()] = model; } return model; } void Model::clear() { // delete all models in the registry for (Registry::iterator mit = model_registry.begin(); mit != model_registry.end(); ++mit) { delete(*mit).second; } model_registry.clear(); // clear the vertex array if (VertexArray::instance()) VertexArray::instance()->clear(); } void Model::list() { for (Registry::iterator mit = model_registry.begin(); mit != model_registry.end(); ++mit) { Model *model = (*mit).second; size_t frags = 0; for (Groups::iterator git = model->groups().begin(); git != model->groups().end(); ++git) { frags += (*git)->size(); } con_print << " " << model->name() << " " << frags << " frags " << model->model_tris_detail_count << "/" << model->model_tris_count << " detail/tris " << model->model_quad_detail_count << "/" << model->model_quad_count << " detail/quads " << "radius " << model->radius() << std::endl; } if (VertexArray::instance()) { VertexArray::instance()->info(); } con_print << "^B " << model_registry.size() << " registered models" << std::endl; } }