Allow setting color without copying the mesh

This commit is contained in:
Benau 2016-06-28 14:55:48 +08:00
parent 892bc490f7
commit 22e5c0909c
25 changed files with 186 additions and 200 deletions

View File

@ -8,7 +8,7 @@ flat in sampler2D handle;
flat in sampler2D secondhandle;
#endif
uniform float color_change;
uniform vec2 color_change;
in vec2 uv;
in vec4 color;
@ -33,11 +33,11 @@ void main(void)
float emitmap = texture(SpecMap, uv).b;
#endif
if (color_change > 0.0)
if (color_change.x > 0.0)
{
vec3 old_hsv = rgbToHsv(col.rgb);
old_hsv.y = max(old_hsv.y, 0.93);
vec3 new_color = hsvToRgb(vec3(color_change, old_hsv.y, old_hsv.z));
old_hsv.y = max(old_hsv.y, color_change.y);
vec3 new_color = hsvToRgb(vec3(color_change.x, old_hsv.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, col.a);
}

View File

@ -6,7 +6,7 @@ uniform sampler2D Albedo;
uniform sampler2D SpecMap;
#endif
uniform float color_change;
uniform vec2 color_change;
in vec2 uv;
in vec4 color;
@ -27,11 +27,11 @@ void main(void)
vec4 col = texture(Albedo, uv);
#endif
if (color_change > 0.0)
if (color_change.x > 0.0)
{
vec3 old_hsv = rgbToHsv(col.rgb);
old_hsv.y = max(old_hsv.y, 0.93);
vec3 new_color = hsvToRgb(vec3(color_change, old_hsv.y, old_hsv.z));
old_hsv.y = max(old_hsv.y, color_change.y);
vec3 new_color = hsvToRgb(vec3(color_change.x, old_hsv.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, col.a);
}

View File

@ -10,15 +10,6 @@ namespace irr
namespace video
{
//! Flag for mesh buffer (mainly karts in STK) to use specific render type
enum E_RENDER_TYPE
{
ERT_DEFAULT = 0,
ERT_TRANSPARENT,
ERT_RED,
ERT_BLUE
};
//! Abstracted and easy to use fixed function/programmable pipeline material modes.
enum E_MATERIAL_TYPE
{

View File

@ -5,18 +5,15 @@
#ifndef __I_MESH_H_INCLUDED__
#define __I_MESH_H_INCLUDED__
#include "IMeshBuffer.h"
#include "IReferenceCounted.h"
#include "SMaterial.h"
#include "EHardwareBufferFlags.h"
#include <algorithm>
#include <vector>
namespace irr
{
namespace scene
{
class IMeshBuffer;
//! Class which holds the geometry of an object.
/** An IMesh is nothing more than a collection of some mesh buffers
@ -26,9 +23,6 @@ namespace scene
class IMesh : public virtual IReferenceCounted
{
public:
IMesh() : m_custom_render_type(false) {}
virtual ~IMesh() {}
//! Get the amount of mesh buffers.
/** \return Amount of mesh buffers (IMeshBuffer) in this mesh. */
@ -72,30 +66,6 @@ namespace scene
indices have changed. Otherwise, changes won't be updated
on the GPU in the next render cycle. */
virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) = 0;
//! True if this mesh has specific render type (mainly karts in STK)
bool hasCustomRenderType() const { return m_custom_render_type; }
//! Set whether this mesh is having a specific render type (mainly karts in STK)
void setCustomRenderType(bool has_custom) { m_custom_render_type = has_custom; }
//! Set the mesh to use a specific render type (mainly karts in STK)
/** \param t New render type for the mesh.
\param affected_buffers Mesh buffer numbers which are effected by new render type,
if not given all mesh buffers are affected. */
void setMeshRenderType(video::E_RENDER_TYPE t, const std::vector<int>& affected_buffers = std::vector<int>())
{
if (t == video::ERT_DEFAULT) return;
setCustomRenderType(true);
for (int i = 0; i < int(getMeshBufferCount()); i++)
{
if (!affected_buffers.empty() && std::find(affected_buffers.begin(), affected_buffers.end(), i) == affected_buffers.end())
continue;
getMeshBuffer(i)->setRenderType(t);
}
}
private:
bool m_custom_render_type;
};
} // end namespace scene

View File

@ -39,9 +39,6 @@ namespace scene
class IMeshBuffer : public virtual IReferenceCounted
{
public:
IMeshBuffer() : m_rt(video::ERT_DEFAULT) {}
virtual ~IMeshBuffer() {}
//! Get the material of this meshbuffer
/** \return Material of this buffer. */
@ -150,15 +147,6 @@ namespace scene
//! Get the currently used ID for identification of changes.
/** This shouldn't be used for anything outside the VideoDriver. */
virtual u32 getChangedID_Index() const = 0;
//! Set the mesh buffer to use a specific render type (mainly karts in STK)
/** \param t New render type for the mesh. */
void setRenderType(video::E_RENDER_TYPE t) const { m_rt = t; }
//! Get the specific render type of the mesh buffer (mainly karts in STK)
video::E_RENDER_TYPE getRenderType() const { return m_rt; }
private:
mutable video::E_RENDER_TYPE m_rt;
};
} // end namespace scene

View File

@ -25,7 +25,6 @@
#include "graphics/2dutils.hpp"
#include "graphics/graphics_restrictions.hpp"
#include "graphics/light.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/per_camera_node.hpp"
#include "graphics/post_processing.hpp"
@ -1013,9 +1012,7 @@ scene::IMesh *IrrDriver::getMesh(const std::string &filename)
* \return Newly created skinned mesh. You should call drop() when you don't
* need it anymore.
*/
scene::IAnimatedMesh *IrrDriver::copyAnimatedMesh(scene::IAnimatedMesh *orig,
video::E_RENDER_TYPE rt,
const std::vector<int>& affected_buffers)
scene::IAnimatedMesh *IrrDriver::copyAnimatedMesh(scene::IAnimatedMesh *orig)
{
using namespace scene;
CSkinnedMesh *mesh = dynamic_cast<CSkinnedMesh*>(orig);
@ -1026,7 +1023,6 @@ scene::IAnimatedMesh *IrrDriver::copyAnimatedMesh(scene::IAnimatedMesh *orig,
}
scene::IAnimatedMesh* out = mesh->clone();
out->setMeshRenderType(rt, affected_buffers);
return out;
} // copyAnimatedMesh
@ -1172,7 +1168,8 @@ scene::IParticleSystemSceneNode *IrrDriver::addParticleNode(bool default_emitter
*/
scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
const std::string& debug_name,
scene::ISceneNode *parent)
scene::ISceneNode *parent,
const CustomRenderInfo& cri)
{
if (!CVS->isGLSL())
return m_scene_manager->addMeshSceneNode(mesh, parent);
@ -1182,7 +1179,11 @@ scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
scene::IMeshSceneNode* node = new STKMeshSceneNode(mesh, parent,
m_scene_manager, -1,
debug_name);
debug_name,
core::vector3df(0, 0, 0),
core::vector3df(0, 0, 0),
core::vector3df(1.0f, 1.0f, 1.0f),
true, cri);
node->drop();
return node;
@ -1364,7 +1365,8 @@ void IrrDriver::removeTexture(video::ITexture *t)
* \param mesh The animated mesh to add.
*/
scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *mesh,
const std::string& debug_name, scene::ISceneNode* parent)
const std::string& debug_name, scene::ISceneNode* parent,
const CustomRenderInfo& cri)
{
if (!CVS->isGLSL())
{
@ -1379,7 +1381,7 @@ scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *
parent = m_scene_manager->getRootSceneNode();
scene::IAnimatedMeshSceneNode* node =
new STKAnimatedMesh(mesh, parent, m_scene_manager, -1, debug_name,
core::vector3df(0, 0, 0), core::vector3df(0, 0, 0), core::vector3df(1, 1, 1));
core::vector3df(0, 0, 0), core::vector3df(0, 0, 0), core::vector3df(1, 1, 1), cri);
node->drop();
return node;
} // addAnimatedMesh

