Add support for colorizing library objects using material.xml only

This commit is contained in:
Benau 2016-08-17 11:57:18 +08:00
parent d213bef9db
commit f07452842d
17 changed files with 167 additions and 60 deletions

View File

@ -143,6 +143,7 @@ Material::Material(const XMLNode *node, bool deprecated)
node->get("disable-z-write", &m_disable_z_write );
node->get("colorizable", &m_colorizable );
node->get("colorization-factor", &m_colorization_factor);
node->get("hue-settings", &m_hue_settings );
node->get("fog", &m_fog );
node->get("mask", &m_mask );

View File

@ -21,6 +21,7 @@
#define HEADER_MATERIAL_HPP
#include "utils/no_copy.hpp"
#include "utils/random_generator.hpp"
#include <assert.h>
#include <map>
@ -181,6 +182,12 @@ private:
/** Minimum resulting saturation when colorized (from 0 to 1) */
float m_colorization_factor;
/** List of hue pre-defined for colorization (from 0 to 1) */
std::vector<float> m_hue_settings;
/** Random generator for getting pre-defined hue */
RandomGenerator m_random_hue;
/** Some textures need to be pre-multiplied, some divided to give
* the intended effect. */
//enum {ADJ_NONE, ADJ_PREMUL, ADJ_DIV}
@ -291,7 +298,7 @@ public:
* is driving on it. */
bool isDriveReset () const { return m_drive_reset; }
// ------------------------------------------------------------------------
/** Returns if this material can be colorized (like red/blue in team game).
/** Returns if this material can be colorized.
*/
bool isColorizable () const { return m_colorizable; }
// ------------------------------------------------------------------------
@ -299,6 +306,17 @@ public:
*/
float getColorizationFactor () const { return m_colorization_factor; }
// ------------------------------------------------------------------------
/** Returns a random hue when colorized.
*/
float getRandomHue()
{
if (m_hue_settings.empty())
return 0.0f;
const unsigned int hue = m_random_hue.get(m_hue_settings.size());
assert(hue < m_hue_settings.size());
return m_hue_settings[hue];
}
// ------------------------------------------------------------------------
/** Returns if this material should trigger a rescue if a kart
* crashes against it. */
CollisionReaction getCollisionReaction() const { return m_collision_reaction; }

View File

@ -26,6 +26,19 @@
// ----------------------------------------------------------------------------
RenderInfo::RenderInfo(float hue, bool transparent)
{
m_hue = hue;
m_static_hue = hue;
m_transparent = transparent;
} // RenderInfo
// ----------------------------------------------------------------------------
void RenderInfo::setDynamicHue(irr::scene::IMesh* mesh)
{
unsigned int n = mesh->getMeshBufferCount();
for (unsigned int i = 0; i < n; i++)
{
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
m_dynamic_hue.push_back(m->getRandomHue());
}
} // setDynamicHue

View File

@ -21,6 +21,8 @@
#include "utils/leak_check.hpp"
#include <vector>
namespace irr
{
namespace scene { class IMesh; }
@ -41,10 +43,12 @@ public:
};
private:
float m_hue;
float m_static_hue;
bool m_transparent;
std::vector<float> m_dynamic_hue;
public:
LEAK_CHECK();
// ------------------------------------------------------------------------
@ -52,11 +56,11 @@ public:
// ------------------------------------------------------------------------
~RenderInfo() {}
// ------------------------------------------------------------------------
void setHue(float hue) { m_hue = hue; }
void setHue(float hue) { m_static_hue = hue; }
// ------------------------------------------------------------------------
void setTransparent(bool transparent) { m_transparent = transparent; }
// ------------------------------------------------------------------------
float getHue() const { return m_hue; }
float getHue() const { return m_static_hue; }
// ------------------------------------------------------------------------
bool isTransparent() const { return m_transparent; }
// ------------------------------------------------------------------------
@ -68,7 +72,20 @@ public:
setTransparent(krt == RenderInfo::KRT_TRANSPARENT ? true : false);
}
// ------------------------------------------------------------------------
void setRenderInfo(const RenderInfo* other) { *this = *other; }
/** Returns true if this render info is static. ie affect all material
* using the same hue. (like the kart colorization in soccer game)
*/
bool isStatic() const { return m_dynamic_hue.empty(); }
// ------------------------------------------------------------------------
unsigned int getNumberOfHue() const { return m_dynamic_hue.size(); }
// ------------------------------------------------------------------------
float getDynamicHue(unsigned int hue) const
{
assert(hue < m_dynamic_hue.size());
return m_dynamic_hue[hue];
}
// ------------------------------------------------------------------------
void setDynamicHue(irr::scene::IMesh* mesh);
}; // RenderInfo

