1
0
forked from 0ad/0ad

Collada: Don't warn about unrecognised joints (since they're probably prop points). Get animation start/end times more reliably when possible.

This was SVN commit r4938.
This commit is contained in:
Ykkrosh 2007-03-02 20:09:27 +00:00
parent f1971f03d1
commit e2f1e48f53
2 changed files with 72 additions and 52 deletions

View File

@ -6,6 +6,7 @@
#include "FCollada.h"
#include "FCDocument/FCDocument.h"
#include "FCDocument/FCDController.h"
#include "FCDocument/FCDControllerInstance.h"
#include "FCDocument/FCDGeometry.h"
#include "FCDocument/FCDGeometryMesh.h"
#include "FCDocument/FCDGeometryPolygons.h"
@ -177,7 +178,7 @@ public:
// Store into the VertexBlend
int boneId = StdSkeletons::FindStandardBoneID(joint->GetName());
REQUIRE(boneId >= 0, "recognised bone name");
REQUIRE(boneId >= 0, "vertex influenced by recognised bone");
influences.bones[j] = (uint8)boneId;
influences.weights[j] = vertexInfluences[i][j].weight;
}
@ -194,6 +195,16 @@ public:
for (size_t i = 0; i < jointCount; ++i)
{
FCDSceneNode* joint = controllerInstance->GetJoint(i);
int boneId = StdSkeletons::FindStandardBoneID(joint->GetName());
if (boneId < 0)
{
// unrecognised joint - it's probably just a prop point
// or something, so ignore it
continue;
}
FMMatrix44 bindPose = skin->GetBindPoses()[i].Inverted();
HMatrix matrix;
@ -208,20 +219,13 @@ public:
{ parts.q.x, parts.q.y, parts.q.z, parts.q.w }
};
FCDSceneNode* joint = controllerInstance->GetJoint(i);
int boneId = StdSkeletons::FindStandardBoneID(joint->GetName());
if (boneId < 0)
{
Log(LOG_WARNING, "Unrecognised bone name '%s'", joint->GetName().c_str());
continue;
}
boneTransforms[boneId] = b;
}
// Construct the list of prop points
// (Currently, all objects that aren't recognised a standard bone,
// which are attached to a standard bone, are assumed to be props)
// (Currently, all objects that aren't recognised as a standard bone,
// but which are directly attached to a standard bone, are assumed to
// be prop points)
std::vector<PropPoint> propPoints;
@ -232,7 +236,7 @@ public:
int boneId = StdSkeletons::FindStandardBoneID(joint->GetName());
if (boneId < 0)
{
// Unrecognised bone name - already reported as a warning
// unrecognised joint name - ignore, same as before
continue;
}
@ -245,7 +249,7 @@ public:
continue;
}
Log(LOG_INFO, "Adding prop point %s", child->GetName().c_str());
//Log(LOG_INFO, "Adding prop point %s", child->GetName().c_str());
// Get translation and orientation of local transform

View File

@ -9,6 +9,7 @@
#include "FCDocument/FCDAnimationCurve.h"
#include "FCDocument/FCDController.h"
#include "FCDocument/FCDControllerInstance.h"
#include "FCDocument/FCDExtra.h"
#include "FCDocument/FCDGeometry.h"
#include "FCDocument/FCDGeometryMesh.h"
#include "FCDocument/FCDGeometryPolygons.h"
@ -65,51 +66,66 @@ public:
{
FCDControllerInstance* controllerInstance = (FCDControllerInstance*)instance;
// Find the first and last times which have animations
// TODO: use the FCOLLADA start_time/end_time where available
float timeStart = std::numeric_limits<float>::max();
float timeEnd = -std::numeric_limits<float>::max();
for (size_t i = 0; i < controllerInstance->GetJointCount(); ++i)
float frameLength = 1.f / 30.f; // currently we always want to create PMDs at fixed 30fps
// Find the extents of the animation:
float timeStart, timeEnd;
// FCollada tools export <extra> info in the scene to specify the start
// and end times.
// If that isn't available, we have to search for the earliest and latest
// keyframes on any of the bones.
if (doc->HasStartTime() && doc->HasEndTime())
{
FCDSceneNode* joint = controllerInstance->GetJoint(i);
REQUIRE(joint != NULL, "joint exists");
int boneId = StdSkeletons::FindStandardBoneID(joint->GetName());
if (boneId < 0)
timeStart = doc->GetStartTime();
timeEnd = doc->GetEndTime();
}
else
{
timeStart = std::numeric_limits<float>::max();
timeEnd = -std::numeric_limits<float>::max();
for (size_t i = 0; i < controllerInstance->GetJointCount(); ++i)
{
Log(LOG_WARNING, "Unrecognised bone name '%s'", joint->GetName().c_str());
continue;
}
FCDSceneNode* joint = controllerInstance->GetJoint(i);
REQUIRE(joint != NULL, "joint exists");
// Skip unanimated joints
if (joint->GetTransformCount() == 0)
continue;
REQUIRE(joint->GetTransformCount() == 1, "joint has single transform");
FCDTransform* transform = joint->GetTransform(0);
// Skip unanimated joints again. (TODO: Which of these happens in practice?)
if (! transform->IsAnimated())
continue;
// Iterate over all curves
FCDAnimated* anim = transform->GetAnimated();
FCDAnimationCurveListList& curvesList = anim->GetCurves();
for (size_t j = 0; j < curvesList.size(); ++j)
{
FCDAnimationCurveList& curves = curvesList[j];
for (size_t k = 0; k < curves.size(); ++k)
int boneId = StdSkeletons::FindStandardBoneID(joint->GetName());
if (boneId < 0)
{
FCDAnimationCurve* curve = curves[k];
timeStart = std::min(timeStart, curve->GetKeys().front());
timeEnd = std::max(timeEnd, curve->GetKeys().back());
// unrecognised joint - it's probably just a prop point
// or something, so ignore it
continue;
}
// Skip unanimated joints
if (joint->GetTransformCount() == 0)
continue;
REQUIRE(joint->GetTransformCount() == 1, "joint has single transform");
FCDTransform* transform = joint->GetTransform(0);
// Skip unanimated joints (TODO: Which of these happens in practice?)
if (! transform->IsAnimated())
continue;
// Iterate over all curves
FCDAnimated* anim = transform->GetAnimated();
FCDAnimationCurveListList& curvesList = anim->GetCurves();
for (size_t j = 0; j < curvesList.size(); ++j)
{
FCDAnimationCurveList& curves = curvesList[j];
for (size_t k = 0; k < curves.size(); ++k)
{
FCDAnimationCurve* curve = curves[k];
timeStart = std::min(timeStart, curve->GetKeys().front());
timeEnd = std::max(timeEnd, curve->GetKeys().back());
}
}
}
}
float frameLength = 1.f / 30.f;
// Count frames; don't include the last keyframe
size_t frameCount = (size_t)((timeEnd - timeStart) / frameLength - 0.5f);
// (TODO: sort out the timing/looping problems)
@ -132,7 +148,7 @@ public:
int boneId = StdSkeletons::FindStandardBoneID(joint->GetName());
if (boneId < 0)
continue; // already emitted a warning earlier
continue; // not a recognised bone - ignore it, same as before
FCDTransform* transform = joint->GetTransform(0);
FCDAnimated* anim = transform->GetAnimated();
@ -164,7 +180,7 @@ public:
int boneId = StdSkeletons::FindStandardBoneID(joint->GetName());
if (boneId < 0)
continue; // already emitted a warning earlier
continue; // not a recognised bone - ignore it, same as before
FMMatrix44 worldTransform = joint->CalculateWorldTransform();