View File

@ -37,6 +37,8 @@
#include "IrrlichtDevice.h"
#include "ISkinnedMesh.h"
#include "graphics/gl_headers.hpp"
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/skybox.hpp"
#include "graphics/sphericalHarmonics.hpp"
#include "graphics/wind.hpp"
@ -177,6 +179,54 @@ enum TypeRTT
RTT_COUNT
};
struct CustomRenderInfo
{
float m_custom_hue;
float m_custom_min_saturation;
bool m_transparent;
std::vector<int> m_affected_parts;
std::vector<int> getColorizableParts(scene::IMesh* m)
{
std::vector<int> colorizable_parts;
for (int i = 0; i < int(m->getMeshBufferCount()); ++i)
{
scene::IMeshBuffer* mb = m->getMeshBuffer(i);
Material* material = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
if (material->isColorizable())
colorizable_parts.push_back(i);
}
return colorizable_parts;
}
CustomRenderInfo()
{
m_custom_hue = 0.0f;
m_custom_min_saturation = 0.0f;
m_transparent = false;
}
CustomRenderInfo(float custom_hue, float custom_min_saturation,
bool transparent, scene::IMesh* m = NULL)
{
m_custom_hue = custom_hue;
m_custom_min_saturation = custom_min_saturation;
m_transparent = transparent;
if (m)
m_affected_parts = getColorizableParts(m);
}
CustomRenderInfo(const CustomRenderInfo& cri)
{
m_custom_hue = cri.m_custom_hue;
m_custom_min_saturation = cri.m_custom_min_saturation;
m_transparent = cri.m_transparent;
}
};
/**
* \brief class that creates the irrLicht device and offers higher-level
* ways to manage the 3D scene
@ -353,9 +403,7 @@ public:
void setAllMaterialFlags(scene::IMesh *mesh) const;
scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
scene::IMesh *getMesh(const std::string &name);
scene::IAnimatedMesh *copyAnimatedMesh(scene::IAnimatedMesh *orig,
video::E_RENDER_TYPE rt,
const std::vector<int>& affected_buffers = std::vector<int>());
scene::IAnimatedMesh *copyAnimatedMesh(scene::IAnimatedMesh *orig);
video::ITexture *applyMask(video::ITexture* texture,
const std::string& mask_path);
void displayFPS();
@ -388,7 +436,8 @@ public:
const video::SColor &color=video::SColor(128, 255, 255, 255));
scene::IMeshSceneNode*addMesh(scene::IMesh *mesh,
const std::string& debug_name,
scene::ISceneNode *parent=NULL);
scene::ISceneNode *parent=NULL,
const CustomRenderInfo& cri = CustomRenderInfo());
PerCameraNode *addPerCameraNode(scene::ISceneNode* node,
scene::ICameraSceneNode* cam,
scene::ISceneNode *parent = NULL);
@ -408,7 +457,10 @@ public:
void removeMeshFromCache(scene::IMesh *mesh);
void removeTexture(video::ITexture *t);
scene::IAnimatedMeshSceneNode
*addAnimatedMesh(scene::IAnimatedMesh *mesh, const std::string& debug_name, scene::ISceneNode* parent = NULL);
*addAnimatedMesh(scene::IAnimatedMesh *mesh,
const std::string& debug_name,
scene::ISceneNode* parent = NULL,
const CustomRenderInfo& cri = CustomRenderInfo());
scene::ICameraSceneNode
*addCameraSceneNode();
Camera *addCamera(unsigned int index, AbstractKart *kart);

View File

@ -153,11 +153,11 @@ public:
4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // InstancedObjectPass2Shader
virtual bool changeHue(float hue = 0.0f) const OVERRIDE
virtual bool changeableColor(float hue = 0.0f, float min_sat = 0.0f) const OVERRIDE
{
glUniform1f(m_color_change_location, hue);
glUniform2f(m_color_change_location, hue, min_sat);
return true;
} // changeHue
} // changeableColor
}; // InstancedObjectPass2Shader
// ============================================================================
@ -998,18 +998,11 @@ void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
GLenum itype = mesh->IndexType;
size_t count = mesh->IndexCount;
const video::E_RENDER_TYPE rt = mesh->mb->getRenderType();
const bool need_change_hue = (rt != video::ERT_DEFAULT);
const bool need_change_hue = (mesh->m_custom_hue > 0.0f);
if (need_change_hue)
{
if (rt == video::ERT_RED)
{
Shader->changeHue(1.0f);
}
else if (rt == video::ERT_BLUE)
{
Shader->changeHue(0.66f);
}
Shader->changeableColor(mesh->m_custom_hue,
mesh->m_custom_min_saturation);
}
Shader->setUniforms(Args...);
@ -1020,7 +1013,7 @@ void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
if (need_change_hue)
{
// Reset after changing
Shader->changeHue();
Shader->changeableColor();
}
} // draw
@ -1305,18 +1298,11 @@ void renderInstancedMeshes2ndPass(const std::vector<GLuint> &Prefilled_tex, Args
ExpandTex(*mesh, T::SecondPassTextures, Prefilled_tex[0],
Prefilled_tex[1], Prefilled_tex[2]);
const video::E_RENDER_TYPE rt = mesh->mb->getRenderType();
const bool need_change_hue = (rt != video::ERT_DEFAULT);
const bool need_change_hue = (mesh->m_custom_hue > 0.0f);
if (need_change_hue)
{
if (rt == video::ERT_RED)
{
T::InstancedSecondPassShader::getInstance()->changeHue(1.0f);
}
else if (rt == video::ERT_BLUE)
{
T::InstancedSecondPassShader::getInstance()->changeHue(0.66f);
}
T::InstancedSecondPassShader::getInstance()->changeableColor
(mesh->m_custom_hue, mesh->m_custom_min_saturation);
}
T::InstancedSecondPassShader::getInstance()->setUniforms(args...);
@ -1327,7 +1313,7 @@ void renderInstancedMeshes2ndPass(const std::vector<GLuint> &Prefilled_tex, Args
if (need_change_hue)
{
// Reset after changing
T::InstancedSecondPassShader::getInstance()->changeHue();
T::InstancedSecondPassShader::getInstance()->changeableColor();
}
}
} // renderInstancedMeshes2ndPass

View File

@ -150,11 +150,11 @@ public:
GLint m_color_change_location;
public:
ObjectPass2Shader();
virtual bool changeHue(float hue = 0.0f) const OVERRIDE
virtual bool changeableColor(float hue = 0.0f, float min_sat = 0.0f) const OVERRIDE
{
glUniform1f(m_color_change_location, hue);
glUniform2f(m_color_change_location, hue, min_sat);
return true;
} // changeHue
} // changeableColor
}; // ObjectPass2Shader
// ========================================================================

View File

@ -31,6 +31,7 @@
#include <IMaterialRenderer.h>
#include <ISceneManager.h>
#include <ISkinnedMesh.h>
#include <algorithm>
using namespace irr;
@ -38,11 +39,12 @@ STKAnimatedMesh::STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::IS
irr::scene::ISceneManager* mgr, s32 id, const std::string& debug_name,
const core::vector3df& position,
const core::vector3df& rotation,
const core::vector3df& scale) :
const core::vector3df& scale, const CustomRenderInfo& cri) :
CAnimatedMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
isGLInitialized = false;
isMaterialInitialized = false;
m_cri = cri;
#ifdef DEBUG
m_debug_name = debug_name;
#endif
@ -100,7 +102,13 @@ void STKAnimatedMesh::updateNoGL()
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name));
const bool affected = m_cri.m_affected_parts.empty() ||
std::find(m_cri.m_affected_parts.begin(),
m_cri.m_affected_parts.end(), i) != m_cri.m_affected_parts.end();
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected ? m_cri : CustomRenderInfo()/*default info if not affected*/));
}
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
@ -126,15 +134,11 @@ void STKAnimatedMesh::updateNoGL()
TransparentMaterial TranspMat = getTransparentMaterialFromType(type, MaterialTypeParam, material);
TransparentMesh[TranspMat].push_back(&mesh);
}
else if (mb->getRenderType() == video::ERT_TRANSPARENT)
else if (mesh.m_transparent)
{
TransparentMesh[TM_ADDITIVE].push_back(&mesh);
}
else if (mb->getRenderType() == video::ERT_RED)
{
MeshSolidMaterial[Material::SHADERTYPE_SOLID].push_back(&mesh);
}
else if (mb->getRenderType() == video::ERT_BLUE)
else if (mesh.m_custom_hue > 0.0f)
{
MeshSolidMaterial[Material::SHADERTYPE_SOLID].push_back(&mesh);
}

