From 2c98d3eef488233b99a76ca44d69c1c9d53404af Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 7 Dec 2014 16:12:49 +0000 Subject: Cleanup of the slots code, unified model weapon and dock tags into a single slots list, load dock tags into entity slots, represent entity slot locations in entity coordinate space, have r_slots render fixed-size slot indicators regardless of model scale. --- src/core/slot.cc | 39 +++++++----- src/core/slot.h | 49 +++++++++++---- src/core/slots.cc | 23 +++++-- src/core/slots.h | 2 +- src/game/base/game.cc | 4 +- src/game/base/patrol.cc | 17 ++---- src/game/base/platform.cc | 12 ++-- src/game/base/ship.cc | 40 ++++++++----- src/game/base/weapon.h | 8 +-- src/model/mapfile.cc | 68 +++++++++------------ src/model/model.cc | 26 +++----- src/model/model.h | 33 ++++------- src/model/tags.cc | 52 +++++++--------- src/model/tags.h | 148 ++++++++++++++++------------------------------ src/render/draw.cc | 106 ++++++++++++++++----------------- 15 files changed, 292 insertions(+), 335 deletions(-) diff --git a/src/core/slot.cc b/src/core/slot.cc index 58bb51c..8907097 100644 --- a/src/core/slot.cc +++ b/src/core/slot.cc @@ -12,17 +12,36 @@ namespace core { Slot::Slot() +{ + clear(); +} + +Slot::~Slot() +{ +} + +void Slot::load(const model::Slot *slot_tag, const float modelscale) +{ + if (slot_tag) { + set_type(slot_tag->type()); + set_location(slot_tag->location() * modelscale); + set_axis(slot_tag->axis()); + set_radius(slot_tag->radius()); + set_cone(slot_tag->cone() * M_PI / 180.0f); + } else { + Slot(); + } +} + +void Slot::clear() { slot_item = 0; slot_flags = 0; slot_timestamp = 0; slot_last_fired = 0; slot_cone = 0; - slot_type = model::Weapon::Cannon; -} - -Slot::~Slot() -{ + slot_radius = 1.0f; + slot_type = model::Slot::None; } void Slot::set_flag(const Flags flag) @@ -43,14 +62,4 @@ void Slot::set_item(Item *item) set_timestamp(game() ? game()->timestamp() : 1); } -void Slot::load(const model::Weapon * weapon_tag) -{ - if (weapon_tag) { - set_type(weapon_tag->type()); - set_cone(weapon_tag->cone() * M_PI / 180.0f); - set_location(weapon_tag->location()); - set_axis(weapon_tag->axis()); - } -} - } // namespace core diff --git a/src/core/slot.h b/src/core/slot.h index 5466de8..99353ee 100644 --- a/src/core/slot.h +++ b/src/core/slot.h @@ -23,19 +23,29 @@ namespace core * */ class Slot { public: - enum Flags {Mounted = 1, Active = 2}; + enum Flags {None = 0, Mounted = 1, Active = 2}; /** * @brief default constructor * Creates an empty slot * */ Slot(); - + /** * @brief default destructor * */ ~Slot(); + /** + * @brief load slot configuration from a model slot + * */ + void load(const model::Slot *slot_tag, const float modelscale); + + /** + * @brief clear slot values + * */ + void clear(); + /** * @brief location of the slot within the parent model * */ @@ -85,10 +95,18 @@ public: return slot_last_fired; } + /** + * @brief slot radius + * */ + inline const float radius() const + { + return slot_radius; + } + /** * @brief slot fire cone, in degrees * */ - inline float cone() const + inline const float cone() const { return slot_cone; } @@ -96,7 +114,7 @@ public: /** * @brief weapon slot type * */ - inline const model::Weapon::Type type() const + inline const model::Slot::Type type() const { return slot_type; } @@ -160,10 +178,18 @@ public: slot_cone = cone; } + /** + * @brief set slot slot_radius + * */ + void set_radius(const float radius) + { + slot_radius = radius; + } + /** * @brief set slot type * */ - void set_type(const model::Weapon::Type type) + void set_type(const model::Slot::Type type) { slot_type = type; } @@ -171,13 +197,19 @@ public: /** * @brief load slot parameters from a model weapon tag * */ - void load(const model::Weapon *weapon_tag); + void load(const model::Slot *slot_tag); private: + model::Slot::Type slot_type; + math::Vector3f slot_location; math::Axis slot_axis; + + float slot_radius; + + float slot_cone; // slot flags unsigned int slot_flags; @@ -188,13 +220,8 @@ private: // timestamp indicating when the slot last generated a projectile, server-side unsigned long slot_last_fired; - // item mounted in this slot Item *slot_item; - - model::Weapon::Type slot_type; - - float slot_cone; }; } // namespace core diff --git a/src/core/slots.cc b/src/core/slots.cc index 6d6096a..23fb7e1 100644 --- a/src/core/slots.cc +++ b/src/core/slots.cc @@ -19,12 +19,25 @@ Slots::~Slots() clear(); } -void Slots::load(model::Model *model) +void Slots::load(model::Model *model, const float modelscale) { - for (model::Model::Weapons::iterator it = model->weapons().begin(); it != model->weapons().end(); ++it) { - Slot *slot = new Slot(); - slot->load((*it)); - slots_container.push_back(slot); + for (model::Model::Slots::const_iterator slit = model->slots().begin(); slit != model->slots().end(); ++slit) { + + const model::Slot *tag_slot = (*slit); + Slot *slot = 0; + + switch (tag_slot->type()) { + case model::Slot::Cannon: + case model::Slot::Turret: + case model::Slot::Dock: + slot = new Slot(); + slot->load(tag_slot, modelscale); + slots_container.push_back(slot); + break; + + case model::Slot::None: + break; + } } //con_debug << " loaded " << slots_container.size() << " entity slots" << std::endl; } diff --git a/src/core/slots.h b/src/core/slots.h index 2452ccb..b7b0673 100644 --- a/src/core/slots.h +++ b/src/core/slots.h @@ -32,7 +32,7 @@ public: /** * @brief initialize slots collection from model properties * */ - void load(model::Model *model); + void load(model::Model *model, const float modelscale); /** * @brief remove all slots diff --git a/src/game/base/game.cc b/src/game/base/game.cc index 201b18c..f802ff2 100644 --- a/src/game/base/game.cc +++ b/src/game/base/game.cc @@ -2579,8 +2579,10 @@ bool Game::validate_zone(core::Zone *zone) } if (entity->model()) { + const float modelscale = entity->radius() / entity->model()->radius(); + entity->add_slots(); - entity->slots()->load(entity->model()); + entity->slots()->load(entity->model(), modelscale); } } diff --git a/src/game/base/patrol.cc b/src/game/base/patrol.cc index 51b7e2a..9b805de 100644 --- a/src/game/base/patrol.cc +++ b/src/game/base/patrol.cc @@ -318,16 +318,11 @@ void Patrol::create_patrol() npc->menus().clear(); } - // install inventory - if (!npc->inventory()) { - npc->add_inventory(); - } + // inventory has been added by the Ship constructor + assert (npc->inventory()); - // install slots - if (!npc->slots()) { - npc->add_slots(); - slots()->load(model()); - } + // slots have been added by the Ship constructor + assert(npc->slots()); // install weapons for (core::Slots::iterator slit = npc->slots()->begin(); slit != npc->slots()->end(); ++slit) { @@ -335,11 +330,11 @@ void Patrol::create_patrol() core::Item *item = 0; - if (slot->type() == model::Weapon::Cannon) { + if (slot->type() == model::Slot::Cannon) { if (npctype->cannon()) { item = new core::Item(npctype->cannon()); } - } else if (slot->type() == model::Weapon::Turret) { + } else if (slot->type() == model::Slot::Turret) { if (npctype->turret()) { item = new core::Item(npctype->turret()); } diff --git a/src/game/base/platform.cc b/src/game/base/platform.cc index 77059ae..bfad7ef 100644 --- a/src/game/base/platform.cc +++ b/src/game/base/platform.cc @@ -88,17 +88,15 @@ void Platform::frame(const unsigned long elapsed) // platforms do not need weapons in inventory to fire if (enemylist.size()) { - const float modelscale = radius() / (model() ? model()->radius() : 1.0f); - - for (core::Slots::iterator it = slots()->begin(); it != slots()->end(); it++) { - core::Slot *slot = (*it); + for (core::Slots::iterator slit = slots()->begin(); slit != slots()->end(); slit++) { + core::Slot *slot = (*slit); // found out if this slot is a cannon or a turret const Weapon *weapon = 0; - if (slot->type() == model::Weapon::Cannon) { + if (slot->type() == model::Slot::Cannon) { weapon = cannon(); - } else if (slot->type() == model::Weapon::Turret) { + } else if (slot->type() == model::Slot::Turret) { weapon = turret(); } @@ -111,7 +109,7 @@ void Platform::frame(const unsigned long elapsed) } // location of the slot in world coordinates - const math::Vector3f slot_location(location() + (axis() * slot->location() * modelscale)); + const math::Vector3f slot_location(location() + (axis() * slot->location())); // find a target for this slot Ship *current_enemy = 0; diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index b3f6fd0..9a4218f 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -96,8 +96,10 @@ Ship::Ship(core::Player *owner, const ShipModel *shipmodel) : core::EntityContro inventory()->set_capacity(ship_shipmodel->maxcargo()); if (model()) { + const float modelscale = radius() / model()->radius(); + add_slots(); - slots()->load(model()); + slots()->load(model(), modelscale); } // menus for docked players @@ -537,20 +539,30 @@ void Ship::launch() get_axis().assign(ship_dock->axis()); get_location().assign(ship_dock->location() + (ship_dock->axis().forward() * (PLANET_SAFE_DISTANCE + this->radius() + ship_dock->radius()))); - } else { - if (ship_dock->model() && ship_dock->model()->docks().size()) { - // choose a random dock to launch from - model::Model::Docks::iterator dit = ship_dock->model()->docks().begin(); - int launchbay_index = math::randomi(ship_dock->model()->docks().size()); - for (int i = 0; i < launchbay_index; i++) { - ++dit; + } else { + int nbdocks = 0; + + if (ship_dock->slots()) { + for (core::Slots::iterator slit = ship_dock->slots()->begin(); slit != ship_dock->slots()->end(); ++slit) { + if ((*slit)->type() == model::Slot::Dock) { + ++nbdocks; + } } - model::Dock *launchbay = (*dit); - - const float modelscale = ship_dock->radius() / ship_dock->model()->radius(); + } + + if (nbdocks) { + // choose a random dock to launch from + core::Slots::iterator slit = ship_dock->slots()->begin(); + int launchbay_index = math::randomi(nbdocks); + for (int i = 0; i < launchbay_index; ++slit) { + if ((*slit)->type() == model::Slot::Dock) { + ++i; + } + } + core::Slot *launchbay = (*slit); get_axis().assign(ship_dock->axis() * launchbay->axis()); - get_location().assign(ship_dock->location() + ship_dock->axis() * ( launchbay->location() * modelscale + launchbay->axis().forward() * radius())); + get_location().assign(ship_dock->location() + ship_dock->axis() * ( launchbay->location() + launchbay->axis().forward() * radius())); } else { const float r = radius() + ship_dock->radius(); @@ -1173,8 +1185,6 @@ void Ship::frame(const unsigned long elapsed) // fire weapons if (slots() && (state() == core::Entity::Normal) && has_target_controlflag(core::EntityControlable::ControlFlagFire)) { - const float modelscale = radius() / (model() ? model()->radius() : 1.0f); - for (core::Slots::iterator it = slots()->begin(); it != slots()->end(); it++) { core::Slot *slot = (*it); @@ -1198,7 +1208,7 @@ void Ship::frame(const unsigned long elapsed) const float projectile_radius = core::PROJECTILE_RADIUS; // FIXME this should be defined somewhere math::Axis projectile_axis(axis() * slot->axis()); - math::Vector3f projectile_location(location() + (axis() * slot->location() * modelscale) + projectile_axis.forward() * projectile_radius); + math::Vector3f projectile_location(location() + axis() * slot->location() + projectile_axis.forward() * projectile_radius); math::Vector3f projectile_direction(target_aim - projectile_location); projectile_direction.normalize(); float cosa = math::dotproduct(projectile_direction, projectile_axis.forward()); diff --git a/src/game/base/weapon.h b/src/game/base/weapon.h index a6a5731..857b3cd 100644 --- a/src/game/base/weapon.h +++ b/src/game/base/weapon.h @@ -88,17 +88,17 @@ public: return weapon_projectile_soundname; } - inline const model::Weapon::Type slot_type() const + inline const model::Slot::Type slot_type() const { switch (weapon_subtype) { case Cannon: - return model::Weapon::Cannon; + return model::Slot::Cannon; break; case Turret: - return model::Weapon::Turret; + return model::Slot::Turret; break; default: - return model::Weapon::Unmountable; + return model::Slot::None; } } diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index 49122d5..3a8aa40 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -1429,13 +1429,12 @@ Model * MapFile::load(std::string const &name) Model *model = new Model(name); mapfile.clear_bbox(); - Dock *tag_dock = 0; + Slot *tag_slot = 0; Particles *tag_particles = 0; Flare *tag_flare = 0; Light *tag_light = 0; SubModel *tag_submodel = 0; Sound *tag_sound = 0; - Weapon *tag_weapon = 0; std::string modelname; math::Vector3f location; @@ -1820,25 +1819,25 @@ Model * MapFile::load(std::string const &name) } else if (mapfile.got_classname("location_dock")) { // new docking location - tag_dock = new Dock(); - model->add_dock(tag_dock); + tag_slot = new Slot(Slot::Dock); + model->add_slot(tag_slot); } else if (mapfile.classname().compare("location_dock") == 0) { // dock attributes - if (mapfile.got_key_axis(tag_dock->get_axis())) { + if (mapfile.got_key_axis(tag_slot->get_axis())) { continue; } else if (mapfile.got_key_vector3f("origin", location)) { - tag_dock->get_location().assign(location * SCALE); + tag_slot->get_location().assign(location * SCALE); continue; } else if (mapfile.got_key_float("radius", r)) { - tag_dock->set_radius(r * SCALE); + tag_slot->set_radius(r * SCALE); continue; } else if (mapfile.got_key_string("info", str)) { - tag_dock->set_info(str); + tag_slot->set_info(str); } else if (mapfile.got_key()) { mapfile.unknown_key(); @@ -1848,26 +1847,26 @@ Model * MapFile::load(std::string const &name) } else if (mapfile.got_classname("location_cannon")) { // new cannon slot - tag_weapon = new Weapon(Weapon::Cannon); - model->add_weapon(tag_weapon); + tag_slot = new Slot(Slot::Cannon); + model->add_slot(tag_slot); continue; } else if (mapfile.classname().compare("location_cannon") == 0) { // cannon options - if (mapfile.got_key_axis(tag_weapon->get_axis())) { + if (mapfile.got_key_axis(tag_slot->get_axis())) { continue; } else if (mapfile.got_key_vector3f("origin", location)) { - tag_weapon->get_location().assign(location * SCALE); + tag_slot->get_location().assign(location * SCALE); continue; } else if (mapfile.got_key_float("cone", r)) { - tag_weapon->set_cone(r); + tag_slot->set_cone(r); continue; } else if (mapfile.got_key_string("info", str)) { - tag_weapon->set_info(str); + tag_slot->set_info(str); } else if (mapfile.got_key()) { mapfile.unknown_key(); @@ -1878,26 +1877,26 @@ Model * MapFile::load(std::string const &name) } else if (mapfile.got_classname("location_turret")) { // new turret slot - tag_weapon = new Weapon(Weapon::Turret); - model->add_weapon(tag_weapon); + tag_slot = new Slot(Slot::Turret); + model->add_slot(tag_slot); continue; } else if (mapfile.classname().compare("location_turret") == 0) { // turret options - if (mapfile.got_key_axis(tag_weapon->get_axis())) { + if (mapfile.got_key_axis(tag_slot->get_axis())) { continue; } else if (mapfile.got_key_vector3f("origin", location)) { - tag_weapon->get_location().assign(location * SCALE); + tag_slot->get_location().assign(location * SCALE); continue; } else if (mapfile.got_key_float("cone", r)) { - tag_weapon->set_cone(r); + tag_slot->set_cone(r); continue; } else if (mapfile.got_key_string("info", str)) { - tag_weapon->set_info(str); + tag_slot->set_info(str); } else if (mapfile.got_key()) { mapfile.unknown_key(); @@ -2048,21 +2047,12 @@ Model * MapFile::load(std::string const &name) model->add_sound(tag_sound); } - // copy dock tags - for (Model::Docks::const_iterator dit = submodel_model->docks().begin(); dit != submodel_model->docks().end(); ++dit) { - tag_dock = new Dock(*(*dit)); - tag_dock->get_location().assign(tag_submodel->location() + tag_submodel->axis() * (tag_dock->location() - submodel_model->origin()) * tag_submodel->scale()); - model->add_dock(tag_dock); + // copy slot tags + for (Model::Slots::const_iterator slit = submodel_model->slots().begin(); slit != submodel_model->slots().end(); ++slit) { + tag_slot = new Slot(*(*slit)); + tag_slot->get_location().assign(tag_submodel->location() + tag_submodel->axis() * (tag_slot->location() - submodel_model->origin()) * tag_submodel->scale()); + model->add_slot(tag_slot); } - - // copy weapon tags - for (Model::Weapons::const_iterator wit = submodel_model->weapons().begin(); wit != submodel_model->weapons().end(); ++wit) { - tag_weapon = new Weapon(*(*wit)); - tag_weapon->get_location().assign(tag_submodel->location() + tag_submodel->axis() * (tag_weapon->location() - submodel_model->origin()) * tag_submodel->scale()); - model->add_weapon(tag_weapon); - } - - } delete tag_submodel; @@ -2124,14 +2114,10 @@ Model * MapFile::load(std::string const &name) (*sit)->get_location() -= map_center; } - for (Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); ++dit) { - (*dit)->get_location() -= map_center; + for (Model::Slots::iterator slit = model->slots().begin(); slit != model->slots().end(); ++slit) { + (*slit)->get_location() -= map_center; } - - for (Model::Weapons::iterator wit = model->weapons().begin(); wit != model->weapons().end(); ++wit) { - (*wit)->get_location() -= map_center; - } - + if (mapfile.warning_q2brush) con_warn << mapfile.name() << " quake2 style brushes detected" << std::endl; diff --git a/src/model/model.cc b/src/model/model.cc index fdff22e..e98a251 100644 --- a/src/model/model.cc +++ b/src/model/model.cc @@ -43,11 +43,11 @@ Model::~Model() } model_groups.clear(); - // delete all docks - for (Docks::iterator dit = model_docks.begin(); dit != model_docks.end(); ++dit) { - delete(*dit); + // delete all slots + for (Slots::iterator slit = model_slots.begin(); slit != model_slots.end(); ++slit) { + delete(*slit); } - model_docks.clear(); + model_slots.clear(); // delete all particle systems for (Model::ParticleSystems::iterator pit = model_particles.begin(); pit != model_particles.end(); ++pit) { @@ -72,12 +72,6 @@ Model::~Model() delete (*sit); } model_sounds.clear(); - - // delete all weapon tags - for (Weapons::iterator wit = model_weapons.begin(); wit != model_weapons.end(); ++wit) { - delete (*wit); - } - model_weapons.clear(); } void Model::set_collisionmodel(CollisionModel *collisionmodel) @@ -120,14 +114,9 @@ void Model::add_sound(Sound *sound) model_sounds.push_back(sound); } -void Model::add_dock(Dock *dock) -{ - model_docks.push_back(dock); -} - -void Model::add_weapon(Weapon *weapon) +void Model::add_slot(Slot *slot) { - model_weapons.push_back(weapon); + model_slots.push_back(slot); } void Model::print() const @@ -193,8 +182,7 @@ bool compare_tag_location_front(const Tag *first, const Tag *second) } void Model::sort() { - model_weapons.sort(compare_tag_location); - model_docks.sort(compare_tag_location_front); + model_slots.sort(compare_tag_location_front); model_particles.sort(compare_tag_location); model_lights.sort(compare_tag_location); diff --git a/src/model/model.h b/src/model/model.h index 4d72793..3e6bd2d 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -43,8 +43,8 @@ public: /// type definition for a list of model flare tags typedef std::list Flares; - /// type definition for a list of model dock tags - typedef std::list Docks; + /// type definition for a list of model slot tags + typedef std::list Slots; /// type definition for a list of model particle system tags typedef std::list ParticleSystems; @@ -52,9 +52,6 @@ public: /// type definition for a list of model sound tags typedef std::list Sounds; - /// type definition for a list of model weapon tags - typedef std::list Weapons; - /// type definition for a list of FragmentGroups typedef std::list Groups; @@ -92,9 +89,9 @@ public: return model_lights; } - /// list of model dock tags - inline Docks & docks() { - return model_docks; + /// list of model slot tags + inline Slots & slots() { + return model_slots; } /// list of model flare tags @@ -107,11 +104,6 @@ public: return model_sounds; } - /// list of model weapon tags - inline Weapons & weapons() { - return model_weapons; - } - /// list of model particle system tags inline ParticleSystems & particles() { return model_particles; @@ -150,12 +142,9 @@ public: /// add a flare tag to the model void add_flare(Flare *flare); - /// add a docking location tag to the model - void add_dock(Dock *dock); + /// add a slot tag to the model + void add_slot(Slot *slot); - /// add a weapon slot tag to the model - void add_weapon(Weapon *weapon); - /// add a sound tag to the model void add_sound(Sound *sound); @@ -220,16 +209,16 @@ private: void sort(); std::string model_name; - Docks model_docks; + Slots model_slots; Flares model_flares; Sounds model_sounds; Lights model_lights; ParticleSystems model_particles; - Weapons model_weapons; Groups model_groups; - float model_radius; - static Registry model_registry; + float model_radius; CollisionModel *model_collisionmodel; + + static Registry model_registry; }; } diff --git a/src/model/tags.cc b/src/model/tags.cc index 7e5a393..f755373 100644 --- a/src/model/tags.cc +++ b/src/model/tags.cc @@ -121,23 +121,6 @@ Particles::~Particles() { } -/* ---- class Dock ------------------------------------------------- */ - -Dock::Dock() : Tag() -{ - dock_radius = 0.01f; -} - -Dock::Dock(const Dock& other) : Tag(other) -{ - dock_radius = other.radius(); - dock_axis.assign(other.axis()); -} - -Dock::~Dock() -{ -} - /* ---- class Sound ------------------------------------------------- */ Sound::Sound() : Tag() @@ -153,36 +136,41 @@ Sound::~Sound() { } -/* ---- class Dock ------------------------------------------------- */ +/* ---- class Slot ------------------------------------------------- */ -Weapon::Weapon(const Type type) : Tag() -{ +Slot::Slot(const Type type) : Tag() +{ + slot_radius = 0.0f; set_type(type); + } -Weapon::Weapon(const Weapon& other) : Tag(other) +Slot::Slot(const Slot& other) : Tag(other) { - weapon_type = other.type(); - weapon_cone = other.cone(); - weapon_axis.assign(other.axis()); + slot_type = other.type(); + slot_axis.assign(other.axis()); + slot_radius = other.radius(); + slot_cone = other.cone(); + } -Weapon::~Weapon() +Slot::~Slot() { } -void Weapon::set_type(const Type type) +void Slot::set_type(const Type type) { - weapon_type = type; - switch (weapon_type) { - case Unmountable: - weapon_cone = 0.0f; + slot_type = type; + switch (slot_type) { + case None: + case Dock: + slot_cone = 0.0f; break; case Cannon: - weapon_cone = 60.0f; // 60 degrees + slot_cone = 60.0f; // 60 degrees break; case Turret: - weapon_cone = 180.0f; // 180 degrees + slot_cone = 180.0f; // 180 degrees break; } } diff --git a/src/model/tags.h b/src/model/tags.h index 5be7576..775dc73 100644 --- a/src/model/tags.h +++ b/src/model/tags.h @@ -546,74 +546,6 @@ private: std::string particles_script; }; -/* ---- class Dock ------------------------------------------------- */ - -/// a docking location tag -class Dock : public Tag -{ -public: - /** - * @brief default constructor - * */ - Dock(); - - /** - * @brief copy constructor - * */ - Dock(const Dock& other); - - /** - * @brief destructor - * */ - ~Dock(); - - /* ---- inspectors ----------------------------------------- */ - - /** - * @brief dock radius, default is 0.01f - * */ - inline float radius() const - { - return dock_radius; - } - - inline const math::Axis &axis() const - { - return dock_axis; - } - - /* ---- mutators ------------------------------------------- */ - - /** - * @brief set dock radius - * */ - inline void set_radius(const float radius) - { - dock_radius = radius; - } - - /** - * @brief set dock axis - * */ - inline void set_axis(const math::Axis& axis) - { - dock_axis.assign(axis); - } - - /* ---- actors --------------------------------------------- */ - - /** - * @brief mutable reference to the axis - * */ - inline math::Axis& get_axis() { - return dock_axis; - } - -private: - float dock_radius; - math::Axis dock_axis; -}; - /* ---- class Sound ------------------------------------------------ */ /** @@ -711,89 +643,111 @@ private: math::Axis submodel_axis; }; -/* ---- class Weapon ----------------------------------------------- */ +/* ---- class Slot ------------------------------------------------- */ /** - * @brief a weapon slot tag + * @brief a slot tag + * A slot tag can be a cannon, turret or a dock. + * Unlike visual effects like lights and flares. slots get copied into entity space. * */ -class Weapon : public Tag +class Slot : public Tag { public: - enum Type {Unmountable = 0, Cannon = 1, Turret = 2 }; + enum Type {None = 0, Cannon = 1, Turret = 2, Dock = 3}; /** * @brief default constructor * */ - Weapon(const Type type = Cannon); + Slot(const Type type = None); /** * @brief copy constructor * */ - Weapon(const Weapon& other); + Slot(const Slot& other); /** * @brief destructor * */ - ~Weapon(); + ~Slot(); /* ---- inspectors ----------------------------------------- */ - inline const math::Axis &axis() const { - return weapon_axis; + /** + * @brief slot type + * */ + inline const Type type() const + { + return slot_type; } /** - * @brief weapon fire cone, in degrees + * @brief slot orientation within the parent model * */ - inline float cone() const - { - return weapon_cone; + inline const math::Axis &axis() const { + return slot_axis; } /** - * @brief weapon slot type + * @brief slot radius, used by Dock slots * */ - inline const Type type() const + inline float radius() const { - return weapon_type; + return slot_radius; } + /** + * @brief slot fire cone, in degrees, used by Turret and Cannon slots. + * */ + inline float cone() const + { + return slot_cone; + } + /* ---- mutators ------------------------------------------- */ /** - * @brief set weapon fire cone, in degrees + * @brief set slot type * */ - inline void set_cone(const float cone) - { - weapon_cone = cone; - } + void set_type(const Type type); /** - * @brief set weapon slot axis + * @brief set slot axis * */ inline void set_axis(const math::Axis& axis) { - weapon_axis.assign(axis); + slot_axis.assign(axis); } /** - * @brief set weapon slot type + * @brief set slot radius * */ -; void set_type(const Type type); + inline void set_radius(const float radius) + { + slot_radius = radius; + } + /** + * @brief set slot fire cone, in degrees + * */ + inline void set_cone(const float cone) + { + slot_cone = cone; + } + /* ---- actors --------------------------------------------- */ /** * @brief mutable reference to the axis * */ inline math::Axis& get_axis() { - return weapon_axis; + return slot_axis; } private: - Type weapon_type; - math::Axis weapon_axis; - float weapon_cone; + Type slot_type; + math::Axis slot_axis; + float slot_radius; + float slot_cone; }; diff --git a/src/render/draw.cc b/src/render/draw.cc index 2428735..47fcb40 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -824,10 +824,6 @@ void draw_pass_model_fragments() ext_render(entity)->power(), ext_render(entity)->thrust() ); - - if (r_slots && r_slots->value()) { - draw_slots(entity); - } if (r_bbox->value()) { gl::disable(GL_DEPTH_TEST); @@ -847,8 +843,18 @@ void draw_pass_model_fragments() draw_inidicators(static_cast(entity)); } + if (entity->slots() && r_slots && r_slots->value()) { + gl::pop(); + + gl::push(); + gl::translate(entity->location()); + gl::multmatrix(entity->axis()); + + // not scaled through modelscale + draw_slots(entity); + } gl::pop(); - } + } } } @@ -1393,80 +1399,72 @@ void draw_inidicators(const core::EntityControlable *entity) void draw_slots(const core::Entity *entity) { - if (!entity->model()) { - return; - } - - if (entity->model()->docks().size()) { + if (entity->slots()) + { + const float r = 0.025f; - // draw docks: pass 1 - background with GL_DEPTH_TEST disabled + // draw slots: pass 1 - background with GL_DEPTH_TEST disabled gl::disable(GL_DEPTH_TEST); - gl::color(0.0f, 0.5f, 0.5f, 0.25f); - - for (model::Model::Docks::iterator dit = entity->model()->docks().begin(); dit != entity->model()->docks().end(); ++dit) { - model::Dock *dock = (*dit); - math::Vector3f maxbox(dock->location()); - math::Vector3f minbox(dock->location()); - - for (size_t i = 0; i < 3; i++) { - maxbox[i] += 0.025; - minbox[i] -= 0.025; - } - - draw_box(minbox, maxbox); - } - - // draw docks: pass 2 - highlight with GL_DEPTH_TEST enabled - gl::enable(GL_DEPTH_TEST); - gl::color(0.0f, 1.0f, 1.0f, 1.0f); - - for (model::Model::Docks::iterator dit = entity->model()->docks().begin(); dit != entity->model()->docks().end(); ++dit) { - model::Dock *dock = (*dit); - math::Vector3f maxbox(dock->location()); - math::Vector3f minbox(dock->location()); - - for (size_t i = 0; i < 3; i++) { - maxbox[i] += 0.025; - minbox[i] -= 0.025; - } - - draw_box(minbox, maxbox); - } - } - - if (entity->slots()) { - - // draw weapon slots: pass 1 - background with GL_DEPTH_TEST disabled - gl::disable(GL_DEPTH_TEST); - gl::color(0.5f, 0.0f, 0.0f, 0.25f); for(core::Slots::iterator it = entity->slots()->begin(); it != entity->slots()->end(); ++it) { core::Slot *slot = (*it); + switch (slot->type()) { + case model::Slot::Cannon: + case model::Slot::Turret: + // red for weapons + gl::color(0.5f, 0.0f, 0.0f, 0.25f); + break; + case model::Slot::Dock: + // cyan for docks + gl::color(0.0f, 0.5f, 0.5f, 0.25f); + break; + case model::Slot::None: + // gray for unkown + gl::color(0.25f, 0.25f, 0.25f, 0.25f); + break; + } + math::Vector3f maxbox(slot->location()); math::Vector3f minbox(slot->location()); for (size_t i = 0; i < 3; i++) { - maxbox[i] += 0.025; - minbox[i] -= 0.025; + maxbox[i] += r; + minbox[i] -= r; } draw_box(minbox, maxbox); } - // draw weapon slots: pass 2 - highlight with GL_DEPTH_TEST enabled + // draw slots: pass 2 - highlight with GL_DEPTH_TEST enabled gl::enable(GL_DEPTH_TEST); gl::color(1.0f, 0.0f, 0.0f); for(core::Slots::iterator it = entity->slots()->begin(); it != entity->slots()->end(); ++it) { core::Slot *slot = (*it); + switch (slot->type()) { + case model::Slot::Cannon: + case model::Slot::Turret: + // red for weapons + gl::color(1.0f, 0.0f, 0.0f, 1.0f); + break; + case model::Slot::Dock: + // cyan for docks + gl::color(0.0f, 1.0f, 1.0f, 1.0f); + break; + case model::Slot::None: + // gray for unkown + gl::color(0.5f, 0.5f, 0.5f, 1.0f); + break; + } + math::Vector3f maxbox(slot->location()); math::Vector3f minbox(slot->location()); for (size_t i = 0; i < 3; i++) { - maxbox[i] += 0.025; - minbox[i] -= 0.025; + maxbox[i] += r; + minbox[i] -= r; } draw_box(minbox, maxbox); -- cgit v1.2.3