Allow speed weight objects to be attached to bone

This commit is contained in:
Benau 2017-09-18 11:27:21 +08:00
parent f6fa44f0df
commit b09eec4bcb
18 changed files with 322 additions and 272 deletions

View File

@ -23,6 +23,7 @@
#include "karts/abstract_kart.hpp"
#include "karts/explosion_animation.hpp"
#include "karts/kart.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/skidding.hpp"
#include "physics/btKart.hpp"

View File

@ -89,10 +89,10 @@ void ModelViewWidget::clearModels()
{
m_models.clearWithoutDeleting();
m_model_location.clear();
m_model_scale.clear();
m_model_frames.clear();
m_model_render_info_affected.clear();
m_model_animation_speed.clear();
m_bone_attached.clear();
if (m_rtt_main_node != NULL) m_rtt_main_node->remove();
if (m_light != NULL) m_light->remove();
@ -106,19 +106,21 @@ void ModelViewWidget::clearModels()
// -----------------------------------------------------------------------------
void ModelViewWidget::addModel(irr::scene::IMesh* mesh, const Vec3& location,
const Vec3& scale, const int start_loop_frame,
void ModelViewWidget::addModel(irr::scene::IMesh* mesh,
const core::matrix4& location,
const int start_loop_frame,
const int end_loop_frame,
bool all_parts_colorized, float animation_speed)
bool all_parts_colorized, float animation_speed,
const std::string& bone_name)
{
if(!mesh) return;
m_models.push_back(mesh);
m_model_location.push_back(location);
m_model_scale.push_back(scale);
m_model_frames.emplace_back(start_loop_frame, end_loop_frame);
m_model_render_info_affected.push_back(all_parts_colorized);
m_model_animation_speed.push_back(animation_speed);
m_bone_attached.push_back(bone_name);
#ifndef SERVER_ONLY
if (!CVS->isGLSL())
m_render_target = NULL;
@ -219,59 +221,69 @@ void ModelViewWidget::setupRTTScene()
m_light = NULL;
irr_driver->clearLights();
scene::IAnimatedMeshSceneNode* animated_node = NULL;
if (m_model_frames[0].first == -1)
{
scene::ISceneNode* node = irr_driver->addMesh(m_models.get(0), "rtt_mesh",
NULL, m_render_info, m_model_render_info_affected[0]);
node->setPosition(m_model_location[0].toIrrVector());
node->setScale(m_model_scale[0].toIrrVector());
node->setPosition(m_model_location[0].getTranslation());
node->setRotation(m_model_location[0].getRotationDegrees());
node->setScale(m_model_location[0].getScale());
node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_rtt_main_node = node;
}
else
{
scene::IAnimatedMeshSceneNode* node =
animated_node =
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_models.get(0), "rtt_mesh",
NULL, m_render_info, m_model_render_info_affected[0]);
node->setPosition(m_model_location[0].toIrrVector());
node->setFrameLoop(m_model_frames[0].first, m_model_frames[0].second);
node->setAnimationSpeed(m_model_animation_speed[0]);
node->setScale(m_model_scale[0].toIrrVector());
node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_rtt_main_node = node;
animated_node->setPosition(m_model_location[0].getTranslation());
animated_node->setRotation(m_model_location[0].getRotationDegrees());
animated_node->setScale(m_model_location[0].getScale());
animated_node->setFrameLoop(m_model_frames[0].first, m_model_frames[0].second);
animated_node->setAnimationSpeed(m_model_animation_speed[0]);
animated_node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_rtt_main_node = animated_node;
}
assert(m_rtt_main_node != NULL);
assert(m_models.size() == m_model_location.size());
assert(m_models.size() == m_model_frames.size());
assert(m_models.size() == m_model_scale.size());
assert(m_models.size() == m_model_render_info_affected.size());
assert(m_models.size() == m_model_animation_speed.size());
assert(m_models.size() == m_bone_attached.size());
const int mesh_amount = m_models.size();
for (int n = 1; n<mesh_amount; n++)
for (int n = 1; n < mesh_amount; n++)
{
const bool bone_attachment =
animated_node && !m_bone_attached[n].empty();
scene::ISceneNode* parent = bone_attachment ?
animated_node->getJointNode(m_bone_attached[n].c_str()) :
m_rtt_main_node;
assert(parent);
if (m_model_frames[n].first == -1)
{
scene::ISceneNode* node =
irr_driver->addMesh(m_models.get(n), "rtt_node", m_rtt_main_node,
irr_driver->addMesh(m_models.get(n), "rtt_node", parent,
m_render_info, m_model_render_info_affected[n]);
node->setPosition(m_model_location[n].toIrrVector());
node->setPosition(m_model_location[n].getTranslation());
node->setRotation(m_model_location[n].getRotationDegrees());
node->setScale(m_model_location[n].getScale());
node->updateAbsolutePosition();
node->setScale(m_model_scale[n].toIrrVector());
}
else
{
scene::IAnimatedMeshSceneNode* node =
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_models.get(n),
"modelviewrtt", m_rtt_main_node, m_render_info,
"modelviewrtt", parent, m_render_info,
m_model_render_info_affected[n]);
node->setPosition(m_model_location[n].toIrrVector());
node->setPosition(m_model_location[n].getTranslation());
node->setRotation(m_model_location[n].getRotationDegrees());
node->setScale(m_model_location[n].getScale());
node->setFrameLoop(m_model_frames[n].first, m_model_frames[n].second);
node->setAnimationSpeed(m_model_animation_speed[n]);
node->updateAbsolutePosition();
node->setScale(m_model_scale[n].toIrrVector());
//Log::info("ModelViewWidget", "Set frame %d", m_model_frames[n]);
}
}

View File

@ -48,11 +48,11 @@ namespace GUIEngine
float m_rotation_target;
PtrVector<scene::IMesh, REF> m_models;
AlignedArray<Vec3> m_model_location;
AlignedArray<Vec3> m_model_scale;
std::vector<core::matrix4> m_model_location;
std::vector<std::pair<int, int> > m_model_frames;
std::vector<bool> m_model_render_info_affected;
std::vector<float> m_model_animation_speed;
std::vector<std::string> m_bone_attached;
std::unique_ptr<RenderTarget> m_render_target;
float m_angle;
@ -76,12 +76,12 @@ namespace GUIEngine
void add();
void clearModels();
void addModel(irr::scene::IMesh* mesh,
const Vec3& location = Vec3(0,0,0),
const Vec3& scale = Vec3(1,1,1),
const core::matrix4& location = core::matrix4(),
const int start_loop_frame=-1,
const int end_loop_frame=-1,
bool all_parts_colorized = false,
float animation_speed=0.0f);
float animation_speed = 0.0f,
const std::string& bone_name = std::string());
void update(float delta);