View File

@ -40,12 +40,15 @@ public:
irr::scene::ISceneManager* mgr, irr::s32 id, const std::string& debug_name,
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),
const irr::core::vector3df& rotation = irr::core::vector3df(0,0,0),
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f),
const CustomRenderInfo& cri = CustomRenderInfo());
~STKAnimatedMesh();
virtual void render();
virtual void setMesh(irr::scene::IAnimatedMesh* mesh);
virtual bool glow() const { return false; }
private:
CustomRenderInfo m_cri;
};
#endif // STKANIMATEDMESH_HPP

View File

@ -163,9 +163,13 @@ GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type)
} // createVAO
// ----------------------------------------------------------------------------
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb, const std::string& debug_name)
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb, const std::string& debug_name,
const CustomRenderInfo& cri)
{
GLMesh result = {};
result.m_custom_hue = cri.m_custom_hue;
result.m_custom_min_saturation = cri.m_custom_min_saturation;
result.m_transparent = cri.m_transparent;
if (!mb)
return result;
result.mb = mb;

View File

@ -56,6 +56,9 @@ struct GLMesh
video::E_VERTEX_TYPE VAOType;
uint64_t TextureHandles[6];
scene::IMeshBuffer *mb;
float m_custom_hue;
float m_custom_min_saturation;
bool m_transparent;
#ifdef DEBUG
std::string debug_name;
#endif
@ -63,7 +66,8 @@ struct GLMesh
// ----------------------------------------------------------------------------
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb,
const std::string& debug_name);
const std::string& debug_name,
const CustomRenderInfo& cri);
void fillLocalBuffer(GLMesh &, scene::IMeshBuffer* mb);
video::E_VERTEX_TYPE getVTXTYPEFromStride(size_t stride);
GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type);

