Merge branch 'master' of https://github.com/supertuxkart/stk-code
This commit is contained in:
commit
9f4c842b6c
@ -1474,77 +1474,6 @@ void CSkinnedMesh::calculateTangents(
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Copies a mesh.
|
||||
*/
|
||||
CSkinnedMesh *CSkinnedMesh::clone()
|
||||
{
|
||||
|
||||
CSkinnedMesh* skinned_mesh = new CSkinnedMesh();
|
||||
|
||||
for (u32 i = 0; i < getMeshBuffers().size(); i++)
|
||||
{
|
||||
SSkinMeshBuffer * buffer = skinned_mesh->addMeshBuffer();
|
||||
*buffer = *(getMeshBuffers()[i]);
|
||||
}
|
||||
|
||||
for (u32 j = 0; j < getAllJoints().size(); ++j)
|
||||
{
|
||||
ISkinnedMesh::SJoint *joint = skinned_mesh->addJoint();
|
||||
*joint = *(getAllJoints()[j]);
|
||||
}
|
||||
|
||||
// fix children pointers (they still have old pointers)
|
||||
core::array<ISkinnedMesh::SJoint*> & new_joints = skinned_mesh->getAllJoints();
|
||||
for (u32 i = 0; i < new_joints.size(); ++i)
|
||||
{
|
||||
ISkinnedMesh::SJoint * joint = new_joints[i];
|
||||
for (u32 c = 0; c < joint->Children.size(); ++c)
|
||||
{
|
||||
// the child is one of the oldJoints and must be replaced by the newjoint on the same index
|
||||
bool found = false;
|
||||
for (u32 k = 0; k < AllJoints.size(); ++k)
|
||||
{
|
||||
if (joint->Children[c] == AllJoints[k])
|
||||
{
|
||||
joint->Children[c] = new_joints[k];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} // k < old_joints.size
|
||||
|
||||
if (!found)
|
||||
found = true;
|
||||
} // c < joint->Children.size()
|
||||
} // i < new_joints.size()
|
||||
|
||||
// In finalize the values from LocalBuffers are copied into
|
||||
// Weights[].StaticPos. Since skinned_mesh already has the correct
|
||||
// values in Weights, we have to copy the values from Weights
|
||||
// into LocalBuffer (so that in the copy from LocalBuffer to weights
|
||||
// no values are overwritten).
|
||||
// FIXME: Not ideal, better would be not to copy the values in
|
||||
// finalize().
|
||||
for (unsigned int i = 0; i<AllJoints.size(); ++i)
|
||||
{
|
||||
SJoint *joint = AllJoints[i];
|
||||
for (unsigned int j = 0; j<joint->Weights.size(); ++j)
|
||||
{
|
||||
const u16 buffer_id = joint->Weights[j].buffer_id;
|
||||
const u32 vertex_id = joint->Weights[j].vertex_id;
|
||||
|
||||
skinned_mesh->LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos;
|
||||
skinned_mesh->LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal;
|
||||
}
|
||||
}
|
||||
skinned_mesh->finalize();
|
||||
|
||||
|
||||
|
||||
return skinned_mesh;
|
||||
|
||||
} // clone
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
|
@ -159,7 +159,6 @@ namespace scene
|
||||
void addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
|
||||
IAnimatedMeshSceneNode* node,
|
||||
ISceneManager* smgr);
|
||||
CSkinnedMesh *clone();
|
||||
private:
|
||||
void checkForAnimation();
|
||||
|
||||
|
@ -1069,28 +1069,6 @@ scene::IMesh *IrrDriver::getMesh(const std::string &filename)
|
||||
return am->getMesh(0);
|
||||
} // getMesh
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Create a skinned mesh which has copied all meshbuffers and joints of the
|
||||
* original mesh. Note, that this will not copy any other information like
|
||||
* joints data.
|
||||
* \param mesh Original mesh
|
||||
* \return Newly created skinned mesh. You should call drop() when you don't
|
||||
* need it anymore.
|
||||
*/
|
||||
scene::IAnimatedMesh *IrrDriver::copyAnimatedMesh(scene::IAnimatedMesh *orig)
|
||||
{
|
||||
using namespace scene;
|
||||
CSkinnedMesh *mesh = dynamic_cast<CSkinnedMesh*>(orig);
|
||||
if (!mesh)
|
||||
{
|
||||
Log::error("copyAnimatedMesh", "Given mesh was not a skinned mesh.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scene::IAnimatedMesh* out = mesh->clone();
|
||||
return out;
|
||||
} // copyAnimatedMesh
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets the material flags in this mesh depending on the settings in
|
||||
* material_manager.
|
||||
@ -1236,7 +1214,8 @@ scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
|
||||
const std::string& debug_name,
|
||||
scene::ISceneNode *parent,
|
||||
RenderInfo* render_info,
|
||||
bool all_parts_colorized)
|
||||
bool all_parts_colorized,
|
||||
int frame_for_mesh)
|
||||
{
|
||||
if (!CVS->isGLSL())
|
||||
return m_scene_manager->addMeshSceneNode(mesh, parent);
|
||||
@ -1251,7 +1230,8 @@ scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
|
||||
core::vector3df(0, 0, 0),
|
||||
core::vector3df(1.0f, 1.0f, 1.0f),
|
||||
true, render_info,
|
||||
all_parts_colorized);
|
||||
all_parts_colorized,
|
||||
frame_for_mesh);
|
||||
node->drop();
|
||||
|
||||
return node;
|
||||
|
@ -358,7 +358,6 @@ 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::ITexture *applyMask(video::ITexture* texture,
|
||||
const std::string& mask_path);
|
||||
void displayFPS();
|
||||
@ -393,7 +392,8 @@ public:
|
||||
const std::string& debug_name,
|
||||
scene::ISceneNode *parent = NULL,
|
||||
RenderInfo* render_info = NULL,
|
||||
bool all_parts_colorized = false);
|
||||
bool all_parts_colorized = false,
|
||||
int frame_for_mesh = -1);
|
||||
PerCameraNode *addPerCameraNode(scene::ISceneNode* node,
|
||||
scene::ICameraSceneNode* cam,
|
||||
scene::ISceneNode *parent = NULL);
|
||||
|
@ -99,6 +99,16 @@ void STKAnimatedMesh::updateNoGL()
|
||||
|
||||
if (!isMaterialInitialized)
|
||||
{
|
||||
// Use a default render info to distinguish same mesh buffer created by
|
||||
// different animated mesh node in vao manager when using instanced
|
||||
// rendering
|
||||
RenderInfo* default_ri = NULL;
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
{
|
||||
default_ri = new RenderInfo();
|
||||
m_static_render_info.push_back(default_ri);
|
||||
}
|
||||
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
const u32 mb_count = m->getMeshBufferCount();
|
||||
for (u32 i = 0; i < mb_count; ++i)
|
||||
@ -121,7 +131,7 @@ void STKAnimatedMesh::updateNoGL()
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_ri = NULL;
|
||||
cur_ri = default_ri;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -137,7 +147,7 @@ void STKAnimatedMesh::updateNoGL()
|
||||
assert(cur_ri ? cur_ri->isStatic() : true);
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
|
||||
affected || m_all_parts_colorized || (cur_ri
|
||||
&& cur_ri->isTransparent()) ? cur_ri : NULL));
|
||||
&& cur_ri->isTransparent()) ? cur_ri : default_ri));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
|
||||
@ -221,7 +231,7 @@ void STKAnimatedMesh::updateGL()
|
||||
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
{
|
||||
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
|
||||
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb, GLmeshes[i].m_render_info);
|
||||
mesh.vaoBaseVertex = p.first;
|
||||
mesh.vaoOffset = p.second;
|
||||
}
|
||||
|
@ -32,8 +32,8 @@
|
||||
#include "utils/helpers.hpp"
|
||||
#include "utils/tuple.hpp"
|
||||
|
||||
#include <ISceneManager.h>
|
||||
#include <IMaterialRenderer.h>
|
||||
#include <ISceneManager.h>
|
||||
|
||||
// ============================================================================
|
||||
class ColorizeShader : public Shader<ColorizeShader, core::matrix4,
|
||||
@ -54,12 +54,14 @@ 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, RenderInfo* render_info, bool all_parts_colorized) :
|
||||
const irr::core::vector3df& scale, bool createGLMeshes, RenderInfo* render_info, bool all_parts_colorized,
|
||||
int frame_for_mesh) :
|
||||
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
|
||||
{
|
||||
isDisplacement = false;
|
||||
immediate_draw = false;
|
||||
update_each_frame = false;
|
||||
m_frame_for_mesh = frame_for_mesh;
|
||||
isGlow = false;
|
||||
|
||||
m_debug_name = debug_name;
|
||||
@ -250,9 +252,18 @@ void STKMeshSceneNode::updateGL()
|
||||
{
|
||||
if (isGLInitialized)
|
||||
return;
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
|
||||
scene::IAnimatedMesh* am = dynamic_cast<scene::IAnimatedMesh*>(Mesh);
|
||||
scene::IMesh* m = Mesh;
|
||||
if (am && m_frame_for_mesh > -1)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
// Get the correct frame of animation for animated mesh
|
||||
m = am->getMesh(m_frame_for_mesh);
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = m->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
|
@ -29,6 +29,7 @@ class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
|
||||
{
|
||||
protected:
|
||||
PtrVector<RenderInfo> m_static_render_info;
|
||||
int m_frame_for_mesh;
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix;
|
||||
core::vector3df windDir;
|
||||
@ -58,7 +59,8 @@ public:
|
||||
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,
|
||||
RenderInfo* render_info = NULL, bool all_parts_colorized = false);
|
||||
RenderInfo* render_info = NULL, bool all_parts_colorized = false,
|
||||
int frame_for_mesh = -1);
|
||||
virtual void render();
|
||||
virtual void setMesh(irr::scene::IMesh* mesh);
|
||||
virtual void OnRegisterSceneNode();
|
||||
|
@ -41,7 +41,6 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include <SViewFrustum.h>
|
||||
#include <functional>
|
||||
|
||||
template<typename T>
|
||||
struct InstanceFiller
|
||||
@ -156,28 +155,6 @@ FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > Instan
|
||||
PolyCount += (InstanceBufferOffset - InitialOffset) * mesh->IndexCount / 3;
|
||||
}
|
||||
|
||||
class MeshRenderInfoHash
|
||||
{
|
||||
public:
|
||||
size_t operator() (const std::pair<scene::IMeshBuffer*, RenderInfo*> &p) const
|
||||
{
|
||||
return (std::hash<scene::IMeshBuffer*>()(p.first) ^
|
||||
(std::hash<RenderInfo*>()(p.second) << 1));
|
||||
}
|
||||
};
|
||||
|
||||
struct MeshRenderInfoEquals : std::binary_function
|
||||
<const std::pair<scene::IMeshBuffer*, RenderInfo*>&,
|
||||
const std::pair<scene::IMeshBuffer*, RenderInfo*>&, bool>
|
||||
{
|
||||
result_type operator() (first_argument_type lhs,
|
||||
second_argument_type rhs) const
|
||||
{
|
||||
return (lhs.first == rhs.first) &&
|
||||
(lhs.second == rhs.second);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static
|
||||
void FillInstances(const std::unordered_map<std::pair<scene::IMeshBuffer*, RenderInfo*>, std::vector<std::pair<GLMesh *, scene::ISceneNode*> >, MeshRenderInfoHash, MeshRenderInfoEquals> &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
|
||||
|
@ -287,7 +287,7 @@ irr::video::E_VERTEX_TYPE VAOManager::getVertexType(enum VTXTYPE tp)
|
||||
}
|
||||
}
|
||||
|
||||
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
|
||||
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp, RenderInfo* ri)
|
||||
{
|
||||
size_t old_vtx_cnt = last_vertex[tp];
|
||||
size_t old_idx_cnt = last_index[tp];
|
||||
@ -318,26 +318,28 @@ void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, old_idx_cnt * sizeof(u16), mb->getIndexCount() * sizeof(u16), mb->getIndices());
|
||||
}
|
||||
|
||||
mappedBaseVertex[tp][mb] = old_vtx_cnt;
|
||||
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
|
||||
std::pair<scene::IMeshBuffer*, RenderInfo*> key(mb, ri);
|
||||
mappedBaseVertex[tp][key] = old_vtx_cnt;
|
||||
mappedBaseIndex[tp][key] = old_idx_cnt * sizeof(u16);
|
||||
}
|
||||
|
||||
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
|
||||
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb, RenderInfo* ri)
|
||||
{
|
||||
VTXTYPE tp = getVTXTYPE(mb->getVertexType());
|
||||
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
|
||||
std::pair<scene::IMeshBuffer*, RenderInfo*> key(mb, ri);
|
||||
if (mappedBaseVertex[tp].find(key) == mappedBaseVertex[tp].end())
|
||||
{
|
||||
assert(mappedBaseIndex[tp].find(mb) == mappedBaseIndex[tp].end());
|
||||
append(mb, tp);
|
||||
assert(mappedBaseIndex[tp].find(key) == mappedBaseIndex[tp].end());
|
||||
append(mb, tp, ri);
|
||||
regenerateVAO(tp);
|
||||
regenerateInstancedVAO();
|
||||
}
|
||||
|
||||
std::unordered_map<scene::IMeshBuffer*, unsigned>::iterator It;
|
||||
It = mappedBaseVertex[tp].find(mb);
|
||||
std::unordered_map<std::pair<scene::IMeshBuffer*, RenderInfo*>, unsigned, MeshRenderInfoHash, MeshRenderInfoEquals>::iterator It;
|
||||
It = mappedBaseVertex[tp].find(key);
|
||||
assert(It != mappedBaseVertex[tp].end());
|
||||
unsigned vtx = It->second;
|
||||
It = mappedBaseIndex[tp].find(mb);
|
||||
It = mappedBaseIndex[tp].find(key);
|
||||
assert(It != mappedBaseIndex[tp].end());
|
||||
return std::pair<unsigned, unsigned>(vtx, It->second);
|
||||
}
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
class RenderInfo;
|
||||
|
||||
enum InstanceType
|
||||
{
|
||||
InstanceTypeDualTex,
|
||||
@ -153,6 +155,30 @@ struct GlowInstanceData
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
|
||||
class MeshRenderInfoHash
|
||||
{
|
||||
public:
|
||||
size_t operator() (const std::pair<irr::scene::IMeshBuffer*, RenderInfo*> &p) const
|
||||
{
|
||||
return (std::hash<irr::scene::IMeshBuffer*>()(p.first) ^
|
||||
(std::hash<RenderInfo*>()(p.second) << 1));
|
||||
}
|
||||
};
|
||||
|
||||
struct MeshRenderInfoEquals : std::binary_function
|
||||
<const std::pair<irr::scene::IMeshBuffer*, RenderInfo*>&,
|
||||
const std::pair<irr::scene::IMeshBuffer*, RenderInfo*>&, bool>
|
||||
{
|
||||
result_type operator() (first_argument_type lhs,
|
||||
second_argument_type rhs) const
|
||||
{
|
||||
return (lhs.first == rhs.first) &&
|
||||
(lhs.second == rhs.second);
|
||||
}
|
||||
};
|
||||
|
||||
class VAOManager : public Singleton<VAOManager>
|
||||
{
|
||||
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
|
||||
@ -162,7 +188,7 @@ class VAOManager : public Singleton<VAOManager>
|
||||
void *VBOPtr[VTXTYPE_COUNT], *IBOPtr[VTXTYPE_COUNT];
|
||||
size_t RealVBOSize[VTXTYPE_COUNT], RealIBOSize[VTXTYPE_COUNT];
|
||||
size_t last_vertex[VTXTYPE_COUNT], last_index[VTXTYPE_COUNT];
|
||||
std::unordered_map<irr::scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
|
||||
std::unordered_map <std::pair<irr::scene::IMeshBuffer*, RenderInfo*>, unsigned, MeshRenderInfoHash, MeshRenderInfoEquals> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
|
||||
std::map<std::pair<irr::video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
|
||||
|
||||
void cleanInstanceVAOs();
|
||||
@ -172,10 +198,10 @@ class VAOManager : public Singleton<VAOManager>
|
||||
size_t getVertexPitch(enum VTXTYPE) const;
|
||||
VTXTYPE getVTXTYPE(irr::video::E_VERTEX_TYPE type);
|
||||
irr::video::E_VERTEX_TYPE getVertexType(enum VTXTYPE tp);
|
||||
void append(irr::scene::IMeshBuffer *, VTXTYPE tp);
|
||||
void append(irr::scene::IMeshBuffer *, VTXTYPE tp, RenderInfo* ri = NULL);
|
||||
public:
|
||||
VAOManager();
|
||||
std::pair<unsigned, unsigned> getBase(irr::scene::IMeshBuffer *);
|
||||
std::pair<unsigned, unsigned> getBase(irr::scene::IMeshBuffer *, RenderInfo* ri = NULL);
|
||||
GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; }
|
||||
void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; }
|
||||
unsigned getVBO(irr::video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
|
||||
|
@ -247,12 +247,6 @@ KartModel::~KartModel()
|
||||
{
|
||||
// Master KartModels should never have a speed weighted object attached.
|
||||
assert(!m_is_master);
|
||||
|
||||
// Drop the cloned transparent model if created
|
||||
if (m_krt == KRT_TRANSPARENT)
|
||||
{
|
||||
m_speed_weighted_objects[i].m_model->drop();
|
||||
}
|
||||
m_speed_weighted_objects[i].m_node->drop();
|
||||
}
|
||||
if(m_is_master && m_speed_weighted_objects[i].m_model)
|
||||
@ -262,20 +256,15 @@ KartModel::~KartModel()
|
||||
}
|
||||
}
|
||||
|
||||
// In case of the master, the mesh must be dropped. A non-master KartModel
|
||||
// has a copy of the master's mesh, so it needs to be dropped, too.
|
||||
if (m_mesh)
|
||||
if (m_is_master && m_mesh)
|
||||
{
|
||||
m_mesh->drop();
|
||||
if (m_is_master)
|
||||
// If there is only one copy left, it's the copy in irrlicht's
|
||||
// mesh cache, so it can be removed.
|
||||
if (m_mesh && m_mesh->getReferenceCount() == 1)
|
||||
{
|
||||
// If there is only one copy left, it's the copy in irrlicht's
|
||||
// mesh cache, so it can be removed.
|
||||
if (m_mesh && m_mesh->getReferenceCount() == 1)
|
||||
{
|
||||
irr_driver->dropAllTextures(m_mesh);
|
||||
irr_driver->removeMeshFromCache(m_mesh);
|
||||
}
|
||||
irr_driver->dropAllTextures(m_mesh);
|
||||
irr_driver->removeMeshFromCache(m_mesh);
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,7 +297,7 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
|
||||
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);
|
||||
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;
|
||||
@ -343,12 +332,6 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
|
||||
// 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 (krt == KRT_TRANSPARENT)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int i=AF_BEGIN; i<=AF_END; i++)
|
||||
@ -444,8 +427,12 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
|
||||
? m_animation_frame[AF_STRAIGHT]
|
||||
: 0;
|
||||
|
||||
scene::IMesh* main_frame = m_mesh->getMesh(straight_frame);
|
||||
main_frame->setHardwareMappingHint(scene::EHM_STATIC);
|
||||
scene::IMesh* main_frame = m_mesh;
|
||||
if (!CVS->isGLSL())
|
||||
{
|
||||
main_frame = m_mesh->getMesh(straight_frame);
|
||||
main_frame->setHardwareMappingHint(scene::EHM_STATIC);
|
||||
}
|
||||
|
||||
std::string debug_name;
|
||||
|
||||
@ -454,7 +441,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
|
||||
#endif
|
||||
|
||||
node = irr_driver->addMesh(main_frame, debug_name,
|
||||
NULL /*parent*/, getRenderInfo());
|
||||
NULL /*parent*/, getRenderInfo(), false, straight_frame);
|
||||
|
||||
#ifdef DEBUG
|
||||
node->setName(debug_name.c_str());
|
||||
|
Loading…
Reference in New Issue
Block a user