added rigid animation support.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@967 dfc29bdd-3216-0410-991c-e03cc46cb475
master
lukeph 2007-09-17 11:09:07 +00:00
parent 9779c7a1af
commit 13d10077a3
7 changed files with 100 additions and 7 deletions

View File

@ -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;

View File

@ -7,11 +7,15 @@
#include "IMeshBuffer.h"
#include "S3DVertex.h"
namespace irr
{
namespace scene
{
{
//! A mesh buffer able to choose between
//! S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
@ -203,7 +207,12 @@ struct SSkinMeshBuffer : public IMeshBuffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) {}
//! 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::E_VERTEX_TYPE VertexType;

View File

@ -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)
{

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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:

View File

@ -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" />