View File

@ -33,7 +33,7 @@
#include <ISceneManager.h>
#include <IMaterialRenderer.h>
#include <algorithm>
// ============================================================================
class ColorizeShader : public Shader<ColorizeShader, core::matrix4,
@ -54,7 +54,7 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
irr::s32 id, const std::string& debug_name,
const irr::core::vector3df& position,
const irr::core::vector3df& rotation,
const irr::core::vector3df& scale, bool createGLMeshes) :
const irr::core::vector3df& scale, bool createGLMeshes, const CustomRenderInfo& cri) :
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
isDisplacement = false;
@ -65,7 +65,7 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
m_debug_name = debug_name;
if (createGLMeshes)
this->createGLMeshes();
this->createGLMeshes(cri);
}
void STKMeshSceneNode::setReloadEachFrame(bool val)
@ -75,12 +75,18 @@ void STKMeshSceneNode::setReloadEachFrame(bool val)
immediate_draw = true;
}
void STKMeshSceneNode::createGLMeshes()
void STKMeshSceneNode::createGLMeshes(const CustomRenderInfo& cri)
{
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name));
const bool affected = cri.m_affected_parts.empty() ||
std::find(cri.m_affected_parts.begin(),
cri.m_affected_parts.end(), i) != cri.m_affected_parts.end();
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected ? cri : CustomRenderInfo()/*default info if not affected*/));
}
isMaterialInitialized = false;
isGLInitialized = false;
@ -173,7 +179,7 @@ void STKMeshSceneNode::updateNoGL()
GLMesh &mesh = GLmeshes[i];
Material* material = material_manager->getMaterialFor(mb->getMaterial().getTexture(0), mb);
if (mb->getRenderType() == video::ERT_TRANSPARENT)
if (mesh.m_transparent)
{
if (!immediate_draw)
TransparentMesh[TM_ADDITIVE].push_back(&mesh);
@ -188,12 +194,7 @@ void STKMeshSceneNode::updateNoGL()
else
additive = (TranspMat == TM_ADDITIVE);
}
else if (mb->getRenderType() == video::ERT_RED)
{
if (!immediate_draw)
MeshSolidMaterial[Material::SHADERTYPE_SOLID].push_back(&mesh);
}
else if (mb->getRenderType() == video::ERT_BLUE)
else if (mesh.m_custom_hue > 0.0f)
{
if (!immediate_draw)
MeshSolidMaterial[Material::SHADERTYPE_SOLID].push_back(&mesh);

View File

@ -33,7 +33,7 @@ protected:
// Misc passes shaders (glow, displace...)
void drawGlow(const GLMesh &mesh);
void createGLMeshes();
void createGLMeshes(const CustomRenderInfo& cri = CustomRenderInfo());
void cleanGLMeshes();
void setFirstTimeMaterial();
void updatevbo();
@ -54,7 +54,8 @@ public:
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f),
bool createGLMeshes = true);
bool createGLMeshes = true,
const CustomRenderInfo& cri = CustomRenderInfo());
virtual void render();
virtual void setMesh(irr::scene::IMesh* mesh);
virtual void OnRegisterSceneNode();

View File

@ -242,12 +242,12 @@ public:
glDeleteSamplers(1, &m_sampler_ids[i]);
} // ~TextureShader
/** Override this class and return true if a shader can set different hue.
/** Override this class and return true if a shader has changeable color.
*/
virtual bool changeHue(float hue = 0.0f) const
virtual bool changeableColor(float hue = 0.0f, float min_sat = 0.0f) const
{
return false;
} // changeHue
} // changeableColor
}; // class TextureShader

View File

@ -21,7 +21,6 @@
#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"
@ -36,7 +35,7 @@ AbstractKart::AbstractKart(const std::string& ident,
int world_kart_id, int position,
const btTransform& init_transform,
PerPlayerDifficulty difficulty,
video::E_RENDER_TYPE rt)
KartModel::KartRenderType krt)
: Moveable()
{
m_world_kart_id = world_kart_id;
@ -60,7 +59,7 @@ AbstractKart::AbstractKart(const std::string& ident,
// released when the kart is deleted, but since the original
// kart_model is stored in the kart_properties all the time,
// there is no risk of a mesh being deleted to early.
m_kart_model = m_kart_properties->getKartModelCopy(rt);
m_kart_model = m_kart_properties->getKartModelCopy(krt);
m_kart_width = m_kart_model->getWidth();
m_kart_height = m_kart_model->getHeight();
m_kart_length = m_kart_model->getLength();

View File

@ -19,10 +19,10 @@
#ifndef HEADER_ABSTRACT_KART_HPP
#define HEADER_ABSTRACT_KART_HPP
#include <EMaterialTypes.h>
#include <memory>
#include "items/powerup_manager.hpp"
#include "karts/kart_model.hpp"
#include "karts/moveable.hpp"
#include "karts/controller/kart_control.hpp"
#include "race/race_manager.hpp"
@ -100,7 +100,7 @@ public:
int world_kart_id,
int position, const btTransform& init_transform,
PerPlayerDifficulty difficulty,
video::E_RENDER_TYPE rt);
KartModel::KartRenderType krt);
virtual ~AbstractKart();
virtual core::stringw getName() const;
virtual void reset();