View File

@ -24,6 +24,7 @@
#include "guiengine/widgets/model_view_widget.hpp"
#include "guiengine/widgets/player_name_spinner.hpp"
#include "input/input_device.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "network/network_player_profile.hpp"
@ -193,6 +194,8 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
scale = 30.0f;
}
core::matrix4 model_location;
model_location.setScale(core::vector3df(scale, scale, scale));
const bool has_win_anime =
UserConfigParams::m_show_steering_animations != 0 &&
(((kart_model.getFrame(KartModel::AF_WIN_LOOP_START) > -1 ||
@ -200,8 +203,7 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
kart_model.getFrame(KartModel::AF_WIN_END) > -1) ||
(kart_model.getFrame(KartModel::AF_SELECTION_START) > -1 &&
kart_model.getFrame(KartModel::AF_SELECTION_END) > -1));
m_model_view->addModel( kart_model.getModel(), Vec3(0,0,0),
Vec3(scale, scale, scale),
m_model_view->addModel( kart_model.getModel(), model_location,
has_win_anime ?
kart_model.getFrame(KartModel::AF_SELECTION_START) > -1 ?
kart_model.getFrame(KartModel::AF_SELECTION_START) :
@ -216,18 +218,27 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
kart_model.getBaseFrame(),
false/*all_parts_colorized*/,
kart_model.getAnimationSpeed());
m_model_view->addModel( kart_model.getWheelModel(0),
kart_model.getWheelGraphicsPosition(0) );
m_model_view->addModel( kart_model.getWheelModel(1),
kart_model.getWheelGraphicsPosition(1) );
m_model_view->addModel( kart_model.getWheelModel(2),
kart_model.getWheelGraphicsPosition(2) );
m_model_view->addModel( kart_model.getWheelModel(3),
kart_model.getWheelGraphicsPosition(3) );
for(size_t i=0 ; i < kart_model.getSpeedWeightedObjectsCount() ; i++)
model_location.setScale(core::vector3df(1.0f, 1.0f, 1.0f));
for (unsigned i = 0; i < 4; i++)
{
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject((int)i);
m_model_view->addModel(obj.m_model, obj.m_position);
model_location.setTranslation(kart_model
.getWheelGraphicsPosition(i).toIrrVector());
m_model_view->addModel(kart_model.getWheelModel(i), model_location);
}
for (unsigned i = 0; i < kart_model.getSpeedWeightedObjectsCount(); i++)
{
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject(i);
core::matrix4 swol = obj.m_location;
if (!obj.m_bone_name.empty())
{
core::matrix4 inv =
kart_model.getInverseBoneMatrix(obj.m_bone_name);
swol = inv * obj.m_location;
}
m_model_view->addModel(obj.m_model, swol, -1, -1, false, 0.0f,
obj.m_bone_name);
}
m_model_view->setRotateContinuously( 35.0f );

View File

@ -22,6 +22,7 @@
#include "graphics/render_info.hpp"
#include "items/powerup.hpp"
#include "karts/abstract_kart_animation.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "utils/log.hpp"

View File

@ -23,6 +23,7 @@
#include "animations/three_d_animation.hpp"
#include "items/flyable.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "modes/world.hpp"

View File

@ -28,6 +28,7 @@
#include "karts/abstract_kart.hpp"
#include "karts/controller/controller.hpp"
#include "karts/kart.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/skidding.hpp"
#include "physics/btKart.hpp"

View File

@ -52,14 +52,12 @@ float KartModel::UNDEFINED = -99.9f;
// ------------------------------------------------------------
// SpeedWeightedObject implementation
#define SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED -99.f
SpeedWeightedObject::Properties::Properties()
{
m_strength_factor = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED;
m_speed_factor = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED;
m_texture_speed.X = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED;
m_texture_speed.Y = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED;
m_strength_factor = -1.0f;
m_speed_factor = 0.0f;
m_texture_speed.X = 0.0f;
m_texture_speed.Y = 0.0f;
} // SpeedWeightedObject::Properties::Properties
// ----------------------------------------------------------------------------
@ -71,22 +69,6 @@ void SpeedWeightedObject::Properties::loadFromXMLNode(const XMLNode* xml_node)
xml_node->get("texture-speed-y", &m_texture_speed.Y);
} // SpeedWeightedObject::Properties::loadFromXMLNode
// ----------------------------------------------------------------------------
void SpeedWeightedObject::Properties::checkAllSet()
{
#define CHECK_NEG( a,strA) if(a<=SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED) \
{ \
Log::fatal("SpeedWeightedObject", \
"Missing default value for '%s'.", \
strA); \
}
CHECK_NEG(m_strength_factor, "speed-weighted strength-factor" );
CHECK_NEG(m_speed_factor, "speed-weighted speed-factor" );
CHECK_NEG(m_texture_speed.X, "speed-weighted texture speed X" );
CHECK_NEG(m_texture_speed.Y, "speed-weighted texture speed Y" );
#undef CHECK_NEG
} // SpeedWeightedObject::Properties::checkAllSet
// ============================================================================
/** Default constructor which initialises all variables with defaults.
* Note that the KartModel is copied, so make sure to update makeCopy
@ -157,7 +139,6 @@ 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"))
{
@ -177,13 +158,11 @@ void KartModel::loadInfo(const XMLNode &node)
animation_node->get("start-jump", &m_animation_frame[AF_JUMP_START]);
animation_node->get("start-jump-loop",&m_animation_frame[AF_JUMP_LOOP] );
animation_node->get("end-jump", &m_animation_frame[AF_JUMP_END] );
animation_node->get("selection-start", &m_animation_frame[AF_SELECTION_START]);
animation_node->get("selection-end", &m_animation_frame[AF_SELECTION_END] );
animation_node->get("backpedal-left", &m_animation_frame[AF_BACK_LEFT]);
animation_node->get("backpedal", &m_animation_frame[AF_BACK_STRAIGHT]);
animation_node->get("backpedal-right",&m_animation_frame[AF_BACK_RIGHT]);
animation_node->get("start-speed-weighted", &m_animation_frame[AF_SPEED_WEIGHTED_START]);
animation_node->get("end-speed-weighted", &m_animation_frame[AF_SPEED_WEIGHTED_END] );
animation_node->get("selection-start", &m_animation_frame[AF_SELECTION_START]);
animation_node->get("selection-end", &m_animation_frame[AF_SELECTION_END] );
animation_node->get("speed", &m_animation_speed );
}
@ -206,19 +185,17 @@ void KartModel::loadInfo(const XMLNode &node)
m_has_nitro_emitter = true;
}
if(const XMLNode *speed_weighted_objects_node=node.getNode("speed-weighted-objects"))
unsigned kart_version;
node.get("version", &kart_version);
if (kart_version > 2)
{
SpeedWeightedObject::Properties fallback_properties;
fallback_properties.loadFromXMLNode(speed_weighted_objects_node);
for(unsigned int i=0 ; i < speed_weighted_objects_node->getNumNodes() ; i++)
if (const XMLNode *speed_weighted_objects_node = node.getNode("speed-weighted-objects"))
{
loadSpeedWeightedInfo(speed_weighted_objects_node->getNode(i), fallback_properties);
for (unsigned int i = 0 ;i < speed_weighted_objects_node->getNumNodes() ; i++)
{
loadSpeedWeightedInfo(speed_weighted_objects_node->getNode(i));
}
}
}
if (m_version > 2)
{
if (const XMLNode* headlights_node = node.getNode("headlights"))
{
loadHeadlights(*headlights_node);
@ -274,10 +251,14 @@ KartModel::~KartModel()
assert(!m_is_master);
m_speed_weighted_objects[i].m_node->drop();
}
if(m_is_master && m_speed_weighted_objects[i].m_model)
if (m_is_master && m_speed_weighted_objects[i].m_model)
{
m_speed_weighted_objects[i].m_model->drop();
irr_driver->dropAllTextures(m_speed_weighted_objects[i].m_model);
irr_driver->removeMeshFromCache(m_speed_weighted_objects[i].m_model);
if (m_speed_weighted_objects[i].m_model->getReferenceCount() == 1)
{
irr_driver->removeMeshFromCache(m_speed_weighted_objects[i].m_model);
}
}
}
@ -337,23 +318,23 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
assert(m_is_master);
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;
km->m_kart_highest_point = m_kart_highest_point;
km->m_kart_lowest_point = m_kart_lowest_point;
km->m_mesh = m_mesh;
km->m_model_filename = m_model_filename;
km->m_animation_speed = m_animation_speed;
km->m_current_animation = AF_DEFAULT;
km->m_animated_node = NULL;
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();
KartModel *km = new KartModel(/*is master*/ false);
km->m_kart_width = m_kart_width;
km->m_kart_length = m_kart_length;
km->m_kart_height = m_kart_height;
km->m_kart_highest_point = m_kart_highest_point;
km->m_kart_lowest_point = m_kart_lowest_point;
km->m_mesh = m_mesh;
km->m_model_filename = m_model_filename;
km->m_animation_speed = m_animation_speed;
km->m_current_animation = AF_DEFAULT;
km->m_animated_node = NULL;
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();
km->m_inverse_bone_matrices = m_inverse_bone_matrices;
km->m_render_info->setKartModelRenderInfo(krt);
km->m_nitro_emitter_position[0] = m_nitro_emitter_position[0];
@ -458,13 +439,6 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool human_playe
m_wheel_node[i]->setParent(lod_node);
}
// Become the owner of the speed weighted objects
for(size_t i=0; i<m_speed_weighted_objects.size(); i++)
{
if(!m_speed_weighted_objects[i].m_node) continue;
m_speed_weighted_objects[i].m_node->setParent(lod_node);
}
#ifndef SERVER_ONLY
// Enable rim lighting for the kart
irr_driver->applyObjectPassShader(lod_node, true);
@ -513,36 +487,51 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool human_playe
m_wheel_node[i]->grab();
((scene::IMeshSceneNode *) m_wheel_node[i])->setReadOnlyMaterials(true);
#ifdef DEBUG
#ifdef DEBUG
std::string debug_name = m_wheel_filename[i]+" (wheel)";
m_wheel_node[i]->setName(debug_name.c_str());
#endif
#endif
m_wheel_node[i]->setPosition(m_wheel_graphics_position[i].toIrrVector());
}
// Attach the speed weighted objects + set the animation state
for(size_t i=0 ; i < m_speed_weighted_objects.size() ; i++)
}
// Attach the speed weighted objects + set the animation state
for (unsigned int i = 0; i < m_speed_weighted_objects.size() ;i++)
{
SpeedWeightedObject& obj = m_speed_weighted_objects[i];
obj.m_node = NULL;
if (obj.m_model)
{
SpeedWeightedObject& obj = m_speed_weighted_objects[i];
obj.m_node = NULL;
if(obj.m_model)
const bool bone_attachment =
m_animated_node && !obj.m_bone_name.empty();
scene::ISceneNode* parent = bone_attachment ?
m_animated_node->getJointNode(obj.m_bone_name.c_str()) : node;
scene::ISceneNode* swo = NULL;
if (animated_models)
{
// Only need to keep track of animated node for speed setting
obj.m_node = irr_driver->addAnimatedMesh(obj.m_model,
"speedweighted", node, getRenderInfo(),
true/*all_parts_colorized*/);
"speedweighted", parent, getRenderInfo(),
true/*all_parts_colorized*/);
swo = obj.m_node;
obj.m_node->grab();
obj.m_node->setFrameLoop(m_animation_frame[AF_SPEED_WEIGHTED_START],
m_animation_frame[AF_SPEED_WEIGHTED_END]);
#ifdef DEBUG
std::string debug_name = obj.m_name+" (speed-weighted)";
obj.m_node->setName(debug_name.c_str());
#endif
obj.m_node->setPosition(obj.m_position.toIrrVector());
obj.m_node->setFrameLoop(0, obj.m_model->getFrameCount() - 1);
}
else
{
swo = irr_driver->addMesh(obj.m_model, "speedweighted",
parent, getRenderInfo(), true/*all_parts_colorized*/);
}
#ifdef DEBUG
std::string debug_name = obj.m_name + " (speed-weighted)";
swo->setName(debug_name.c_str());
#endif
configNode(swo, obj.m_location, bone_attachment ?
getInverseBoneMatrix(obj.m_bone_name) : core::matrix4());
}
}
const float each_energy = 0.5f / m_headlight_objects.size();
const float each_radius = 5.0f / m_headlight_objects.size();
for (unsigned int i = 0; i < m_headlight_objects.size(); i++)
@ -565,7 +554,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool human_playe
}
#endif
configNode(headlight_model, obj.getLocation(), bone_attachment ?
getInverseBoneMatrix(obj.getBoneName().c_str()) : core::matrix4());
getInverseBoneMatrix(obj.getBoneName()) : core::matrix4());
}
}
@ -578,7 +567,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool human_playe
(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());
getInverseBoneMatrix(m_hat_bone) : core::matrix4());
}
return node;
@ -657,6 +646,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
#endif
m_kart_highest_point = kart_max.getY();
m_kart_lowest_point = kart_min.getY();
initInverseBoneMatrices();
// Load the speed weighted object models. We need to do that now because it can affect the dimensions of the kart
for(size_t i=0 ; i < m_speed_weighted_objects.size() ; i++)
@ -676,18 +666,18 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
MeshTools::createSkinnedMeshWithTangents(sm,
&MeshTools::isNormalMap);
}
irr_driver->grabAllTextures(obj.m_model);
#endif
// Update min/max
obj.m_model->grab();
irr_driver->grabAllTextures(obj.m_model);
// Update min/max, speed weight can be scaled
Vec3 obj_min, obj_max;
int frame = m_animation_frame[AF_SPEED_WEIGHTED_START];
if (frame < 0)
frame = 0;
MeshTools::minMax3D(obj.m_model->getMesh(frame), &obj_min, &obj_max);
obj_min += obj.m_position;
obj_max += obj.m_position;
kart_min.min(obj_min);
kart_max.max(obj_max);
MeshTools::minMax3D(obj.m_model->getMesh(0), &obj_min, &obj_max);
core::vector3df transformed_min, transformed_max;
obj.m_location.transformVect(transformed_min, obj_min.toIrrVector());
obj.m_location.transformVect(transformed_max, obj_max.toIrrVector());
kart_min.min(transformed_min);
kart_max.max(transformed_max);
}
for (unsigned int i = 0; i < m_headlight_objects.size(); i++)
@ -771,18 +761,33 @@ void KartModel::loadNitroEmitterInfo(const XMLNode &node,
// ----------------------------------------------------------------------------
/** Loads a single speed weighted node. */
void KartModel::loadSpeedWeightedInfo(const XMLNode* speed_weighted_node,
const SpeedWeightedObject::Properties& fallback_properties)
void KartModel::loadSpeedWeightedInfo(const XMLNode* speed_weighted_node)
{
SpeedWeightedObject obj;
obj.m_properties = fallback_properties;
obj.m_properties.loadFromXMLNode(speed_weighted_node);
speed_weighted_node->get("position", &obj.m_position);
speed_weighted_node->get("model", &obj.m_name);
if(!obj.m_name.empty())
if (speed_weighted_node->getName() == "object")
{
core::vector3df position, rotation, scale;
speed_weighted_node->get("position", &position);
speed_weighted_node->get("rotation", &rotation);
speed_weighted_node->get("scale", &scale);
core::matrix4 lm, sm, rm;
lm.setTranslation(position);
sm.setScale(scale);
rm.setRotationDegrees(rotation);
obj.m_location = lm * rm * sm;
speed_weighted_node->get("bone", &obj.m_bone_name);
speed_weighted_node->get("model", &obj.m_name);
obj.m_properties.loadFromXMLNode(speed_weighted_node);
}
else
{
Log::warn("KartModel",
"Unknown XML node in the speed weighted objects section");
}
if (!obj.m_name.empty())
{
m_speed_weighted_objects.push_back(obj);
}
}
// ----------------------------------------------------------------------------
@ -1081,20 +1086,21 @@ void KartModel::update(float dt, float distance, float steer, float speed,
{
SpeedWeightedObject& obj = m_speed_weighted_objects[i];
#define GET_VALUE(obj, value_name) \
obj.m_properties.value_name > SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED ? obj.m_properties.value_name : \
m_kart->getKartProperties()->getSpeedWeightedObjectProperties().value_name
if (obj.m_node == NULL)
{
continue;
}
// Animation strength
const float strength_factor = GET_VALUE(obj, m_strength_factor);
const float strength_factor = obj.m_properties.m_strength_factor;
if (strength_factor >= 0.0f)
{
float strength = speed * strength_factor;
btClamp<float>(strength, 0.0f, 1.0f);
obj.m_node->setAnimationStrength(strength);
}
// Animation speed
const float speed_factor = GET_VALUE(obj, m_speed_factor);
const float speed_factor = obj.m_properties.m_speed_factor;
if (speed_factor >= 0.0f)
{
float anim_speed = speed * speed_factor;
@ -1103,8 +1109,8 @@ void KartModel::update(float dt, float distance, float steer, float speed,
// Texture animation
core::vector2df tex_speed;
tex_speed.X = GET_VALUE(obj, m_texture_speed.X);
tex_speed.Y = GET_VALUE(obj, m_texture_speed.Y);
tex_speed.X = obj.m_properties.m_texture_speed.X;
tex_speed.Y = obj.m_properties.m_texture_speed.Y;
if (tex_speed != core::vector2df(0.0f, 0.0f))
{
obj.m_texture_cur_offset += speed * tex_speed * dt;
@ -1123,7 +1129,6 @@ void KartModel::update(float dt, float distance, float steer, float speed,
} // for j<MATERIAL_MAX_TEXTURES
} // for i<getMaterialCount
}
#undef GET_VALUE
}
}
@ -1199,26 +1204,41 @@ void KartModel::toggleHeadlights(bool on)
} // toggleHeadlights
//-----------------------------------------------------------------------------
core::matrix4 KartModel::getInverseBoneMatrix(const char* bone_name)
void KartModel::initInverseBoneMatrices()
{
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)
// Due to irrlicht mesh doesn't expose bone name, we have to create a
// dummy aniamted node
// All bone matrices are configured in straight frame (as in exporting)
scene::IAnimatedMeshSceneNode* node = irr_driver->getSceneManager()
->addAnimatedMeshSceneNode(m_mesh);
node->setCurrentFrame((float)m_animation_frame[AF_STRAIGHT]);
const unsigned total_joint = node->getJointCount();
for (unsigned i = 0; i < total_joint; i++)
{
am->setHardwareSkinning(false);
am->OnAnimate(0);
am->setHardwareSkinning(true);
node->OnAnimate(0);
scene::IBoneSceneNode* bone = node->getJointNode(i);
bone->updateAbsolutePosition();
const core::matrix4 mat = bone->getAbsoluteTransformation();
core::matrix4 inv;
mat.getInverse(inv);
const std::string bone_name = bone->getName();
auto ret = m_inverse_bone_matrices.find(bone_name);
if (ret != m_inverse_bone_matrices.end())
{
Log::warn("KartModel", "%s has duplicated bone, name: %s,"
" attachment may not work correctly.",
m_model_filename.c_str(), bone_name.c_str());
}
m_inverse_bone_matrices[bone_name] = inv;
}
else
#endif
m_animated_node->OnAnimate(0);
bone->updateAbsolutePosition();
const core::matrix4 mat = bone->getAbsoluteTransformation();
core::matrix4 inv;
mat.getInverse(inv);
return inv;
node->remove();
} // initInverseBoneMatrices
//-----------------------------------------------------------------------------
const core::matrix4& KartModel::getInverseBoneMatrix
(const std::string& bone_name) const
{
auto ret = m_inverse_bone_matrices.find(bone_name);
assert(ret != m_inverse_bone_matrices.end());
return ret->second;
} // getInverseBoneMatrix

