Allow using bone attachment in straight-frame static mesh. Advanced headlight rendering with light origin from center mass of headlight model which can be bound to any bone in kart model
This commit is contained in:
parent
32243e7eb3
commit
00660293b7
@ -153,13 +153,6 @@ void ShaderBasedRenderer::prepareForwardRenderer()
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ShaderBasedRenderer::updateLightsInfo(scene::ICameraSceneNode * const camnode,
|
||||
float dt)
|
||||
{
|
||||
m_lighting_passes.updateLightsInfo(camnode, dt);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Upload lighting info to the dedicated uniform buffer
|
||||
*/
|
||||
@ -257,6 +250,10 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
m_poly_count[SOLID_NORMAL_AND_DEPTH_PASS] += solid_poly_count;
|
||||
m_poly_count[SHADOW_PASS] += shadow_poly_count;
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
// For correct position of headlight in karts
|
||||
PROFILER_PUSH_CPU_MARKER("Update Light Info", 0xFF, 0x0, 0x0);
|
||||
m_lighting_passes.updateLightsInfo(camnode, dt);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
// Shadows
|
||||
@ -806,9 +803,6 @@ void ShaderBasedRenderer::render(float dt)
|
||||
if (!CVS->isDefferedEnabled())
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Update Light Info", 0xFF, 0x0, 0x0);
|
||||
m_lighting_passes.updateLightsInfo(camnode, dt);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
PROFILER_PUSH_CPU_MARKER("UBO upload", 0x0, 0xFF, 0x0);
|
||||
computeMatrixesAndCameras(camnode, m_rtts->getWidth(), m_rtts->getHeight());
|
||||
m_shadow_matrices.updateSunOrthoMatrices();
|
||||
@ -920,7 +914,6 @@ void ShaderBasedRenderer::renderToTexture(GL3RenderTarget *render_target,
|
||||
irr_driver->getSceneManager()->setActiveCamera(camera);
|
||||
|
||||
computeMatrixesAndCameras(camera, m_rtts->getWidth(), m_rtts->getHeight());
|
||||
updateLightsInfo(camera, dt);
|
||||
if (CVS->isARBUniformBufferObjectUsable())
|
||||
uploadLightingData();
|
||||
|
||||
|
@ -60,10 +60,7 @@ private:
|
||||
void removeItemsInGlowingList();
|
||||
|
||||
void prepareForwardRenderer();
|
||||
|
||||
void updateLightsInfo(irr::scene::ICameraSceneNode * const camnode,
|
||||
float dt);
|
||||
|
||||
|
||||
void uploadLightingData() const;
|
||||
|
||||
void computeMatrixesAndCameras(scene::ICameraSceneNode * const camnode,
|
||||
|
@ -167,10 +167,7 @@ public:
|
||||
// Access to the graphical kart model.
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns this kart's kart model. */
|
||||
KartModel* getKartModel() { return m_kart_model; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns this kart's kart model. */
|
||||
const KartModel* getKartModel() const { return m_kart_model; }
|
||||
KartModel* getKartModel() const { return m_kart_model; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the length of the kart. */
|
||||
float getKartLength() const { return m_kart_length; }
|
||||
|
@ -235,7 +235,7 @@ void Kart::init(RaceManager::KartType type)
|
||||
}
|
||||
loadData(type, animations);
|
||||
|
||||
m_kart_gfx = new KartGFX(this, m_type, Track::getCurrentTrack()->getIsDuringDay());
|
||||
m_kart_gfx = new KartGFX(this, Track::getCurrentTrack()->getIsDuringDay());
|
||||
m_skidding = new Skidding(this);
|
||||
// Create the stars effect
|
||||
m_stars_effect = new Stars(this);
|
||||
|
@ -36,12 +36,11 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
KartGFX::KartGFX(const AbstractKart *kart, RaceManager::KartType type, bool is_day)
|
||||
KartGFX::KartGFX(const AbstractKart *kart, bool is_day)
|
||||
{
|
||||
m_nitro_light = NULL;
|
||||
m_skidding_light_1 = NULL;
|
||||
m_skidding_light_2 = NULL;
|
||||
m_head_light = NULL;
|
||||
m_kart = kart;
|
||||
m_wheel_toggle = 0;
|
||||
m_skid_level = 0;
|
||||
@ -80,22 +79,11 @@ KartGFX::KartGFX(const AbstractKart *kart, RaceManager::KartType type, bool is_d
|
||||
0.05f), /* force */0.4f, /*radius*/4.0f,
|
||||
1.0f, 0.0f, 0.0f, false, node);
|
||||
m_skidding_light_2->setVisible(false);
|
||||
m_skidding_light_2->setName(("skidding emitter 2 (" + m_kart->getIdent()
|
||||
+ ")").c_str() );
|
||||
|
||||
m_head_light =
|
||||
irr_driver->addLight(core::vector3df(0.0f, 0.2f, 1.5f * length),
|
||||
/* force */ 0.5f, /*radius*/5.0f, 1.0f, 1.0f,
|
||||
1.0f, false, node);
|
||||
m_head_light->setName( ("head light " + m_kart->getIdent()
|
||||
+ ")").c_str() );
|
||||
|
||||
m_head_light->setVisible(type == RaceManager::KT_PLAYER && !is_day);
|
||||
|
||||
m_skidding_light_2->setName(("skidding emitter 2 (" + m_kart->getIdent()
|
||||
+ ")").c_str() );
|
||||
m_nitro_light->grab();
|
||||
m_skidding_light_1->grab();
|
||||
m_skidding_light_2->grab();
|
||||
m_head_light->grab();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -149,7 +137,6 @@ KartGFX::~KartGFX()
|
||||
m_nitro_light->drop();
|
||||
m_skidding_light_1->drop();
|
||||
m_skidding_light_2->drop();
|
||||
m_head_light->drop();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -560,7 +547,7 @@ void KartGFX::setGFXInvisible()
|
||||
m_nitro_light->setVisible(false);
|
||||
m_skidding_light_1->setVisible(false);
|
||||
m_skidding_light_2->setVisible(false);
|
||||
m_head_light->setVisible(false);
|
||||
m_kart->getKartModel()->turnOffHeadlights();
|
||||
}
|
||||
#endif
|
||||
} // setGFXInvisible
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "race/race_manager.hpp"
|
||||
|
||||
class AbstractKart;
|
||||
class ParticleEmitter;
|
||||
@ -90,15 +89,12 @@ private:
|
||||
/** A light that's shown on the second skid-level with another color. */
|
||||
irr::scene::ISceneNode* m_skidding_light_2;
|
||||
|
||||
/** A light that's shown on the second skid-level with another color. */
|
||||
irr::scene::ISceneNode* m_head_light;
|
||||
|
||||
void addEffect(KartGFXType type, const std::string &file_name,
|
||||
const Vec3 &position, bool important);
|
||||
void resizeBox(const KartGFXType type, float new_size);
|
||||
|
||||
public:
|
||||
KartGFX(const AbstractKart *kart, RaceManager::KartType type, bool is_day);
|
||||
KartGFX(const AbstractKart *kart, bool is_day);
|
||||
~KartGFX();
|
||||
void reset();
|
||||
void setSkidLevel(const unsigned int level);
|
||||
|
@ -117,9 +117,7 @@ KartModel::KartModel(bool is_master)
|
||||
m_is_master = is_master;
|
||||
m_kart = NULL;
|
||||
m_mesh = NULL;
|
||||
m_hat_name = "";
|
||||
m_hat_node = NULL;
|
||||
m_hat_offset = core::vector3df(0,0,0);
|
||||
m_hat_location = NULL;
|
||||
m_render_info = NULL;
|
||||
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
@ -159,6 +157,7 @@ KartModel::KartModel(bool is_master)
|
||||
*/
|
||||
void KartModel::loadInfo(const XMLNode &node)
|
||||
{
|
||||
node.get("version", &m_version);
|
||||
node.get("model-file", &m_model_filename);
|
||||
if(const XMLNode *animation_node=node.getNode("animations"))
|
||||
{
|
||||
@ -195,11 +194,6 @@ void KartModel::loadInfo(const XMLNode &node)
|
||||
loadWheelInfo(*wheels_node, "rear-right", 2);
|
||||
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);
|
||||
@ -223,10 +217,27 @@ void KartModel::loadInfo(const XMLNode &node)
|
||||
}
|
||||
}
|
||||
|
||||
if(const XMLNode *hat_node=node.getNode("hat"))
|
||||
if (m_version > 2)
|
||||
{
|
||||
hat_node->get("offset", &m_hat_offset);
|
||||
if (const XMLNode* headlights_node = node.getNode("headlights"))
|
||||
{
|
||||
loadHeadlights(*headlights_node);
|
||||
}
|
||||
if (const XMLNode* hat_node = node.getNode("hat"))
|
||||
{
|
||||
core::vector3df position, rotation, scale;
|
||||
hat_node->get("position", &position);
|
||||
hat_node->get("rotation", &rotation);
|
||||
hat_node->get("scale", &scale);
|
||||
core::matrix4 lm, sm, rm;
|
||||
lm.setTranslation(position);
|
||||
sm.setScale(scale);
|
||||
rm.setRotationDegrees(rotation);
|
||||
m_hat_location = new core::matrix4(lm * rm * sm);
|
||||
hat_node->get("bone", &m_hat_bone);
|
||||
}
|
||||
}
|
||||
|
||||
} // loadInfo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -298,6 +309,7 @@ KartModel::~KartModel()
|
||||
}
|
||||
}
|
||||
|
||||
delete m_hat_location;
|
||||
delete m_render_info;
|
||||
#ifdef DEBUG
|
||||
#if SKELETON_DEBUG
|
||||
@ -322,6 +334,7 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
|
||||
assert(m_render_info == NULL);
|
||||
assert(!m_animated_node);
|
||||
KartModel *km = new KartModel(/*is master*/ false);
|
||||
km->m_version = m_version;
|
||||
km->m_kart_width = m_kart_width;
|
||||
km->m_kart_length = m_kart_length;
|
||||
km->m_kart_height = m_kart_height;
|
||||
@ -332,8 +345,8 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
|
||||
km->m_animation_speed = m_animation_speed;
|
||||
km->m_current_animation = AF_DEFAULT;
|
||||
km->m_animated_node = NULL;
|
||||
km->m_hat_offset = m_hat_offset;
|
||||
km->m_hat_name = m_hat_name;
|
||||
km->m_hat_bone = m_hat_bone;
|
||||
km->m_krt = krt;
|
||||
km->m_support_colorization = m_support_colorization;
|
||||
km->m_render_info = new RenderInfo();
|
||||
@ -342,6 +355,11 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
|
||||
km->m_nitro_emitter_position[0] = m_nitro_emitter_position[0];
|
||||
km->m_nitro_emitter_position[1] = m_nitro_emitter_position[1];
|
||||
km->m_has_nitro_emitter = m_has_nitro_emitter;
|
||||
if (m_hat_location)
|
||||
{
|
||||
km->m_hat_location = new core::matrix4();
|
||||
*(km->m_hat_location) = *m_hat_location;
|
||||
}
|
||||
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
@ -383,7 +401,7 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
|
||||
/** Attach the kart model and wheels to the scene node.
|
||||
* \return the node with the model attached
|
||||
*/
|
||||
scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_animated)
|
||||
scene::ISceneNode* KartModel::attachModel(bool animated_models, bool human_player)
|
||||
{
|
||||
assert(!m_is_master);
|
||||
|
||||
@ -401,7 +419,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
|
||||
NULL/*parent*/, getRenderInfo());
|
||||
node->setAutomaticCulling(scene::EAC_FRUSTUM_BOX);
|
||||
#endif
|
||||
if (always_animated)
|
||||
if (human_player)
|
||||
{
|
||||
// give a huge LOD distance for the player's kart. the reason is that it should
|
||||
// use its animations for the shadow pass too, where the camera can be quite far
|
||||
@ -418,8 +436,6 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
|
||||
m_animated_node = static_cast<scene::IAnimatedMeshSceneNode*>(node);
|
||||
}
|
||||
|
||||
attachHat();
|
||||
|
||||
#ifdef DEBUG
|
||||
std::string debug_name = m_model_filename+" (animated-kart-model)";
|
||||
node->setName(debug_name.c_str());
|
||||
@ -445,12 +461,6 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
|
||||
m_speed_weighted_objects[i].m_node->setParent(lod_node);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i<m_headlight_objects.size(); i++)
|
||||
{
|
||||
if (!m_headlight_objects[i].getNode()) continue;
|
||||
m_headlight_objects[i].getNode()->setParent(lod_node);
|
||||
}
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
// Enable rim lighting for the kart
|
||||
irr_driver->applyObjectPassShader(lod_node, true);
|
||||
@ -528,28 +538,48 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
|
||||
obj.m_node->setPosition(obj.m_position.toIrrVector());
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < m_headlight_objects.size(); i++)
|
||||
{
|
||||
HeadlightObject& obj = m_headlight_objects[i];
|
||||
|
||||
obj.setNode(NULL);
|
||||
if (obj.getModel())
|
||||
{
|
||||
scene::ISceneNode *new_node =
|
||||
irr_driver->addMesh(obj.getModel(), "kart_headlight",
|
||||
node, getRenderInfo() );
|
||||
|
||||
new_node->grab();
|
||||
obj.setNode(new_node);
|
||||
|
||||
Track* track = Track::getCurrentTrack();
|
||||
if (track == NULL || track->getIsDuringDay())
|
||||
obj.getNode()->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
const float each_energy = 0.2f / m_headlight_objects.size();
|
||||
const float each_radius = 2.0f / m_headlight_objects.size();
|
||||
for (unsigned int i = 0; i < m_headlight_objects.size(); i++)
|
||||
{
|
||||
HeadlightObject& obj = m_headlight_objects[i];
|
||||
Track* track = Track::getCurrentTrack();
|
||||
if (obj.getModel() && !(track == NULL || track->getIsDuringDay()))
|
||||
{
|
||||
const bool bone_attachment =
|
||||
m_animated_node && !obj.getBoneName().empty();
|
||||
scene::ISceneNode* parent = bone_attachment ?
|
||||
m_animated_node->getJointNode(obj.getBoneName().c_str()) : node;
|
||||
scene::ISceneNode* new_node =
|
||||
irr_driver->addMesh(obj.getModel(), "kart_headlight",
|
||||
parent, getRenderInfo());
|
||||
#ifndef SERVER_ONLY
|
||||
if (human_player && CVS->isGLSL() && CVS->isDefferedEnabled())
|
||||
{
|
||||
obj.setNode(irr_driver->addLight(core::vector3df
|
||||
(0.0f, 0.0f, 0.0f), each_energy, each_radius,
|
||||
1.0f, 1.0f, 1.0f, false, new_node));
|
||||
obj.getNode()->grab();
|
||||
}
|
||||
#endif
|
||||
configNode(new_node, obj.getLocation(), bone_attachment ?
|
||||
getInverseBoneMatrix(obj.getBoneName().c_str()) : core::matrix4());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_hat_location && !m_hat_name.empty())
|
||||
{
|
||||
const bool bone_attachment = m_animated_node && !m_hat_bone.empty();
|
||||
scene::ISceneNode* parent = bone_attachment ?
|
||||
m_animated_node->getJointNode(m_hat_bone.c_str()) : node;
|
||||
scene::IMesh* hat_mesh = irr_driver->getAnimatedMesh
|
||||
(file_manager->getAsset(FileManager::MODEL, m_hat_name));
|
||||
scene::ISceneNode* node = irr_driver->addMesh(hat_mesh, "hat", parent);
|
||||
configNode(node, *m_hat_location, bone_attachment ?
|
||||
getInverseBoneMatrix(m_hat_bone.c_str()) : core::matrix4());
|
||||
}
|
||||
|
||||
return node;
|
||||
} // attachModel
|
||||
|
||||
@ -770,14 +800,20 @@ void KartModel::loadHeadlights(const XMLNode &node)
|
||||
const XMLNode* child = node.getNode(i);
|
||||
if (child->getName() == "object")
|
||||
{
|
||||
// <object position="-0.168000 0.151288 0.917929" model="TuxHeadlight.spm"/>
|
||||
core::vector3df position;
|
||||
core::vector3df position, rotation, scale;
|
||||
child->get("position", &position);
|
||||
|
||||
child->get("rotation", &rotation);
|
||||
child->get("scale", &scale);
|
||||
core::matrix4 lm, sm, rm;
|
||||
lm.setTranslation(position);
|
||||
sm.setScale(scale);
|
||||
rm.setRotationDegrees(rotation);
|
||||
core::matrix4 location = lm * rm * sm;
|
||||
std::string bone_name;
|
||||
child->get("bone", &bone_name);
|
||||
std::string model;
|
||||
child->get("model", &model);
|
||||
|
||||
m_headlight_objects.push_back(HeadlightObject(model, position));
|
||||
m_headlight_objects.push_back(HeadlightObject(model, location, bone_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -809,6 +845,15 @@ void KartModel::reset()
|
||||
LODNode *lod = dynamic_cast<LODNode*>(m_kart->getNode());
|
||||
if (lod)
|
||||
lod->forceLevelOfDetail(-1);
|
||||
|
||||
for (unsigned int i = 0; i < m_headlight_objects.size(); i++)
|
||||
{
|
||||
HeadlightObject& obj = m_headlight_objects[i];
|
||||
if (obj.getNode())
|
||||
{
|
||||
obj.getNode()->setVisible(true);
|
||||
}
|
||||
}
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1123,55 +1168,47 @@ void KartModel::resetVisualWheelPosition()
|
||||
} // for i < 4
|
||||
} // resetVisualSuspension
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void KartModel::attachHat()
|
||||
{
|
||||
m_hat_node = NULL;
|
||||
if(m_hat_name.size()>0)
|
||||
{
|
||||
scene::IBoneSceneNode *bone = m_animated_node->getJointNode("Head");
|
||||
if(!bone)
|
||||
bone = m_animated_node->getJointNode("head");
|
||||
if(bone)
|
||||
{
|
||||
// Till we have all models fixed, accept Head and head as bone name
|
||||
scene::IMesh *hat_mesh =
|
||||
irr_driver->getAnimatedMesh(
|
||||
file_manager->getAsset(FileManager::MODEL, m_hat_name));
|
||||
m_hat_node = irr_driver->addMesh(hat_mesh, "hat");
|
||||
bone->addChild(m_hat_node);
|
||||
m_animated_node->setCurrentFrame((float)m_animation_frame[AF_STRAIGHT]);
|
||||
#ifndef SERVER_ONLY
|
||||
STKAnimatedMesh* am = dynamic_cast<STKAnimatedMesh*>(m_animated_node);
|
||||
if (am)
|
||||
{
|
||||
am->setHardwareSkinning(false);
|
||||
am->OnAnimate(0);
|
||||
am->setHardwareSkinning(true);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
m_animated_node->OnAnimate(0);
|
||||
bone->updateAbsolutePosition();
|
||||
// With the hat node attached to the head bone, we have to
|
||||
// reverse the transformation of the bone, so that the hat
|
||||
// is still properly placed. Esp. the hat offset needs
|
||||
// to be rotated.
|
||||
const core::matrix4 mat = bone->getAbsoluteTransformation();
|
||||
core::matrix4 inv;
|
||||
mat.getInverse(inv);
|
||||
core::vector3df rotated_offset;
|
||||
inv.rotateVect(rotated_offset, m_hat_offset);
|
||||
m_hat_node->setPosition(rotated_offset);
|
||||
m_hat_node->setScale(inv.getScale());
|
||||
m_hat_node->setRotation(inv.getRotationDegrees());
|
||||
} // if bone
|
||||
} // if(m_hat_name)
|
||||
} // attachHat
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderInfo* KartModel::getRenderInfo()
|
||||
{
|
||||
return m_support_colorization || m_krt == KRT_TRANSPARENT ?
|
||||
m_render_info : NULL;
|
||||
} // getRenderInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void KartModel::turnOffHeadlights()
|
||||
{
|
||||
for (unsigned int i = 0; i < m_headlight_objects.size(); i++)
|
||||
{
|
||||
HeadlightObject& obj = m_headlight_objects[i];
|
||||
if (obj.getNode())
|
||||
{
|
||||
obj.getNode()->setVisible(false);
|
||||
}
|
||||
}
|
||||
} // turnOffHeadlights
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
core::matrix4 KartModel::getInverseBoneMatrix(const char* bone_name)
|
||||
{
|
||||
assert(m_animated_node);
|
||||
scene::IBoneSceneNode* bone = m_animated_node->getJointNode(bone_name);
|
||||
assert(bone);
|
||||
m_animated_node->setCurrentFrame((float)m_animation_frame[AF_STRAIGHT]);
|
||||
#ifndef SERVER_ONLY
|
||||
STKAnimatedMesh* am = dynamic_cast<STKAnimatedMesh*>(m_animated_node);
|
||||
if (am)
|
||||
{
|
||||
am->setHardwareSkinning(false);
|
||||
am->OnAnimate(0);
|
||||
am->setHardwareSkinning(true);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
m_animated_node->OnAnimate(0);
|
||||
bone->updateAbsolutePosition();
|
||||
const core::matrix4 mat = bone->getAbsoluteTransformation();
|
||||
core::matrix4 inv;
|
||||
mat.getInverse(inv);
|
||||
return inv;
|
||||
} // getInverseBoneMatrix
|
||||
|
@ -92,30 +92,32 @@ class HeadlightObject
|
||||
private:
|
||||
/** The filename of the headlight model. */
|
||||
std::string m_filename;
|
||||
/** The position relative to the parent kart scene node where the
|
||||
* headlight mesh is attached to. */
|
||||
core::vector3df m_position;
|
||||
/** The relative matrix to the parent kart scene node
|
||||
* or bone where the headlight mesh is attached to. */
|
||||
core::matrix4 m_location;
|
||||
/** The mesh for the headlight. */
|
||||
scene::IMesh* m_model;
|
||||
/** The scene node of the headlight. */
|
||||
scene::ISceneNode* m_node;
|
||||
|
||||
std::string m_bone_name;
|
||||
|
||||
public:
|
||||
|
||||
HeadlightObject()
|
||||
{
|
||||
m_model = NULL;
|
||||
m_node = NULL;
|
||||
m_filename = "";
|
||||
m_position.set(0, 0, 0);
|
||||
} // HeadlightObject
|
||||
// ------------------------------------------------------------------------
|
||||
HeadlightObject(const std::string& filename, core::vector3df &pos)
|
||||
HeadlightObject(const std::string& filename, const core::matrix4& location,
|
||||
const std::string& bone_name)
|
||||
{
|
||||
m_filename = filename;
|
||||
m_position = pos;
|
||||
m_location = location;
|
||||
m_model = NULL;
|
||||
m_node = NULL;
|
||||
m_bone_name = bone_name;
|
||||
} // HeadlightObjects
|
||||
// ------------------------------------------------------------------------
|
||||
const std::string& getFilename() const { return m_filename; }
|
||||
@ -123,12 +125,10 @@ public:
|
||||
/** Sets the mesh for this headlight object. */
|
||||
void setModel(scene::IMesh *mesh) { m_model = mesh; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the node of the headlight, and (if not NULL) also sets the
|
||||
* position of this scene node to be the position of the headlight. */
|
||||
/** Sets the node of the headlight. */
|
||||
void setNode(scene::ISceneNode *node)
|
||||
{
|
||||
m_node = node;
|
||||
if (m_node) m_node->setPosition(m_position);
|
||||
m_node = node;
|
||||
} // setNode
|
||||
// ------------------------------------------------------------------------
|
||||
const scene::ISceneNode *getNode() const { return m_node; }
|
||||
@ -139,6 +139,10 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
scene::IMesh *getModel() { return m_model; }
|
||||
// ------------------------------------------------------------------------
|
||||
const core::matrix4& getLocation() const { return m_location; }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::string& getBoneName() const { return m_bone_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
}; // class HeadlightObject
|
||||
|
||||
// ============================================================================
|
||||
@ -198,11 +202,11 @@ private:
|
||||
* (i.e. neither read nor written) if animations are disabled. */
|
||||
scene::IAnimatedMeshSceneNode *m_animated_node;
|
||||
|
||||
/** The scene node for a hat the driver is wearing. */
|
||||
scene::IMeshSceneNode *m_hat_node;
|
||||
/** Location of hat in object space. */
|
||||
core::matrix4* m_hat_location;
|
||||
|
||||
/** Offset of the hat relative to the bone called 'head'. */
|
||||
core::vector3df m_hat_offset;
|
||||
/** Name of the bone for hat attachment. */
|
||||
std::string m_hat_bone;
|
||||
|
||||
/** Name of the hat to use for this kart. "" if no hat. */
|
||||
std::string m_hat_name;
|
||||
@ -307,6 +311,23 @@ private:
|
||||
|
||||
bool m_support_colorization;
|
||||
|
||||
unsigned m_version;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
core::matrix4 getInverseBoneMatrix(const char* bone_name);
|
||||
// ------------------------------------------------------------------------
|
||||
void configNode(scene::ISceneNode* node, const core::matrix4& global_mat,
|
||||
const core::matrix4& inv_mat)
|
||||
{
|
||||
const core::matrix4 mat = inv_mat * global_mat;
|
||||
const core::vector3df position = mat.getTranslation();
|
||||
const core::vector3df rotation = mat.getRotationDegrees();
|
||||
const core::vector3df scale = mat.getScale();
|
||||
node->setPosition(position);
|
||||
node->setRotation(rotation);
|
||||
node->setScale(scale);
|
||||
}
|
||||
|
||||
public:
|
||||
KartModel(bool is_master);
|
||||
~KartModel();
|
||||
@ -321,7 +342,7 @@ public:
|
||||
void finishedRace();
|
||||
void resetVisualWheelPosition();
|
||||
scene::ISceneNode*
|
||||
attachModel(bool animatedModels, bool always_animated);
|
||||
attachModel(bool animatedModels, bool human_player);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the animated mesh of this kart model. */
|
||||
scene::IAnimatedMesh*
|
||||
@ -403,18 +424,16 @@ public:
|
||||
/** Name of the hat mesh to use. */
|
||||
void setHatMeshName(const std::string &name) {m_hat_name = name; }
|
||||
// ------------------------------------------------------------------------
|
||||
void attachHat();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the array of wheel nodes. */
|
||||
scene::ISceneNode** getWheelNodes() { return m_wheel_node; }
|
||||
// ------------------------------------------------------------------------
|
||||
scene::IAnimatedMeshSceneNode* getAnimatedNode(){ return m_animated_node; }
|
||||
// ------------------------------------------------------------------------
|
||||
core::vector3df getHatOffset() { return m_hat_offset; }
|
||||
// ------------------------------------------------------------------------
|
||||
RenderInfo* getRenderInfo();
|
||||
// ------------------------------------------------------------------------
|
||||
bool supportColorization() const { return m_support_colorization; }
|
||||
// ------------------------------------------------------------------------
|
||||
void turnOffHeadlights();
|
||||
|
||||
}; // KartModel
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user