Commit 13d10077 authored by lukeph's avatar lukeph

added rigid animation support.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@967 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 9779c7a1
...@@ -137,6 +137,8 @@ namespace scene ...@@ -137,6 +137,8 @@ namespace scene
//! List of child joints //! List of child joints
core::array<SJoint*> Children; core::array<SJoint*> Children;
core::array<u32> AttachedMeshes;
//! Animation keys causing translation change //! Animation keys causing translation change
core::array<SPositionKey> PositionKeys; core::array<SPositionKey> PositionKeys;
......
...@@ -8,11 +8,15 @@ ...@@ -8,11 +8,15 @@
#include "IMeshBuffer.h" #include "IMeshBuffer.h"
#include "S3DVertex.h" #include "S3DVertex.h"
namespace irr namespace irr
{ {
namespace scene namespace scene
{ {
//! A mesh buffer able to choose between //! A mesh buffer able to choose between
//! S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime //! S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
struct SSkinMeshBuffer : public IMeshBuffer struct SSkinMeshBuffer : public IMeshBuffer
...@@ -205,6 +209,11 @@ struct SSkinMeshBuffer : public IMeshBuffer ...@@ -205,6 +209,11 @@ struct SSkinMeshBuffer : public IMeshBuffer
//! append the meshbuffer to the current buffer //! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other) {} virtual void append(const IMeshBuffer* const other) {}
//ISkinnedMesh::SJoint *AttachedJoint;
core::matrix4 Transformation;
video::SMaterial Material; video::SMaterial Material;
video::E_VERTEX_TYPE VertexType; video::E_VERTEX_TYPE VertexType;
core::array<video::S3DVertexTangents> Vertices_Tangents; core::array<video::S3DVertexTangents> Vertices_Tangents;
......
...@@ -335,12 +335,19 @@ void CAnimatedMeshSceneNode::render() ...@@ -335,12 +335,19 @@ void CAnimatedMeshSceneNode::render()
if (transparent == isTransparentPass) if (transparent == isTransparentPass)
{ {
scene::IMeshBuffer* mb = m->getMeshBuffer(i); scene::IMeshBuffer* mb = m->getMeshBuffer(i);
if (Mesh->getMeshType() == EAMT_SKINNED)
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation);
driver->setMaterial(Materials[i]); driver->setMaterial(Materials[i]);
driver->drawMeshBuffer(mb); driver->drawMeshBuffer(mb);
} }
} }
} }
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
// for debug purposes only: // for debug purposes only:
if (DebugDataVisible && PassCount==1) if (DebugDataVisible && PassCount==1)
{ {
......
...@@ -409,12 +409,26 @@ void CSkinnedMesh::skinMesh() ...@@ -409,12 +409,26 @@ void CSkinnedMesh::skinMesh()
buildAll_GlobalAnimatedMatrices(); buildAll_GlobalAnimatedMatrices();
//----------------- //-----------------
//Software skin.... //Software skin....
u32 i;
//rigid animation
for (i=0; i<AllJoints.size(); ++i)
{
for (u32 j=0; j<AllJoints[i]->AttachedMeshes.size(); ++j)
{
SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ];
Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix;
}
}
//clear skinning helper array //clear skinning helper array
u32 i;
for (i=0; i<Vertices_Moved.size(); ++i) for (i=0; i<Vertices_Moved.size(); ++i)
for (u32 j=0; j<Vertices_Moved[i].size(); ++j) for (u32 j=0; j<Vertices_Moved[i].size(); ++j)
Vertices_Moved[i][j]=false; Vertices_Moved[i][j]=false;
...@@ -999,6 +1013,21 @@ void CSkinnedMesh::finalize() ...@@ -999,6 +1013,21 @@ void CSkinnedMesh::finalize()
//animateMesh(0, 1); //animateMesh(0, 1);
//buildAll_LocalAnimatedMatrices(); //buildAll_LocalAnimatedMatrices();
//buildAll_GlobalAnimatedMatrices(); //buildAll_GlobalAnimatedMatrices();
//rigid animation for non animated meshes
for (i=0; i<AllJoints.size(); ++i)
{
for (u32 j=0; j<AllJoints[i]->AttachedMeshes.size(); ++j)
{
SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ];
Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix;
}
}
} }
......
...@@ -118,8 +118,17 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -118,8 +118,17 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{ {
mesh->Buffers.push_back( AnimatedMesh->createBuffer() ); mesh->Buffers.push_back( AnimatedMesh->createBuffer() );
mesh->Buffers.getLast()->Material = mesh->Materials[i]; mesh->Buffers.getLast()->Material = mesh->Materials[i];
if (!mesh->HasSkinning)
{
//Set up rigid animation
if (mesh->AttachedJointID!=-1)
{
AnimatedMesh->getAllJoints()[mesh->AttachedJointID]->AttachedMeshes.push_back( AnimatedMesh->getMeshBuffers().size()-1 );
}
} }
}
#ifdef BETTER_MESHBUFFER_SPLITTING_FOR_X #ifdef BETTER_MESHBUFFER_SPLITTING_FOR_X
{ {
...@@ -200,7 +209,13 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -200,7 +209,13 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{ {
ISkinnedMesh::SWeight& Weight = Joint->Weights[j]; ISkinnedMesh::SWeight& Weight = Joint->Weights[j];
const u32 id = Weight.vertex_id; u32 id = Weight.vertex_id;
if (id>verticesLink.size())
{
os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
id=0;
}
if (verticesLinkBuffer[id].size()==1) if (verticesLinkBuffer[id].size()==1)
{ {
...@@ -283,14 +298,30 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -283,14 +298,30 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{ {
ISkinnedMesh::SWeight& Weight = Joint->Weights[j]; ISkinnedMesh::SWeight& Weight = Joint->Weights[j];
const u32 id = Weight.vertex_id; u32 id = Weight.vertex_id;
if (id>verticesLink.size())
{
os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
id=0;
}
Weight.vertex_id=verticesLink[id]; Weight.vertex_id=verticesLink[id];
Weight.buffer_id=verticesLinkBuffer[id]; Weight.buffer_id=verticesLinkBuffer[id];
} }
} }
} }
#endif #endif
} }
return true; return true;
...@@ -490,6 +521,8 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent ) ...@@ -490,6 +521,8 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent )
// Frame template instances as child objects when loading a Frame // Frame template instances as child objects when loading a Frame
// instance. // instance.
u32 JointID=0;
core::stringc name; core::stringc name;
if (!readHeadOfDataObject(&name)) if (!readHeadOfDataObject(&name))
...@@ -507,6 +540,7 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent ) ...@@ -507,6 +540,7 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent )
if (AnimatedMesh->getAllJoints()[n]->Name==name) if (AnimatedMesh->getAllJoints()[n]->Name==name)
{ {
joint=AnimatedMesh->getAllJoints()[n]; joint=AnimatedMesh->getAllJoints()[n];
JointID=n;
break; break;
} }
} }
...@@ -519,6 +553,7 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent ) ...@@ -519,6 +553,7 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent )
#endif #endif
joint=AnimatedMesh->createJoint(Parent); joint=AnimatedMesh->createJoint(Parent);
joint->Name=name; joint->Name=name;
JointID=AnimatedMesh->getAllJoints().size()-1;
} }
else else
{ {
...@@ -577,6 +612,8 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent ) ...@@ -577,6 +612,8 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent )
*/ */
SXMesh *mesh=new SXMesh; SXMesh *mesh=new SXMesh;
mesh->AttachedJointID=JointID;
Meshes.push_back(mesh); Meshes.push_back(mesh);
if (!parseDataObjectMesh(*mesh)) if (!parseDataObjectMesh(*mesh))
...@@ -816,6 +853,9 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh) ...@@ -816,6 +853,9 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
return false; return false;
} }
mesh.HasSkinning=true;
CSkinnedMesh::SJoint *joint=0; CSkinnedMesh::SJoint *joint=0;
for (u32 n=0; n < AnimatedMesh->getAllJoints().size(); ++n) for (u32 n=0; n < AnimatedMesh->getAllJoints().size(); ++n)
......
...@@ -46,7 +46,7 @@ public: ...@@ -46,7 +46,7 @@ public:
struct SXMesh struct SXMesh
{ {
SXMesh() : MaxSkinWeightsPerVertex(0), MaxSkinWeightsPerFace(0), BoneCount(0) {} SXMesh() : MaxSkinWeightsPerVertex(0), MaxSkinWeightsPerFace(0), BoneCount(0),AttachedJointID(-1),HasSkinning(false){}
// this mesh contains triangulated texture data. // this mesh contains triangulated texture data.
// because in an .x file, faces can be made of more than 3 // because in an .x file, faces can be made of more than 3
// vertices, the indices data structure is triangulated during the // vertices, the indices data structure is triangulated during the
...@@ -72,6 +72,10 @@ public: ...@@ -72,6 +72,10 @@ public:
core::array<u32> FaceMaterialIndices; // index of material for each face core::array<u32> FaceMaterialIndices; // index of material for each face
core::array<video::SMaterial> Materials; // material array core::array<video::SMaterial> Materials; // material array
s32 AttachedJointID;
bool HasSkinning;
}; };
private: private:
......
...@@ -359,6 +359,8 @@ ...@@ -359,6 +359,8 @@
<Unit filename="CIrrDeviceStub.h" /> <Unit filename="CIrrDeviceStub.h" />
<Unit filename="CIrrDeviceWin32.cpp" /> <Unit filename="CIrrDeviceWin32.cpp" />
<Unit filename="CIrrDeviceWin32.h" /> <Unit filename="CIrrDeviceWin32.h" />
<Unit filename="CIrrMeshFileLoader.cpp" />
<Unit filename="CIrrMeshFileLoader.h" />
<Unit filename="CIrrMeshWriter.cpp" /> <Unit filename="CIrrMeshWriter.cpp" />
<Unit filename="CIrrMeshWriter.h" /> <Unit filename="CIrrMeshWriter.h" />
<Unit filename="CLMTSMeshFileLoader.cpp" /> <Unit filename="CLMTSMeshFileLoader.cpp" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment