24 #include "FCDocument/FCDocument.h"
25 #include "FCDocument/FCDocumentTools.h"
26 #include "FCDocument/FCDAnimated.h"
27 #include "FCDocument/FCDAnimationCurve.h"
28 #include "FCDocument/FCDAnimationKey.h"
29 #include "FCDocument/FCDController.h"
30 #include "FCDocument/FCDControllerInstance.h"
31 #include "FCDocument/FCDExtra.h"
32 #include "FCDocument/FCDGeometry.h"
33 #include "FCDocument/FCDGeometryMesh.h"
34 #include "FCDocument/FCDGeometryPolygons.h"
35 #include "FCDocument/FCDGeometrySource.h"
36 #include "FCDocument/FCDSceneNode.h"
64 if (converter.
GetInstance().GetType() == FCDEntityInstance::CONTROLLER)
66 FCDControllerInstance& controllerInstance =
static_cast<FCDControllerInstance&
>(converter.
GetInstance());
70 assert(converter.
GetInstance().GetEntity()->GetType() == FCDEntity::CONTROLLER);
71 FCDController* controller =
static_cast<FCDController*
>(converter.
GetInstance().GetEntity());
73 FCDSkinController* skin = controller->GetSkinController();
74 REQUIRE(skin != NULL,
"is skin controller");
78 float frameLength = 1.f / 30.f;
82 float timeStart = 0, timeEnd = 0;
85 REQUIRE(timeEnd > timeStart,
"animation end frame must come after start frame");
88 size_t frameCount = (size_t)((timeEnd - timeStart) / frameLength - 0.5f);
89 REQUIRE(frameCount > 0,
"animation must have frames");
94 std::vector<BoneTransform> boneTransforms;
96 for (
size_t frame = 0; frame < frameCount; ++frame)
98 float time = timeStart + frameLength * frame;
101 std::vector<BoneTransform> frameBoneTransforms (boneCount, boneDefault);
109 for (
size_t i = 0; i < controllerInstance.GetJointCount(); ++i)
111 FCDSceneNode* joint = controllerInstance.GetJoint(i);
113 int boneId = skeleton.
GetRealBoneID(joint->GetName().c_str());
117 FMMatrix44 worldTransform = joint->CalculateWorldTransform();
120 memcpy(matrix, worldTransform.Transposed().m,
sizeof(matrix));
126 { parts.
t.
x, parts.
t.
y, parts.
t.
z },
127 { parts.
q.
x, parts.
q.
y, parts.
q.
z, parts.
q.
w }
130 frameBoneTransforms[boneId] = b;
134 copy(frameBoneTransforms.begin(), frameBoneTransforms.end(),
135 std::inserter(boneTransforms, boneTransforms.end()));
142 WritePSA(output, frameCount, boneCount, boneTransforms);
153 static void WritePSA(
OutputCB&
output,
size_t frameCount,
size_t boneCount,
const std::vector<BoneTransform>& boneTransforms)
156 write(output, (uint32)1);
157 write(output, (uint32)(
161 7*4*boneCount*frameCount
165 write(output, (uint32)0);
168 write(output, 1000.f/30.f);
170 write(output, (uint32)boneCount);
171 write(output, (uint32)frameCount);
173 for (
size_t i = 0; i < boneCount*frameCount; ++i)
175 output((
char*)&boneTransforms[i], 7*4);
180 const FMMatrix44& transform,
bool yUp,
bool isXSI)
197 const FCDControllerInstance& controllerInstance,
198 float& timeStart,
float& timeEnd)
217 timeStart = std::numeric_limits<float>::max();
218 timeEnd = -std::numeric_limits<float>::max();
219 for (
size_t i = 0; i < controllerInstance.GetJointCount(); ++i)
221 const FCDSceneNode* joint = controllerInstance.GetJoint(i);
222 REQUIRE(joint != NULL,
"joint exists");
224 int boneId = skeleton.
GetBoneID(joint->GetName().c_str());
233 if (joint->GetTransformCount() == 0)
236 for (
size_t j = 0; j < joint->GetTransformCount(); ++j)
238 const FCDTransform* transform = joint->GetTransform(j);
240 if (! transform->IsAnimated())
244 const FCDAnimated* anim = transform->GetAnimated();
245 const FCDAnimationCurveListList& curvesList = anim->GetCurves();
246 for (
size_t j = 0; j < curvesList.size(); ++j)
248 const FCDAnimationCurveTrackList& curves = curvesList[j];
249 for (
size_t k = 0; k < curves.size(); ++k)
251 const FCDAnimationCurve* curve = curves[k];
252 timeStart = std::min(timeStart, curve->GetKeys()[0]->input);
253 timeEnd = std::max(timeEnd, curve->GetKeys()[curve->GetKeyCount()-1]->input);
263 if (! extra)
return false;
265 FCDEType* type = extra->GetDefaultType();
266 if (! type)
return false;
268 FCDETechnique* technique = type->FindTechnique(
"XSI");
269 if (! technique)
return false;
271 FCDENode* scene = technique->FindChildNode(
"SI_Scene");
272 if (! scene)
return false;
274 float start = FLT_MAX, end = -FLT_MAX, framerate = 0.f;
276 FCDENodeList paramNodes;
277 scene->FindChildrenNodes(
"xsi_param", paramNodes);
278 for (FCDENodeList::iterator it = paramNodes.begin(); it != paramNodes.end(); ++it)
280 if ((*it)->ReadAttribute(
"sid") ==
"start")
281 start = FUStringConversion::ToFloat((*it)->GetContent());
282 else if ((*it)->ReadAttribute(
"sid") ==
"end")
283 end = FUStringConversion::ToFloat((*it)->GetContent());
284 else if ((*it)->ReadAttribute(
"sid") ==
"frameRate")
285 framerate = FUStringConversion::ToFloat((*it)->GetContent());
288 if (framerate != 0.f && start != FLT_MAX && end != -FLT_MAX)
290 timeStart = start / framerate;
291 timeEnd = end / framerate;
300 for (
size_t i = 0; i < node.GetTransformCount(); ++i)
302 FCDTransform* transform = node.GetTransform(i);
303 FCDAnimated* anim = transform->GetAnimated();
305 anim->Evaluate(time);
308 for (
size_t i = 0; i < node.GetChildrenCount(); ++i)
Standard document loader.
#define REQUIRE(value, message)
Throws a ColladaException unless the value is true.
FCDocument * GetDocument() const
Returns the FCDocument that was loaded.
FCDExtra * GetExtra() const
Returns the <extra> data from the <COLLADA> element.
FMMatrix44 FMMatrix44_Identity
static void GetAnimationRange(const FColladaDocument &doc, const Skeleton &skeleton, const FCDControllerInstance &controllerInstance, float &timeStart, float &timeEnd)
void FixSkeletonRoots(FCDControllerInstance &controllerInstance)
Fixes some occasional problems with the skeleton root definitions in a controller.
const Skeleton & FindSkeleton(const FCDControllerInstance &controllerInstance)
Finds the skeleton definition which best matches the given controller.
FMMatrix44 DecomposeToScaleMatrix(const FMMatrix44 &m)
static void ColladaToPSA(const char *input, OutputCB &output, std::string &xmlErrors)
Converts a COLLADA XML document into the PSA animation format.
const FColladaDocument & GetDocument() const
void TransformBones(std::vector< BoneTransform > &bones, const FMMatrix44 &scaleTransform, bool yUp)
Performs the standard transformations on bones, applying a scale matrix and moving them into the game...
int GetBoneCount() const
Returns the number of bones in the standard-skeleton which this current skeleton is mapped onto...
int GetRealBoneID(const std::string &name) const
Similar to GetBoneID, but only returns a value for the most important (first) nonstandard-skeleton bo...
FCDEntityInstance & GetInstance()
void decomp_affine(HMatrix A, AffineParts *parts)
Wrapper for code shared between the PMD and PSA converters.
static void WritePSA(OutputCB &output, size_t frameCount, size_t boneCount, const std::vector< BoneTransform > &boneTransforms)
Writes the animation data in the PSA format.
void write(OutputCB &output, const T &data)
Outputs a structure, using sizeof to get the size.
static void EvaluateAnimations(FCDSceneNode &node, float time)
static bool GetAnimationRange_XSI(const FColladaDocument &doc, float &timeStart, float &timeEnd)
void ColladaToPSA(const char *input, OutputCB &output, std::string &xmlErrors)
static void TransformVertices(std::vector< BoneTransform > &bones, const FMMatrix44 &transform, bool yUp, bool isXSI)
int GetBoneID(const std::string &name) const
Returns the ID number of the standard-skeleton bone, which corresponds to the named nonstandard-skele...