diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index 732c02aa7..92906ddef 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -38,6 +38,7 @@ #include "karts/ghost_kart.hpp" #include "karts/kart_properties.hpp" #include "physics/btKart.hpp" +#include "tracks/track.hpp" #include "utils/constants.hpp" #include "utils/log.hpp" @@ -140,6 +141,7 @@ KartModel::KartModel(bool is_master) m_wheel_filename[2] = ""; m_wheel_filename[3] = ""; m_speed_weighted_objects.clear(); + m_headlight_objects.clear(); m_animated_node = NULL; for(unsigned int i=AF_BEGIN; i<=AF_END; i++) m_animation_frame[i]=-1; @@ -194,6 +196,11 @@ void KartModel::loadInfo(const XMLNode &node) loadWheelInfo(*wheels_node, "rear-left", 3); } + if (const XMLNode *headlights_node = node.getNode("headlights")) + { + loadHeadlights(*headlights_node); + } + m_nitro_emitter_position[0] = Vec3 (0,0.1f,0); m_nitro_emitter_position[1] = Vec3 (0,0.1f,0); m_has_nitro_emitter = false; @@ -263,6 +270,23 @@ KartModel::~KartModel() } } + for (size_t i = 0; i < m_headlight_objects.size(); i++) + { + HeadlightObject& obj = m_headlight_objects[i]; + obj.m_node = NULL; + if (obj.m_node) + { + // Master KartModels should never have a speed weighted object attached. + assert(!m_is_master); + obj.m_node->drop(); + } + if (m_is_master && obj.m_model) + { + irr_driver->dropAllTextures(obj.m_model); + irr_driver->removeMeshFromCache(obj.m_model); + } + } + if (m_is_master && m_mesh) { m_mesh->drop(); @@ -341,6 +365,14 @@ KartModel* KartModel::makeCopy(KartRenderType krt) km->m_speed_weighted_objects[i] = m_speed_weighted_objects[i]; } + km->m_headlight_objects.resize(m_headlight_objects.size()); + for (size_t i = 0; im_headlight_objects[i] = m_headlight_objects[i]; + } + for(unsigned int i=AF_BEGIN; i<=AF_END; i++) km->m_animation_frame[i] = m_animation_frame[i]; @@ -413,6 +445,13 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim if(!m_speed_weighted_objects[i].m_node) continue; m_speed_weighted_objects[i].m_node->setParent(lod_node); } + + for (size_t i = 0; isetParent(lod_node); + } + #ifndef SERVER_ONLY // Enable rim lighting for the kart irr_driver->applyObjectPassShader(lod_node, true); @@ -490,6 +529,24 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim obj.m_node->setPosition(obj.m_position.toIrrVector()); } } + + for (int i = 0; i < m_headlight_objects.size(); i++) + { + HeadlightObject& obj = m_headlight_objects[i]; + + obj.m_node = NULL; + if (obj.m_model) + { + obj.m_node = irr_driver->addMesh(obj.m_model, "kart_headlight", node, getRenderInfo()); + obj.m_node->grab(); + obj.m_node->setPosition(obj.getPosition()); + + Track* track = Track::getCurrentTrack(); + if (track == NULL || track->getIsDuringDay()) + obj.m_node->setVisible(false); + } + } + } return node; } // attachModel @@ -585,6 +642,14 @@ bool KartModel::loadModels(const KartProperties &kart_properties) kart_max.max(obj_max); } + for (int i = 0; i < m_headlight_objects.size(); i++) + { + HeadlightObject& obj = m_headlight_objects[i]; + std::string full_name = kart_properties.getKartDir() + obj.getFilename(); + obj.m_model = irr_driver->getMesh(full_name); + irr_driver->grabAllTextures(obj.m_model); + } + Vec3 size = kart_max-kart_min; m_kart_width = size.getX(); m_kart_height = size.getY(); @@ -654,6 +719,8 @@ void KartModel::loadNitroEmitterInfo(const XMLNode &node, emitter_node->get("position", &m_nitro_emitter_position[index]); } // loadNitroEmitterInfo +// ---------------------------------------------------------------------------- + /** Loads a single speed weighted node. */ void KartModel::loadSpeedWeightedInfo(const XMLNode* speed_weighted_node, const SpeedWeightedObject::Properties& fallback_properties) { @@ -687,6 +754,32 @@ void KartModel::loadWheelInfo(const XMLNode &node, wheel_node->get("max-suspension", &m_max_suspension[index] ); } // loadWheelInfo +// ---------------------------------------------------------------------------- + +void KartModel::loadHeadlights(const XMLNode &node) +{ + int children = node.getNumNodes(); + for (int i = 0; i < children; i++) + { + const XMLNode* child = node.getNode(i); + if (child->getName() == "object") + { + // + core::vector3df position; + child->get("position", &position); + + std::string model; + child->get("model", &model); + + m_headlight_objects.push_back(HeadlightObject(model, position)); + } + else + { + Log::warn("KartModel", "Unknown XML node in the headlights section"); + } + } +} + // ---------------------------------------------------------------------------- /** Resets the kart model. It stops animation from being played and resets * the wheels to the correct position (i.e. no suspension). diff --git a/src/karts/kart_model.hpp b/src/karts/kart_model.hpp index f714f3ee5..c748eb001 100644 --- a/src/karts/kart_model.hpp +++ b/src/karts/kart_model.hpp @@ -84,6 +84,34 @@ struct SpeedWeightedObject }; typedef std::vector SpeedWeightedObjectList; +class HeadlightObject +{ + std::string m_filename; + core::vector3df m_position; + +public: + + scene::IMesh* m_model; + scene::ISceneNode* m_node; + + HeadlightObject() + { + m_model = NULL; + m_node = NULL; + } + + HeadlightObject(const std::string& filename, core::vector3df pos) + { + m_filename = filename; + m_position = pos; + m_model = NULL; + m_node = NULL; + } + + const std::string& getFilename() const { return m_filename; } + const core::vector3df getPosition() const { return m_position; } +}; + /** * \brief This class stores a 3D kart model. * It takes especially care of attaching @@ -178,6 +206,8 @@ private: /** The speed weighted objects. */ SpeedWeightedObjectList m_speed_weighted_objects; + std::vector m_headlight_objects; + /** Length of the physics suspension when the kart is at rest. */ float m_default_physics_suspension[4]; @@ -233,6 +263,8 @@ private: void loadSpeedWeightedInfo(const XMLNode* speed_weighted_node, const SpeedWeightedObject::Properties& fallback_properties); + void loadHeadlights(const XMLNode &node); + void OnAnimationEnd(scene::IAnimatedMeshSceneNode *node); /** Pointer to the kart object belonging to this kart model. */