Skip to content

Commit

Permalink
Add support for colorizing library objects using material.xml only
Browse files Browse the repository at this point in the history
  • Loading branch information
Benau committed Aug 17, 2016
1 parent d213bef commit f074528
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 60 deletions.
1 change: 1 addition & 0 deletions src/graphics/material.cpp
Expand Up @@ -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 );
Expand Down
20 changes: 19 additions & 1 deletion src/graphics/material.hpp
Expand Up @@ -21,6 +21,7 @@
#define HEADER_MATERIAL_HPP

#include "utils/no_copy.hpp"
#include "utils/random_generator.hpp"

#include <assert.h>
#include <map>
Expand Down Expand Up @@ -181,6 +182,12 @@ class Material : public NoCopy
/** 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}
Expand Down Expand Up @@ -291,14 +298,25 @@ class Material : public NoCopy
* 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; }
// ------------------------------------------------------------------------
/** Returns the minimum resulting saturation when colorized.
*/
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; }
Expand Down
15 changes: 14 additions & 1 deletion src/graphics/render_info.cpp
Expand Up @@ -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
25 changes: 21 additions & 4 deletions src/graphics/render_info.hpp
Expand Up @@ -21,6 +21,8 @@

#include "utils/leak_check.hpp"

#include <vector>

namespace irr
{
namespace scene { class IMesh; }
Expand All @@ -41,22 +43,24 @@ class RenderInfo
};

private:
float m_hue;
float m_static_hue;

bool m_transparent;

std::vector<float> m_dynamic_hue;

public:
LEAK_CHECK();
// ------------------------------------------------------------------------
RenderInfo(float hue = 0.0f, bool transparent = false);
// ------------------------------------------------------------------------
~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; }
// ------------------------------------------------------------------------
Expand All @@ -68,7 +72,20 @@ class RenderInfo
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

Expand Down
40 changes: 31 additions & 9 deletions src/graphics/stk_animated_mesh.cpp
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/graphics/stk_animated_mesh.hpp
Expand Up @@ -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();
Expand Down
38 changes: 30 additions & 8 deletions src/graphics/stk_mesh_scene_node.cpp
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/graphics/stk_mesh_scene_node.hpp
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion src/scriptengine/script_challenges.cpp
Expand Up @@ -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"
Expand Down
12 changes: 5 additions & 7 deletions src/tracks/track.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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;

Expand All @@ -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")
{
Expand Down Expand Up @@ -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")
Expand All @@ -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")
{
Expand Down
4 changes: 1 addition & 3 deletions src/tracks/track.hpp
Expand Up @@ -56,7 +56,6 @@ class MusicInformation;
class ParticleEmitter;
class ParticleKind;
class PhysicalObject;
class RenderInfo;
class TrackObject;
class TrackObjectManager;
class TriangleMesh;
Expand Down Expand Up @@ -457,8 +456,7 @@ class Track
// ------------------------------------------------------------------------
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; }
// ------------------------------------------------------------------------
Expand Down

0 comments on commit f074528

Please sign in to comment.