View File

@ -100,22 +100,44 @@ void STKAnimatedMesh::updateNoGL()
if (!isMaterialInitialized)
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
const u32 mb_count = m->getMeshBufferCount();
for (u32 i = 0; i < mb_count; ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
bool affected = false;
if (!m_all_parts_colorized && mb && m_mesh_render_info)
RenderInfo* cur_ri = m_mesh_render_info;
if (!m_all_parts_colorized && mb && cur_ri)
{
// Test if material is affected by hue change
Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
if (m->isColorizable())
affected = true;
if (m_mesh_render_info && !m_mesh_render_info->isStatic())
{
// Convert to static render info for each mesh buffer
assert(m_mesh_render_info->getNumberOfHue() == mb_count);
const float hue = m_mesh_render_info->getDynamicHue(i);
if (hue > 0.0f)
{
cur_ri = new RenderInfo(hue);
m_static_render_info.push_back(cur_ri);
affected = true;
}
else
{
cur_ri = NULL;
}
}
else
{
// Test if material is affected by static hue change
Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
if (m->isColorizable())
affected = true;
}
}
assert(cur_ri ? cur_ri->isStatic() : true);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected || m_all_parts_colorized || (m_mesh_render_info
&& m_mesh_render_info->isTransparent()) ? m_mesh_render_info : NULL));
affected || m_all_parts_colorized || (cur_ri
&& cur_ri->isTransparent()) ? cur_ri : NULL));
}
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)

View File

@ -32,6 +32,7 @@ class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMes
protected:
bool isMaterialInitialized;
bool isGLInitialized;
PtrVector<RenderInfo> m_static_render_info;
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
void cleanGLMeshes();

View File

@ -77,22 +77,44 @@ void STKMeshSceneNode::setReloadEachFrame(bool val)
void STKMeshSceneNode::createGLMeshes(RenderInfo* render_info, bool all_parts_colorized)
{
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
const u32 mb_count = Mesh->getMeshBufferCount();
for (u32 i = 0; i < mb_count; ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
bool affected = false;
RenderInfo* cur_ri = render_info;
if (!all_parts_colorized && mb && render_info)
{
// Test if material is affected by hue change
Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
if (m->isColorizable())
affected = true;
if (render_info && !render_info->isStatic())
{
// Convert to static render info for each mesh buffer
assert(render_info->getNumberOfHue() == mb_count);
const float hue = render_info->getDynamicHue(i);
if (hue > 0.0f)
{
cur_ri = new RenderInfo(hue);
m_static_render_info.push_back(cur_ri);
affected = true;
}
else
{
cur_ri = NULL;
}
}
else
{
// Test if material is affected by static hue change
Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
if (m->isColorizable())
affected = true;
}
}
assert(cur_ri ? cur_ri->isStatic() : true);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected || all_parts_colorized || (render_info &&
render_info->isTransparent()) ? render_info : NULL));
affected || all_parts_colorized || (cur_ri &&
cur_ri->isTransparent()) ? cur_ri : NULL));
}
isMaterialInitialized = false;
isGLInitialized = false;

View File