View File

@ -19,7 +19,6 @@
#include "karts/ghost_kart.hpp"
#include "karts/controller/ghost_controller.hpp"
#include "karts/kart_gfx.hpp"
#include "karts/kart_model.hpp"
#include "modes/world.hpp"
#include "LinearMath/btQuaternion.h"
@ -28,7 +27,7 @@ GhostKart::GhostKart(const std::string& ident, unsigned int world_kart_id,
int position)
: Kart(ident, world_kart_id,
position, btTransform(btQuaternion(0, 0, 0, 1)),
PLAYER_DIFFICULTY_NORMAL, video::ERT_TRANSPARENT)
PLAYER_DIFFICULTY_NORMAL, KartModel::KRT_TRANSPARENT)
{
} // GhostKart

View File

@ -52,7 +52,6 @@
#include "items/projectile_manager.hpp"
#include "karts/controller/end_controller.hpp"
#include "karts/abstract_kart_animation.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties_manager.hpp"
#include "karts/max_speed.hpp"
#include "karts/skidding.hpp"
@ -93,9 +92,9 @@
Kart::Kart (const std::string& ident, unsigned int world_kart_id,
int position, const btTransform& init_transform,
PerPlayerDifficulty difficulty,
video::E_RENDER_TYPE rt)
KartModel::KartRenderType krt)
: AbstractKart(ident, world_kart_id, position, init_transform,
difficulty, rt)
difficulty, krt)
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
# pragma warning(1:4355)

View File

@ -232,7 +232,7 @@ public:
Kart(const std::string& ident, unsigned int world_kart_id,
int position, const btTransform& init_transform,
PerPlayerDifficulty difficulty,
video::E_RENDER_TYPE rt = video::ERT_DEFAULT);
KartModel::KartRenderType krt = KartModel::KRT_DEFAULT);
virtual ~Kart();
virtual void init(RaceManager::KartType type);
virtual void kartIsInRestNow();

View File