View File

@ -20,6 +20,7 @@
#define HEADER_KART_MODEL_HPP
#include <string>
#include <unordered_map>
#include <vector>
#include <IAnimatedMeshSceneNode.h>
@ -59,22 +60,25 @@ struct SpeedWeightedObject
void loadFromXMLNode(const XMLNode* xml_node);
void checkAllSet();
};
SpeedWeightedObject() : m_model(NULL), m_node(NULL), m_position(), m_name() {}
SpeedWeightedObject() : m_model(NULL), m_node(NULL), m_name() {}
/** Model */
scene::IAnimatedMesh * m_model;
/** The scene node the speed weighted model is attached to */
scene::IAnimatedMeshSceneNode * m_node;
/** The position of the "speed weighted" objects relative to the kart */
Vec3 m_position;
/** The relative matrix to the parent kart scene node
* where the speed weighted object is attached to. */
core::matrix4 m_location;
/** Filename of the "speed weighted" object */
std::string m_name;
/** Attach to which bone in kart model if not empty. */
std::string m_bone_name;
/** Current uv translation in the texture matrix for speed-weighted texture animations */
core::vector2df m_texture_cur_offset;
@ -94,7 +98,7 @@ private:
std::string m_filename;
/** The relative matrix to the parent kart scene node
* or bone where the headlight mesh is attached to. */
* where the headlight mesh is attached to. */
core::matrix4 m_location;
/** The mesh for the headlight. */
@ -186,9 +190,7 @@ public:
AF_BACK_LEFT, // Going back left
AF_BACK_STRAIGHT, // Going back straight
AF_BACK_RIGHT, // Going back right
AF_SPEED_WEIGHTED_START, // Start of speed-weighted animation
AF_SPEED_WEIGHTED_END, // End of speed-weighted animation
AF_END=AF_SPEED_WEIGHTED_END, // Last animation frame
AF_END=AF_BACK_RIGHT, // Last animation frame
AF_COUNT}; // Number of entries here
private:
@ -299,8 +301,7 @@ private:
void loadNitroEmitterInfo(const XMLNode &node,
const std::string &emitter_name, int index);
void loadSpeedWeightedInfo(const XMLNode* speed_weighted_node,
const SpeedWeightedObject::Properties& fallback_properties);
void loadSpeedWeightedInfo(const XMLNode* speed_weighted_node);
void loadHeadlights(const XMLNode &node);
@ -315,10 +316,10 @@ private:
bool m_support_colorization;
unsigned m_version;
std::unordered_map<std::string, core::matrix4> m_inverse_bone_matrices;
// ------------------------------------------------------------------------
core::matrix4 getInverseBoneMatrix(const char* bone_name);
void initInverseBoneMatrices();
// ------------------------------------------------------------------------
void configNode(scene::ISceneNode* node, const core::matrix4& global_mat,
const core::matrix4& inv_mat)
@ -438,6 +439,9 @@ public:
bool supportColorization() const { return m_support_colorization; }
// ------------------------------------------------------------------------
void toggleHeadlights(bool on);
// ------------------------------------------------------------------------
const core::matrix4&
getInverseBoneMatrix(const std::string& bone_name) const;
}; // KartModel
#endif