@ -28,6 +28,7 @@ class RenderInfo;
class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
{
protected:
PtrVector<RenderInfo> m_static_render_info;
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
core::vector3df windDir;

View File

@ -23,7 +23,6 @@
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "modes/world.hpp"
#include "config/player_manager.hpp"
#include "states_screens/dialogs/tutorial_message_dialog.hpp"

View File

@ -38,8 +38,6 @@
#include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "items/item.hpp"
@ -1739,7 +1737,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
}
}
loadObjects(root, path, model_def_loader, true, NULL, NULL, NULL);
loadObjects(root, path, model_def_loader, true, NULL, NULL);
model_def_loader.cleanLibraryNodesAfterLoad();
@ -1929,7 +1927,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& model_def_loader,
bool create_lod_definitions, scene::ISceneNode* parent,
TrackObject* parent_library, RenderInfo* ri)
TrackObject* parent_library)
{
unsigned int start_position_counter = 0;
@ -1943,7 +1941,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
if (name == "track" || name == "default-start") continue;
if (name == "object" || name == "library")
{
m_track_object_manager->add(*node, parent, model_def_loader, parent_library, ri);
m_track_object_manager->add(*node, parent, model_def_loader, parent_library);
}
else if (name == "water")
{
@ -1987,7 +1985,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
{
if (UserConfigParams::m_graphical_effects)
{
m_track_object_manager->add(*node, parent, model_def_loader, parent_library, NULL);
m_track_object_manager->add(*node, parent, model_def_loader, parent_library);
}
}
else if (name == "sky-dome" || name == "sky-box" || name == "sky-color")
@ -2000,7 +1998,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
}
else if (name == "light")
{
m_track_object_manager->add(*node, parent, model_def_loader, parent_library, NULL);
m_track_object_manager->add(*node, parent, model_def_loader, parent_library);
}
else if (name == "weather")
{

View File

@ -56,7 +56,6 @@ class MusicInformation;
class ParticleEmitter;
class ParticleKind;
class PhysicalObject;
class RenderInfo;
class TrackObject;
class TrackObjectManager;
class TriangleMesh;
@ -457,8 +456,7 @@ public:
// ------------------------------------------------------------------------
void loadObjects(const XMLNode* root, const std::string& path,
ModelDefinitionLoader& lod_loader, bool create_lod_definitions,
scene::ISceneNode* parent, TrackObject* parent_library,
RenderInfo* ri);
scene::ISceneNode* parent, TrackObject* parent_library);
// ------------------------------------------------------------------------
bool isSoccer () const { return m_is_soccer; }
// ------------------------------------------------------------------------

View File

@ -20,6 +20,8 @@
#include "animations/three_d_animation.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/render_info.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
@ -43,9 +45,9 @@
*/
TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri)
TrackObject* parent_library)
{
init(xml_node, parent, model_def_loader, parent_library, ri);
init(xml_node, parent, model_def_loader, parent_library);
} // TrackObject
// ----------------------------------------------------------------------------
@ -68,6 +70,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr,
m_animator = NULL;
m_physical_object = NULL;
m_parent_library = NULL;
m_render_info = NULL;
m_interaction = interaction;
m_presentation = presentation;
m_is_driveable = false;
@ -94,11 +97,12 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr,
*/
void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri)
TrackObject* parent_library)
{
m_init_xyz = core::vector3df(0,0,0);
m_init_hpr = core::vector3df(0,0,0);
m_init_scale = core::vector3df(1,1,1);
m_render_info = NULL;
m_enabled = true;
m_initially_visible = false;
m_presentation = NULL;
@ -178,13 +182,35 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
}
else
{
// Colorization settings
std::string model_name;
xml_node.get("model", &model_name);
scene::IMesh* mesh = irr_driver->getMesh(model_name);
bool colorizable = false;
unsigned int n = mesh->getMeshBufferCount();
for (unsigned int i = 0; i < n; i++)
{
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
colorizable = colorizable || m->isColorizable();
}
// If at least one material is colorizable, add RenderInfo for it
if (colorizable)
{
m_render_info = new RenderInfo();
m_render_info->setDynamicHue(mesh);
}
scene::ISceneNode *glownode = NULL;
bool is_movable = false;
if (lod_instance)
{
m_type = "lod";
TrackObjectPresentationLOD* lod_node =
new TrackObjectPresentationLOD(xml_node, parent, model_def_loader, ri);
new TrackObjectPresentationLOD(xml_node, parent, model_def_loader, m_render_info);
m_presentation = lod_node;
LODNode* node = (LODNode*)lod_node->getNode();
@ -209,7 +235,7 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
m_presentation = new TrackObjectPresentationMesh(xml_node,
m_enabled,
parent,
ri);
m_render_info);
scene::ISceneNode* node = ((TrackObjectPresentationMesh *)m_presentation)->getNode();
if (type == "movable" && parent != NULL)
{
@ -356,6 +382,7 @@ TrackObject::~TrackObject()
delete m_presentation;
delete m_animator;
delete m_physical_object;
delete m_render_info;
} // ~TrackObject
// ----------------------------------------------------------------------------

View File

@ -31,10 +31,10 @@
#include <string>
#include "animations/three_d_animation.hpp"
class XMLNode;
class ThreeDAnimation;
class ModelDefinitionLoader;
class RenderInfo;
class ThreeDAnimation;
class XMLNode;
/**
* \ingroup tracks
@ -60,8 +60,9 @@ private:
std::string m_id;
protected:
RenderInfo* m_render_info;
protected:
/** The initial XYZ position of the object. */
core::vector3df m_init_xyz;
@ -99,14 +100,13 @@ protected:
void init(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri);
TrackObject* parent_library);
public:
TrackObject(const XMLNode &xml_node,
scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library,
RenderInfo* ri);
TrackObject* parent_library);
TrackObject(const core::vector3df& xyz,
const core::vector3df& hpr,

View File

@ -22,7 +22,6 @@
#include "animations/three_d_animation.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/render_info.hpp"
#include "io/xml_node.hpp"
#include "physics/physical_object.hpp"
#include "tracks/track_object.hpp"
@ -46,11 +45,11 @@ TrackObjectManager::~TrackObjectManager()
*/
void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri)
TrackObject* parent_library)
{
try
{
TrackObject *obj = new TrackObject(xml_node, parent, model_def_loader, parent_library, ri);
TrackObject *obj = new TrackObject(xml_node, parent, model_def_loader, parent_library);
m_all_objects.push_back(obj);
if(obj->isDriveable())
m_driveable_objects.push_back(obj);

View File

@ -23,11 +23,10 @@
#include "tracks/track_object.hpp"
#include "utils/ptr_vector.hpp"
class LODNode;
class RenderInfo;
class Track;
class Vec3;
class XMLNode;
class LODNode;
#include <map>
#include <vector>
@ -59,7 +58,7 @@ public:
void init();
void add(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri);
TrackObject* parent_library);
void update(float dt);
void handleExplosion(const Vec3 &pos, const PhysicalObject *mp,
bool secondary_hits=true);

View File

@ -177,13 +177,8 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
ModelDefinitionLoader& model_def_loader)
: TrackObjectPresentationSceneNode(xml_node)
{
m_render_info = NULL;
std::string name;
xml_node.get("name", &name);
float custom_hue = 0.0f;
xml_node.get("hue", &custom_hue);
if (custom_hue > 0.0f)
m_render_info = new RenderInfo(custom_hue, false);
m_node = irr_driver->getSceneManager()->addEmptySceneNode();
#ifdef DEBUG
@ -273,7 +268,7 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
assert(libroot != NULL);
World::getWorld()->getTrack()->loadObjects(libroot, lib_path, model_def_loader,
create_lod_definitions, m_node, parent, m_render_info);
create_lod_definitions, m_node, parent);
m_parent = parent;
} // TrackObjectPresentationLibraryNode
@ -281,8 +276,6 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
TrackObjectPresentationLibraryNode::~TrackObjectPresentationLibraryNode()
{
irr_driver->removeNode(m_node);
delete m_render_info;
m_render_info = NULL;
} // TrackObjectPresentationLibraryNode
// ----------------------------------------------------------------------------
void TrackObjectPresentationLibraryNode::move(const core::vector3df& xyz, const core::vector3df& hpr,

View File

@ -185,7 +185,6 @@ public:
class TrackObjectPresentationLibraryNode : public TrackObjectPresentationSceneNode
{
TrackObject* m_parent;
RenderInfo* m_render_info;
public:
TrackObjectPresentationLibraryNode(TrackObject* parent,
const XMLNode& xml_node,