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
//! List of child joints
core::array<SJoint*> Children;
core::array<u32> AttachedMeshes;
//! Animation keys causing translation change
core::array<SPositionKey> PositionKeys;
......
......@@ -8,11 +8,15 @@
#include "IMeshBuffer.h"
#include "S3DVertex.h"
namespace irr
{
namespace scene
{
//! A mesh buffer able to choose between
//! S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
struct SSkinMeshBuffer : public IMeshBuffer
......@@ -205,6 +209,11 @@ struct SSkinMeshBuffer : public IMeshBuffer
//! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other) {}
//ISkinnedMesh::SJoint *AttachedJoint;
core::matrix4 Transformation;
video::SMaterial Material;
video::E_VERTEX_TYPE VertexType;
core::array<video::S3DVertexTangents> Vertices_Tangents;
......
......@@ -335,12 +335,19 @@ void CAnimatedMeshSceneNode::render()
if (transparent == isTransparentPass)
{
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->drawMeshBuffer(mb);
}
}
}
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
// for debug purposes only:
if (DebugDataVisible && PassCount==1)
{
......
......@@ -409,12 +409,26 @@ void CSkinnedMesh::skinMesh()
buildAll_GlobalAnimatedMatrices();
//-----------------
//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
u32 i;
for (i=0; i<Vertices_Moved.size(); ++i)
for (u32 j=0; j<Vertices_Moved[i].size(); ++j)
Vertices_Moved[i][j]=false;
......@@ -999,6 +1013,21 @@ void CSkinnedMesh::finalize()
//animateMesh(0, 1);
//buildAll_LocalAnimatedMatrices();
//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)
{
mesh->Buffers.push_back( AnimatedMesh->createBuffer() );
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
{
......@@ -200,7 +209,13 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{
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)
{
......@@ -283,14 +298,30 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{
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.buffer_id=verticesLinkBuffer[id];
}
}
}
#endif
}
return true;
......@@ -490,6 +521,8 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent )
// Frame template instances as child objects when loading a Frame
// instance.
u32 JointID=0;
core::stringc name;
if (!readHeadOfDataObject(&name))
......@@ -507,6 +540,7 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent )
if (AnimatedMesh->getAllJoints()[n]->Name==name)
{
joint=AnimatedMesh->getAllJoints()[n];
JointID=n;
break;
}
}
......@@ -519,6 +553,7 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent )
#endif
joint=AnimatedMesh->createJoint(Parent);
joint->Name=name;
JointID=AnimatedMesh->getAllJoints().size()-1;
}
else
{
......@@ -577,6 +612,8 @@ bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent )
*/
SXMesh *mesh=new SXMesh;
mesh->AttachedJointID=JointID;
Meshes.push_back(mesh);
if (!parseDataObjectMesh(*mesh))
......@@ -816,6 +853,9 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
return false;
}
mesh.HasSkinning=true;
CSkinnedMesh::SJoint *joint=0;
for (u32 n=0; n < AnimatedMesh->getAllJoints().size(); ++n)
......
......@@ -46,7 +46,7 @@ public:
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.
// because in an .x file, faces can be made of more than 3
// vertices, the indices data structure is triangulated during the
......@@ -72,6 +72,10 @@ public:
core::array<u32> FaceMaterialIndices; // index of material for each face
core::array<video::SMaterial> Materials; // material array
s32 AttachedJointID;
bool HasSkinning;
};
private:
......
......@@ -359,6 +359,8 @@
<Unit filename="CIrrDeviceStub.h" />
<Unit filename="CIrrDeviceWin32.cpp" />
<Unit filename="CIrrDeviceWin32.h" />
<Unit filename="CIrrMeshFileLoader.cpp" />
<Unit filename="CIrrMeshFileLoader.h" />
<Unit filename="CIrrMeshWriter.cpp" />
<Unit filename="CIrrMeshWriter.h" />
<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