diff --git a/src/items/item.cpp b/src/items/item.cpp index bfbe47899..76d194409 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -70,7 +70,7 @@ void ItemState::setDisappearCounter() m_used_up_counter = -1; } // switch } // setDisappearCounter - + // ----------------------------------------------------------------------- /** Initialises an item. * \param type Type for this item. @@ -157,24 +157,22 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal, m_was_available_previously = true; m_distance_2 = 1.2f; initItem(type, xyz); - + m_graphical_type = type; m_original_rotation = shortestArcQuat(Vec3(0, 1, 0), normal); m_rotation_angle = 0.0f; - m_original_mesh = mesh; - m_original_lowmesh = lowres_mesh; m_listener = NULL; - LODNode* lodnode = + LODNode* lodnode = new LODNode("item", irr_driver->getSceneManager()->getRootSceneNode(), irr_driver->getSceneManager()); - scene::ISceneNode* meshnode = + scene::ISceneNode* meshnode = irr_driver->addMesh(mesh, StringUtils::insertValues("item_%i", (int)type)); if (lowres_mesh != NULL) { lodnode->add(35, meshnode, true); - scene::ISceneNode* meshnode = - irr_driver->addMesh(lowres_mesh, + scene::ISceneNode* meshnode = + irr_driver->addMesh(lowres_mesh, StringUtils::insertValues("item_lo_%i", (int)type)); lodnode->add(100, meshnode, true); } @@ -209,10 +207,9 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger) { m_distance_2 = distance*distance; initItem(ITEM_TRIGGER, xyz); + m_graphical_type = ITEM_TRIGGER; m_original_rotation = btQuaternion(0, 0, 0, 1); m_rotation_angle = 0.0f; - m_original_mesh = NULL; - m_original_lowmesh = NULL; m_node = NULL; m_listener = trigger; m_was_available_previously = true; @@ -226,8 +223,6 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger) void Item::initItem(ItemType type, const Vec3 &xyz) { ItemState::initItem(type, xyz); - m_rotate = (getType()!=ITEM_BUBBLEGUM) && - (getType()!=ITEM_TRIGGER ); // Now determine in which quad this item is, and its distance // from the center within this quad. m_graph_node = Graph::UNKNOWN_SECTOR; @@ -265,19 +260,6 @@ void Item::initItem(ItemType type, const Vec3 &xyz) void Item::setType(ItemType type) { ItemState::setType(type); - m_rotate = (type!=ITEM_BUBBLEGUM) && (type!=ITEM_TRIGGER); - - if (m_node != NULL) - { - for (auto* node : m_node->getAllNodes()) - { - SP::SPMeshNode* spmn = dynamic_cast(node); - if (spmn) - { - spmn->setGlowColor(ItemManager::get()->getGlowColor(type)); - } - } - } } // setType //----------------------------------------------------------------------------- @@ -287,7 +269,6 @@ void Item::setType(ItemType type) */ void Item::switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh) { - setMesh(mesh, lowmesh); ItemState::switchTo(type, mesh, lowmesh); } // switchTo @@ -299,17 +280,9 @@ void Item::switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh) */ bool Item::switchBack() { - setMesh(m_original_mesh, m_original_lowmesh); - - if (ItemState::switchBack()) + if (ItemState::switchBack()) return true; - if (m_node != NULL) - { - Vec3 hpr; - hpr.setHPR(m_original_rotation); - m_node->setRotation(hpr.toIrrHPR()); - } return false; } // switchBack @@ -319,7 +292,7 @@ void Item::setMesh(scene::IMesh* mesh, scene::IMesh* lowres_mesh) #ifndef SERVER_ONLY if (m_node == NULL) return; - + unsigned i = 0; for (auto* node : m_node->getAllNodes()) { @@ -365,14 +338,33 @@ void Item::reset() { m_was_available_previously = true; ItemState::reset(); - + if (m_node != NULL) { m_node->setScale(core::vector3df(1,1,1)); m_node->setVisible(true); } + handleNewMesh(getType()); } // reset +// ---------------------------------------------------------------------------- +void Item::handleNewMesh(ItemType type) +{ + if (m_node == NULL) + return; + setMesh(ItemManager::get()->getItemModel(type), + ItemManager::get()->getItemLowResolutionModel(type)); + for (auto* node : m_node->getAllNodes()) + { + SP::SPMeshNode* spmn = dynamic_cast(node); + if (spmn) + spmn->setGlowColor(ItemManager::get()->getGlowColor(type)); + } + Vec3 hpr; + hpr.setHPR(m_original_rotation); + m_node->setRotation(hpr.toIrrHPR()); +} // handleNewMesh + // ---------------------------------------------------------------------------- /** Updated the item - rotates it, takes care of items coming back into * the game after it has been collected. @@ -383,9 +375,15 @@ void Item::updateGraphics(float dt) if (m_node == NULL) return; + if (m_graphical_type != getType()) + { + handleNewMesh(getType()); + m_graphical_type = getType(); + } + float time_till_return = stk_config->ticks2Time(getTicksTillReturn()); - bool is_visible = isAvailable() || time_till_return <= 1.0f || - (getType() == ITEM_BUBBLEGUM && + bool is_visible = isAvailable() || time_till_return <= 1.0f || + (getType() == ITEM_BUBBLEGUM && getOriginalType() == ITEM_NONE && !isUsedUp()); m_node->setVisible(is_visible); @@ -403,7 +401,7 @@ void Item::updateGraphics(float dt) m_node->setVisible(true); m_node->setScale(core::vector3df(1, 1, 1)*(1 - time_till_return)); } - if (isAvailable() && m_rotate) + if (isAvailable() && rotating()) { // have it rotate m_rotation_angle += dt * M_PI; @@ -419,7 +417,7 @@ void Item::updateGraphics(float dt) m_node->setRotation(hpr.toIrrHPR()); } // if item is available m_was_available_previously = isAvailable(); -} // update +} // updateGraphics //----------------------------------------------------------------------------- /** Is called when the item is hit by a kart. It sets the flag that the item @@ -429,7 +427,7 @@ void Item::updateGraphics(float dt) void Item::collected(const AbstractKart *kart) { ItemState::collected(kart); - + if (m_listener != NULL) { m_listener->onTriggerItemApproached(); diff --git a/src/items/item.hpp b/src/items/item.hpp index 8a2d31965..daa6fcbf4 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -202,7 +202,7 @@ public: // ----------------------------------------------------------------------- /** Resets an item to its start state. */ - void reset() + virtual void reset() { m_deactive_ticks = 0; m_ticks_till_return = 0; @@ -332,12 +332,8 @@ private: /** Scene node of this item. */ LODNode *m_node; - /** Stores the original mesh in order to reset it. */ - scene::IMesh *m_original_mesh; - scene::IMesh *m_original_lowmesh; - - /** Set to false if item should not rotate. */ - bool m_rotate; + /** Graphical type of the mesh. */ + ItemType m_graphical_type; /** Stores if the item was available in the previously rendered frame. */ bool m_was_available_previously; @@ -363,6 +359,7 @@ private: void setType(ItemType type) OVERRIDE; void initItem(ItemType type, const Vec3 &xyz); void setMesh(scene::IMesh* mesh, scene::IMesh* lowres_mesh); + void handleNewMesh(ItemType type); public: Item(ItemType type, const Vec3& xyz, const Vec3& normal, @@ -374,7 +371,7 @@ public: virtual ~Item (); virtual void updateGraphics(float dt) OVERRIDE; virtual void collected(const AbstractKart *kart) OVERRIDE; - void reset(); + virtual void reset() OVERRIDE; virtual void switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh) OVERRIDE; virtual bool switchBack() OVERRIDE; @@ -397,6 +394,9 @@ public: lc.setY(lc.getY() / 2.0f); return lc.length2() < m_distance_2; } // hitKart + // ------------------------------------------------------------------------ + bool rotating() const + { return getType() != ITEM_BUBBLEGUM && getType() != ITEM_TRIGGER; } public: // ------------------------------------------------------------------------ diff --git a/src/items/item_manager.hpp b/src/items/item_manager.hpp index e40ad15d3..8ab265023 100644 --- a/src/items/item_manager.hpp +++ b/src/items/item_manager.hpp @@ -84,6 +84,10 @@ public: static scene::IMesh* getItemModel(ItemState::ItemType type) { return m_item_mesh[type]; } // ------------------------------------------------------------------------ + /** Returns the low resolution mesh for a certain item. */ + static scene::IMesh* getItemLowResolutionModel(ItemState::ItemType type) + { return m_item_lowres_mesh[type]; } + // ------------------------------------------------------------------------ /** Returns the glow color for an item. */ static video::SColorf& getGlowColor(ItemState::ItemType type) { return m_glow_color[type]; } @@ -101,7 +105,6 @@ protected: /** The vector of all items of the current track. */ typedef std::vector AllItemTypes; AllItemTypes m_all_items; - private: /** Stores which items are on which quad. m_items_in_quads[#quads] * contains all items that are not on a quad. Note that this