Implemented StdMeshInstance

stable-5.2
Armin Burgmeier 2009-07-10 21:57:11 +02:00
parent 2a3382b4ea
commit 16bd81ffad
2 changed files with 103 additions and 7 deletions

View File

@ -114,12 +114,10 @@ public:
// *this = trans * *this
void Transform(const StdMeshMatrix& trans);
#if 0
// *this *= f;
void Mul(float f);
// *this += other;
void Add(const StdMeshVertex& other);
#endif
};
class StdMeshFace
@ -150,6 +148,7 @@ private:
class StdMeshAnimation
{
friend class StdMesh;
friend class StdMeshInstance;
public:
StdMeshAnimation() {}
StdMeshAnimation(const StdMeshAnimation& other);
@ -166,6 +165,7 @@ private:
class StdMesh
{
friend class StdMeshInstance;
public:
StdMesh();
~StdMesh();
@ -184,7 +184,7 @@ public:
const StdMeshBone& GetBone(unsigned int i) const { return *Bones[i]; }
unsigned int GetNumBones() const { return Bones.size(); }
const StdMeshAnimation& GetAnimationByName(const char* name);
const StdMeshAnimation* GetAnimationByName(const StdStrBuf& name) const;
const StdMeshMaterial& GetMaterial() const { return *Material; }
private:
@ -214,17 +214,26 @@ class StdMeshInstance
public:
StdMeshInstance(const StdMesh& mesh);
void SetAnimation(const StdStrBuf& animation);
const StdMeshAnimation& GetAnimation() const;
void SetAnimation(const StdStrBuf& animation_name);
void UnsetAnimation();
const StdMeshAnimation* GetAnimation() const { return Animation; }
void SetPosition(float position);
float GetPosition() const { return Position; }
// Get vertex of instance, with current animation applied. This needs to
// go elsewhere if/when we want to calculate this on the hardware.
const StdMeshVertex& GetVertex(unsigned int i) const { return Vertices[i]; }
unsigned int GetNumVertices() const { return Vertices.size(); }
const StdMesh& Mesh;
protected:
const StdMeshAnimation* Animation;
float Position;
std::vector<StdMeshMatrix> BoneTransforms;
std::vector<StdMeshVertex> Vertices;
};

View File

@ -224,7 +224,6 @@ void StdMeshVertex::Transform(const StdMeshMatrix& trans)
nz = trans(2,0)*old.nx + trans(2,1)*old.ny + trans(2,2)*old.nz;
}
#if 0
void StdMeshVertex::Mul(float f)
{
x *= f;
@ -249,7 +248,6 @@ void StdMeshVertex::Add(const StdMeshVertex& other)
ny += other.ny;
nz += other.nz;
}
#endif
StdMeshMatrix StdMeshTrack::GetTransformAt(float time) const
{
@ -610,4 +608,93 @@ void StdMesh::AddMasterBone(StdMeshBone* bone)
AddMasterBone(bone->Children[i]);
}
const StdMeshAnimation* StdMesh::GetAnimationByName(const StdStrBuf& name) const
{
std::map<StdStrBuf, StdMeshAnimation>::const_iterator iter = Animations.find(name);
if(iter == Animations.end()) return NULL;
return &iter->second;
}
StdMeshInstance::StdMeshInstance(const StdMesh& mesh):
Mesh(mesh), Animation(NULL), Position(0.0f),
BoneTransforms(Mesh.GetNumBones()), Vertices(Mesh.GetNumVertices())
{
for(unsigned int i = 0; i < Mesh.GetNumVertices(); ++i)
Vertices[i] = Mesh.GetVertex(i);
}
void StdMeshInstance::SetAnimation(const StdStrBuf& animation_name)
{
Animation = Mesh.GetAnimationByName(animation_name);
SetPosition(0.0f);
}
void StdMeshInstance::UnsetAnimation()
{
Animation = NULL;
// Reset instance vertices
for(unsigned int i = 0; i < Mesh.GetNumVertices(); ++i)
Vertices[i] = Mesh.GetVertex(i);
}
void StdMeshInstance::SetPosition(float position)
{
assert(Animation);
Position = position;
// Compute transformation matrix for each bone.
for(unsigned int i = 0; i < BoneTransforms.size(); ++i)
{
StdMeshTrack* track = Animation->Tracks[i];
if(track)
{
BoneTransforms[i] = track->GetTransformAt(position);
}
else
{
// No track for this bone, so use parent transformation
const StdMeshBone* parent = Mesh.GetBone(i).GetParent();
if(parent)
{
// Parent should already have been processed, because the bone indices
// are supposed to be hierarchically ordered.
assert(parent->Index < i);
BoneTransforms[i] = BoneTransforms[parent->Index];
}
else
{
BoneTransforms[i].SetIdentity();
}
}
}
// Compute transformation for each vertex. We could later think about
// doing this on the GPU using a vertex shader. This would then probably
// need to go to CStdGL::PerformMesh and CStdD3D::PerformMesh.
for(unsigned int i = 0; i < Vertices.size(); ++i)
{
const StdMesh::Vertex& vertex = Mesh.Vertices[i];
if(!vertex.BoneAssignments.empty())
{
Vertices[i].x = Vertices[i].y = Vertices[i].z = 0.0f;
Vertices[i].nx = Vertices[i].ny = Vertices[i].nz = 0.0f;
Vertices[i].u = vertex.u; Vertices[i].v = vertex.v;
for(unsigned int j = 0; j < vertex.BoneAssignments.size(); ++j)
{
const StdMeshVertexBoneAssignment& assignment = vertex.BoneAssignments[j];
StdMeshVertex vtx = vertex;
vtx.Transform(BoneTransforms[assignment.BoneIndex]);
vtx.Mul(assignment.Weight);
Vertices[i].Add(vtx);
}
}
else
{
Vertices[i] = vertex;
}
}
}
// vim: et ts=2 sw=2