View File

@ -306,6 +306,25 @@ void KartProperties::load(const std::string &filename, const std::string &node)
} // load
// ----------------------------------------------------------------------------
/** Returns a pointer to the KartModel object.
* \param krt The KartRenderType, like default, red, blue or transparent.
* see the RenderInfo include for details
*/
KartModel* KartProperties::getKartModelCopy(KartRenderType krt) const
{
return m_kart_model->makeCopy(krt);
} // getKartModelCopy
// ----------------------------------------------------------------------------
/** Sets the name of a mesh to be used for this kart.
* \param hat_name Name of the mesh.
*/
void KartProperties::setHatMeshName(const std::string &hat_name)
{
m_kart_model->setHatMeshName(hat_name);
} // setHatMeshName
//-----------------------------------------------------------------------------
void KartProperties::combineCharacteristics()
{
@ -372,11 +391,6 @@ void KartProperties::getAllData(const XMLNode * root)
m_ai_properties[RaceManager::DIFFICULTY_BEST]->load(best);
}
if(const XMLNode *speed_weighted_objects_node = root->getNode("speed-weighted-objects"))
{
m_speed_weighted_object_properties.loadFromXMLNode(speed_weighted_objects_node);
}
if(const XMLNode *friction_node = root->getNode("friction"))
friction_node->get("slip", &m_friction_slip);
@ -480,8 +494,6 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_restitution, "collision restitution" );
CHECK_NEG(m_physical_wheel_position, "collision physical-wheel-position");
m_speed_weighted_object_properties.checkAllSet();
for(unsigned int i=0; i<RaceManager::DIFFICULTY_COUNT; i++)
m_ai_properties[i]->checkAllSet(filename);
} // checkAllSet
@ -1173,6 +1185,5 @@ bool KartProperties::getSkidEnabled() const
return m_cached_characteristic->getSkidEnabled();
} // getSkidEnabled
/* <characteristics-end kpgetter> */