@ -142,6 +142,7 @@ KartModel::KartModel(bool is_master)
m_animation_speed = 25;
m_current_animation = AF_DEFAULT;
m_play_non_loop = false;
m_krt = KRT_DEFAULT;
} // KartModel
// ----------------------------------------------------------------------------
@ -228,16 +229,6 @@ KartModel::~KartModel()
{
// Master KartModels should never have a wheel attached.
assert(!m_is_master);
// Drop the cloned transparent mesh wheel if created
if (m_wheel_model[i])
{
// m_wheel_model[i] can be NULL
if (m_wheel_model[i]->hasCustomRenderType())
{
m_wheel_model[i]->drop();
}
}
m_wheel_node[i]->drop();
}
if(m_is_master && m_wheel_model[i])
@ -254,8 +245,8 @@ KartModel::~KartModel()
// Master KartModels should never have a speed weighted object attached.
assert(!m_is_master);
// Drop the cloned model if created
if (m_speed_weighted_objects[i].m_model->hasCustomRenderType())
// Drop the cloned transparent model if created
if (m_krt == KRT_TRANSPARENT)
{
m_speed_weighted_objects[i].m_model->drop();
}
@ -298,7 +289,7 @@ KartModel::~KartModel()
* It is also marked not to be a master copy, so attachModel can be called
* for this instance.
*/
KartModel* KartModel::makeCopy(video::E_RENDER_TYPE rt)
KartModel* KartModel::makeCopy(KartModel::KartRenderType krt)
{
// Make sure that we are copying from a master objects, and
// that there is indeed no animated node defined here ...
@ -311,35 +302,24 @@ KartModel* KartModel::makeCopy(video::E_RENDER_TYPE rt)
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 = irr_driver->copyAnimatedMesh
(m_mesh, rt, getColorizableParts(m_mesh));
km->m_mesh = irr_driver->copyAnimatedMesh(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_offset = m_hat_offset;
km->m_hat_name = m_hat_name;
km->m_krt = 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;
scene::IMeshManipulator *mani =
irr_driver->getVideoDriver()->getMeshManipulator();
for(unsigned int i=0; i<4; i++)
{
// Master should not have any wheel nodes.
assert(!m_wheel_node[i]);
if (m_wheel_model[i] && rt == video::ERT_TRANSPARENT)
{
// Only clone the mesh if transparence is used
scene::SMesh* clone = mani->createMeshCopy(m_wheel_model[i]);
clone->setMeshRenderType(rt);
km->m_wheel_model[i] = dynamic_cast<scene::IMesh*>(clone);
}
else
km->m_wheel_model[i] = m_wheel_model[i];
km->m_wheel_model[i] = m_wheel_model[i];
km->m_wheel_filename[i] = m_wheel_filename[i];
km->m_wheel_graphics_position[i] = m_wheel_graphics_position[i];
km->m_wheel_graphics_radius[i] = m_wheel_graphics_radius[i];
@ -347,18 +327,18 @@ KartModel* KartModel::makeCopy(video::E_RENDER_TYPE rt)
km->m_max_suspension[i] = m_max_suspension[i];
km->m_dampen_suspension_amplitude[i]= m_dampen_suspension_amplitude[i];
}
km->m_speed_weighted_objects.resize(m_speed_weighted_objects.size());
for(size_t i=0; i<m_speed_weighted_objects.size(); i++)
{
// Master should not have any speed weighted nodes.
assert(!m_speed_weighted_objects[i].m_node);
km->m_speed_weighted_objects[i] = m_speed_weighted_objects[i];
if (rt != video::ERT_DEFAULT)
if (krt == KRT_TRANSPARENT)
{
// Only clone the mesh if default type is not used
// Only clone the mesh if transparent type is used, see #2445
km->m_speed_weighted_objects[i].m_model = irr_driver
->copyAnimatedMesh(m_speed_weighted_objects[i].m_model, rt);
->copyAnimatedMesh(m_speed_weighted_objects[i].m_model);
}
}
@ -377,7 +357,12 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
{
assert(!m_is_master);
scene::ISceneNode* node;
scene::ISceneNode* node = NULL;
CustomRenderInfo kart_cri = CustomRenderInfo
(m_krt == KRT_BLUE ? 0.66f : m_krt == KRT_RED ? 1.0f : 0.0f, /*m_custom_hue*/
m_krt == KRT_BLUE || m_krt == KRT_RED ? 0.93f : 0, /*m_custom_min_saturation*/
m_krt == KRT_TRANSPARENT ? true : false, /*m_transparent*/
m_krt == KRT_BLUE || m_krt == KRT_RED ? m_mesh : NULL); /*To get m_affected_parts*/
if (animated_models)
{
@ -386,7 +371,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
irr_driver->getSceneManager() );
node = irr_driver->addAnimatedMesh(m_mesh, "kartmesh");
node = irr_driver->addAnimatedMesh(m_mesh, "kartmesh", NULL/*parent*/, kart_cri);
// as animated mesh are not cheap to render use frustum box culling
if (CVS->isGLSL())
node->setAutomaticCulling(scene::EAC_OFF);
@ -463,7 +448,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
debug_name = m_model_filename + " (kart-model)";
#endif
node = irr_driver->addMesh(main_frame, debug_name);
node = irr_driver->addMesh(main_frame, debug_name, NULL /*parent*/, kart_cri);
#ifdef DEBUG
node->setName(debug_name.c_str());
@ -473,8 +458,11 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
// Attach the wheels
for(unsigned int i=0; i<4; i++)
{
// Use the kart custom render info, but discard affected parts
// So all wheels are affected by the info
CustomRenderInfo wheel_cri = CustomRenderInfo(kart_cri);
if(!m_wheel_model[i]) continue;
m_wheel_node[i] = irr_driver->addMesh(m_wheel_model[i], "wheel", node);
m_wheel_node[i] = irr_driver->addMesh(m_wheel_model[i], "wheel", node, wheel_cri);
Vec3 wheel_min, wheel_max;
MeshTools::minMax3D(m_wheel_model[i], &wheel_min, &wheel_max);
m_wheel_graphics_radius[i] = 0.5f*(wheel_max.getY() - wheel_min.getY());
@ -495,8 +483,10 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
obj.m_node = NULL;
if(obj.m_model)
{
// Same for wheels above
CustomRenderInfo swo_cri = CustomRenderInfo(kart_cri);
obj.m_node = irr_driver->addAnimatedMesh(obj.m_model,
"speedweighted", node);
"speedweighted", node, swo_cri);
obj.m_node->grab();
obj.m_node->setFrameLoop(m_animation_frame[AF_SPEED_WEIGHTED_START],
@ -1021,18 +1011,3 @@ void KartModel::attachHat()
} // if bone
} // if(m_hat_name)
} // attachHat
//-----------------------------------------------------------------------------
std::vector<int> KartModel::getColorizableParts(scene::IAnimatedMesh* m)
{
std::vector<int> colorizable_parts;
for (int i = 0; i < int(m->getMeshBufferCount()); ++i)
{
scene::IMeshBuffer* mb = m->getMeshBuffer(i);
Material* material = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
if (material->isColorizable())
colorizable_parts.push_back(i);
}
return colorizable_parts;
} // getColorizableParts

View File

@ -115,6 +115,15 @@ public:
AF_SPEED_WEIGHTED_END, // End of speed-weighted animation
AF_END=AF_SPEED_WEIGHTED_END, // Last animation frame
AF_COUNT}; // Number of entries here
enum KartRenderType
{
KRT_DEFAULT,
KRT_RED,
KRT_BLUE,
KRT_TRANSPARENT,
};
private:
/** Which frame number starts/end which animation. */
int m_animation_frame[AF_COUNT];
@ -229,10 +238,12 @@ private:
/** Pointer to the kart object belonging to this kart model. */
AbstractKart* m_kart;
KartRenderType m_krt;
public:
KartModel(bool is_master);
~KartModel();
KartModel* makeCopy(video::E_RENDER_TYPE rt);
KartModel* makeCopy(KartRenderType krt);
void reset();
void loadInfo(const XMLNode &node);
bool loadModels(const KartProperties &kart_properties);
@ -328,8 +339,6 @@ public:
scene::IAnimatedMeshSceneNode* getAnimatedNode(){ return m_animated_node; }
// ------------------------------------------------------------------------
core::vector3df getHatOffset() { return m_hat_offset; }
// ------------------------------------------------------------------------
std::vector<int> getColorizableParts(scene::IAnimatedMesh* m);
}; // KartModel
#endif

View File

@ -244,8 +244,8 @@ public:
// ------------------------------------------------------------------------
/** Returns a pointer to the KartModel object. */
KartModel* getKartModelCopy
(video::E_RENDER_TYPE rt = video::ERT_DEFAULT) const
{return m_kart_model->makeCopy(rt); }
(KartModel::KartRenderType krt = KartModel::KRT_DEFAULT) const
{return m_kart_model->makeCopy(krt); }
// ------------------------------------------------------------------------
/** Returns a pointer to the main KartModel object. This copy

View File

@ -392,9 +392,8 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
m_kart_position_map[index] = (unsigned)(pos_index - 1);
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
//difficulty);
difficulty, team == SOCCER_TEAM_BLUE ?
video::ERT_BLUE : video::ERT_RED);
KartModel::KRT_BLUE : KartModel::KRT_RED);
new_kart->init(race_manager->getKartType(index));
Controller *controller = NULL;