View File

@ -32,7 +32,6 @@ namespace irr
using namespace irr;
#include "audio/sfx_manager.hpp"
#include "karts/kart_model.hpp"
#include "io/xml_node.hpp"
#include "race/race_manager.hpp"
#include "utils/interpolation_array.hpp"
@ -42,6 +41,7 @@ class AbstractCharacteristic;
class AIProperties;
class CachedCharacteristic;
class CombinedCharacteristic;
class KartModel;
class Material;
class XMLNode;
@ -176,9 +176,6 @@ private:
// -------------------
float m_friction_slip;
/** Parameters for the speed-weighted objects */
SpeedWeightedObject::Properties m_speed_weighted_object_properties;
/** Shift of center of gravity. */
Vec3 m_gravity_center_shift;
@ -244,26 +241,13 @@ public:
video::ITexture *getMinimapIcon () const {return m_minimap_icon; }
// ------------------------------------------------------------------------
/** Returns a pointer to the KartModel object.
* \param krt The KartRenderType, like default, red, blue or transparent.
* see the RenderInfo include for details
*/
KartModel* getKartModelCopy(KartRenderType krt) const
{return m_kart_model->makeCopy(krt); }
KartModel* getKartModelCopy(KartRenderType krt) const;
// ------------------------------------------------------------------------
/** Returns a pointer to the main KartModel object. This copy
* should not be modified, not attachModel be called on it. */
const KartModel& getMasterKartModel() const {return *m_kart_model; }
// ------------------------------------------------------------------------
/** Sets the name of a mesh to be used for this kart.
* \param hat_name Name of the mesh.
*/
void setHatMeshName(const std::string &hat_name)
{
m_kart_model->setHatMeshName(hat_name);
} // setHatMeshName
void setHatMeshName(const std::string &hat_name);
// ------------------------------------------------------------------------
/** Returns the name of this kart.
\note Pass it through fridibi as needed, this is the LTR name
@ -324,13 +308,6 @@ public:
/** Returns friction slip. */
float getFrictionSlip () const {return m_friction_slip; }
// ------------------------------------------------------------------------
/** Returns parameters for the speed-weighted objects */
const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const
{
return m_speed_weighted_object_properties;
}
// ------------------------------------------------------------------------
/** Returns the wheel base (distance front to rear axis). */
float getWheelBase () const {return m_wheel_base; }

View File

@ -202,6 +202,7 @@
#include "items/projectile_manager.hpp"
#include "karts/combined_characteristic.hpp"
#include "karts/controller/ai_base_lap_controller.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/cutscene_world.hpp"

View File

@ -24,6 +24,7 @@
#include "graphics/material.hpp"
#include "karts/kart.hpp"
#include "karts/kart_model.hpp"
#include "physics/triangle_mesh.hpp"
#include "tracks/terrain_info.hpp"
#include "tracks/track.hpp"

View File

@ -29,6 +29,7 @@
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/cutscene_world.hpp"

View File

@ -30,6 +30,7 @@
#include "guiengine/widgets/label_widget.hpp"
#include "io/file_manager.hpp"
#include "items/item_manager.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/cutscene_world.hpp"

View File

@ -20,13 +20,13 @@
#define HEADER_GRAND_PRIX_LOSE_HPP
#include "guiengine/screen.hpp"
#include "karts/kart_model.hpp"
#include "states_screens/grand_prix_cutscene.hpp"
#include <vector>
#include <string>
namespace irr { namespace scene { class ISceneNode; class ICameraSceneNode; class ILightSceneNode; class IMeshSceneNode; } }
class KartModel;
class KartProperties;
class TrackObject;

View File

@ -32,6 +32,7 @@
#include "input/device_manager.hpp"
#include "items/item_manager.hpp"
#include "karts/abstract_characteristic.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/overworld.hpp"
@ -833,8 +834,10 @@ void KartSelectionScreen::updateKartWidgetModel(int widget_id,
ItemManager::getItemModel(Item::ITEM_BONUS_BOX);
w3->clearModels();
w3->addModel( model, Vec3(0.0f, -12.0f, 0.0f),
Vec3(35.0f, 35.0f, 35.0f) );
core::matrix4 model_location;
model_location.setTranslation(core::vector3df(0.0f, -12.0f, 0.0f));
model_location.setScale(core::vector3df(35.0f, 35.0f, 35.0f));
w3->addModel(model, model_location);
w3->update(0);
m_kart_widgets[widget_id].m_kart_name
->setText( _("Random Kart"), false );
@ -843,9 +846,11 @@ void KartSelectionScreen::updateKartWidgetModel(int widget_id,
else if (StringUtils::startsWith(selection, ID_LOCKED) && !m_multiplayer)
{
w3->clearModels();
core::matrix4 model_location;
model_location.setScale(core::vector3df(15.0f, 15.0f, 15.0f));
w3->addModel(irr_driver->getAnimatedMesh(
file_manager->getAsset(FileManager::MODEL, "chest.spm") )->getMesh(20),
Vec3(0,0,0), Vec3(15.0f, 15.0f, 15.0f) );
file_manager->getAsset(FileManager::MODEL, "chest.spm"))
->getMesh(20), model_location);
w3->update(0);
if (m_multiplayer)
@ -874,6 +879,8 @@ void KartSelectionScreen::updateKartWidgetModel(int widget_id,
scale = 30.0f;
}
core::matrix4 model_location;
model_location.setScale(core::vector3df(scale, scale, scale));
w3->clearModels();
const bool has_win_anime =
UserConfigParams::m_show_steering_animations != 0 &&
@ -882,8 +889,7 @@ void KartSelectionScreen::updateKartWidgetModel(int widget_id,
kart_model.getFrame(KartModel::AF_WIN_END) > -1) ||
(kart_model.getFrame(KartModel::AF_SELECTION_START) > -1 &&
kart_model.getFrame(KartModel::AF_SELECTION_END) > -1));
w3->addModel( kart_model.getModel(), Vec3(0,0,0),
Vec3(scale, scale, scale),
w3->addModel( kart_model.getModel(), model_location,
has_win_anime ?
kart_model.getFrame(KartModel::AF_SELECTION_START) > -1 ?
kart_model.getFrame(KartModel::AF_SELECTION_START) :
@ -898,18 +904,29 @@ void KartSelectionScreen::updateKartWidgetModel(int widget_id,
kart_model.getBaseFrame(),
false/*all_parts_colorized*/,
kart_model.getAnimationSpeed());
w3->addModel( kart_model.getWheelModel(0),
kart_model.getWheelGraphicsPosition(0) );
w3->addModel( kart_model.getWheelModel(1),
kart_model.getWheelGraphicsPosition(1) );
w3->addModel( kart_model.getWheelModel(2),
kart_model.getWheelGraphicsPosition(2) );
w3->addModel( kart_model.getWheelModel(3),
kart_model.getWheelGraphicsPosition(3) );
for (size_t i = 0; i < kart_model.getSpeedWeightedObjectsCount(); i++)
model_location.setScale(core::vector3df(1.0f, 1.0f, 1.0f));
for (unsigned i = 0; i < 4; i++)
{
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject((int)i);
w3->addModel(obj.m_model, obj.m_position);
model_location.setTranslation(kart_model
.getWheelGraphicsPosition(i).toIrrVector());
w3->addModel(kart_model.getWheelModel(i), model_location);
}
for (unsigned i = 0;
i < kart_model.getSpeedWeightedObjectsCount(); i++)
{
const SpeedWeightedObject& obj =
kart_model.getSpeedWeightedObject(i);
core::matrix4 swol = obj.m_location;
if (!obj.m_bone_name.empty())
{
core::matrix4 inv =
kart_model.getInverseBoneMatrix(obj.m_bone_name);
swol = inv * obj.m_location;
}
w3->addModel(obj.m_model, swol, -1, -1, false, 0.0f,
obj.m_bone_name);
}
//w3->update(0);

View File

@ -161,46 +161,36 @@ void SoccerSetupScreen::beforeAddingWidget()
(info.team == SOCCER_TEAM_BLUE ? KRT_BLUE : KRT_RED);
}
core::matrix4 model_location;
model_location.setScale(core::vector3df(35.0f, 35.0f, 35.0f));
// Add the kart model (including wheels and speed weight objects)
kart_view->addModel(kart_model.getModel(), Vec3(0, 0, 0),
Vec3(35.0f, 35.0f, 35.0f), kart_model.getBaseFrame(),
kart_model.getBaseFrame());
kart_view->addModel(kart_model.getModel(), model_location,
kart_model.getBaseFrame(), kart_model.getBaseFrame());
kart_view->addModel( kart_model.getWheelModel(0),
kart_model.getWheelGraphicsPosition(0),
Vec3(1, 1, 1), /*scale*/
-1, /*start_loop_frame*/
-1, /*end_loop_frame*/
true /*all_parts_colorized*/);
kart_view->addModel( kart_model.getWheelModel(1),
kart_model.getWheelGraphicsPosition(1),
Vec3(1, 1, 1), /*scale*/
-1, /*start_loop_frame*/
-1, /*end_loop_frame*/
true /*all_parts_colorized*/);
kart_view->addModel( kart_model.getWheelModel(2),
kart_model.getWheelGraphicsPosition(2),
Vec3(1, 1, 1), /*scale*/
-1, /*start_loop_frame*/
-1, /*end_loop_frame*/
true /*all_parts_colorized*/);
kart_view->addModel( kart_model.getWheelModel(3),
kart_model.getWheelGraphicsPosition(3),
Vec3(1, 1, 1), /*scale*/
-1, /*start_loop_frame*/
-1, /*end_loop_frame*/
true /*all_parts_colorized*/);
for (size_t i = 0; i < kart_model.getSpeedWeightedObjectsCount(); i++)
model_location.setScale(core::vector3df(1.0f, 1.0f, 1.0f));
for (unsigned i = 0; i < 4; i++)
{
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject((int)i);
kart_view->addModel(obj.m_model, obj.m_position,
Vec3(1, 1, 1), /*scale*/
-1, /*start_loop_frame*/
-1, /*end_loop_frame*/
true /*all_parts_colorized*/);
model_location.setTranslation(kart_model
.getWheelGraphicsPosition(i).toIrrVector());
kart_view->addModel(kart_model.getWheelModel(i), model_location,
-1/*start_loop_frame*/ -1/*end_loop_frame*/,
true/*all_parts_colorized*/);
}
for (unsigned i = 0; i < kart_model.getSpeedWeightedObjectsCount();
i++)
{
const SpeedWeightedObject& obj =
kart_model.getSpeedWeightedObject(i);
core::matrix4 swol = obj.m_location;
if (!obj.m_bone_name.empty())
{
core::matrix4 inv =
kart_model.getInverseBoneMatrix(obj.m_bone_name);
swol = inv * obj.m_location;
}
kart_view->addModel(obj.m_model, swol, -1, -1, true, 0.0f,
obj.m_bone_name);
}
kart_view->setRotateContinuously( KART_CONTINUOUS_ROTATION_SPEED );