|
@@ -34,21 +34,79 @@ unsigned int getMaxOffset(domInputLocalOffset_Array& inputArray)
|
|
|
return maxOffset;
|
|
return maxOffset;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Prompts the user if they want to group animations automatically.
|
|
|
|
|
+ * If the user enters an invalid response, the question is asked again.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @return True if the user wants to group animations, false otherwise.
|
|
|
|
|
+ */
|
|
|
|
|
+bool promptUserGroupAnimations()
|
|
|
|
|
+{
|
|
|
|
|
+ char buffer[80];
|
|
|
|
|
+ for (;;)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("Do you want to group animations ? (y/n)\n");
|
|
|
|
|
+ std::cin.getline(buffer, 80);
|
|
|
|
|
+
|
|
|
|
|
+ if (buffer[0] == 'y' || buffer[0] == 'Y' || buffer[0] == '\0')
|
|
|
|
|
+ {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (buffer[0] == 'n' || buffer[0] == 'N')
|
|
|
|
|
+ {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void DAESceneEncoder::optimizeCOLLADA(const EncoderArguments& arguments, domCOLLADA* dom)
|
|
void DAESceneEncoder::optimizeCOLLADA(const EncoderArguments& arguments, domCOLLADA* dom)
|
|
|
{
|
|
{
|
|
|
- DAEOptimizer optimizer(dom);
|
|
|
|
|
const std::vector<std::string>& groupAnimatioNodeIds = arguments.getGroupAnimationNodeId();
|
|
const std::vector<std::string>& groupAnimatioNodeIds = arguments.getGroupAnimationNodeId();
|
|
|
const std::vector<std::string>& groupAnimatioIds = arguments.getGroupAnimationAnimationId();
|
|
const std::vector<std::string>& groupAnimatioIds = arguments.getGroupAnimationAnimationId();
|
|
|
assert(groupAnimatioNodeIds.size() == groupAnimatioIds.size());
|
|
assert(groupAnimatioNodeIds.size() == groupAnimatioIds.size());
|
|
|
- size_t size = groupAnimatioNodeIds.size();
|
|
|
|
|
- if (size > 0)
|
|
|
|
|
|
|
+ if (!groupAnimatioNodeIds.empty())
|
|
|
{
|
|
{
|
|
|
- begin();
|
|
|
|
|
- for (size_t i = 0; i < size; ++i)
|
|
|
|
|
|
|
+ size_t size = groupAnimatioNodeIds.size();
|
|
|
|
|
+ if (size > 0)
|
|
|
{
|
|
{
|
|
|
- optimizer.combineAnimations(groupAnimatioNodeIds[i], groupAnimatioIds[i]);
|
|
|
|
|
|
|
+ DAEOptimizer optimizer(dom);
|
|
|
|
|
+ begin();
|
|
|
|
|
+ for (size_t i = 0; i < size; ++i)
|
|
|
|
|
+ {
|
|
|
|
|
+ optimizer.combineAnimations(groupAnimatioNodeIds[i], groupAnimatioIds[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ end("groupAnimation");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ // Determine if there are any mesh skins that are animated that have more than 1 animation targeting its joints.
|
|
|
|
|
+ // (candidates for grouping)
|
|
|
|
|
+ std::vector<std::string> nodeIds;
|
|
|
|
|
+ if (findGroupAnimationNodes(dom, nodeIds))
|
|
|
|
|
+ {
|
|
|
|
|
+ // Ask the user if they want to group animations automatically.
|
|
|
|
|
+ if (promptUserGroupAnimations())
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("Grouping animations...\n");
|
|
|
|
|
+
|
|
|
|
|
+ DAEOptimizer optimizer(dom);
|
|
|
|
|
+ begin();
|
|
|
|
|
+ char buffer[20];
|
|
|
|
|
+ size_t size = nodeIds.size();
|
|
|
|
|
+ for (size_t i = 0; i < size; ++i)
|
|
|
|
|
+ {
|
|
|
|
|
+ // In COLLADA, ids must be unique but they don't have to be unique in GPB.
|
|
|
|
|
+ // Save the animation id as "animations___#" and then rename it once the GPB objects are created
|
|
|
|
|
+ // but before the GPB is written to file.
|
|
|
|
|
+ sprintf(buffer, "animations___%d", i);
|
|
|
|
|
+ std::string animationId(buffer);
|
|
|
|
|
+ _tempGroupAnimationIds.push_back(animationId);
|
|
|
|
|
+ optimizer.combineAnimations(nodeIds[i], animationId);
|
|
|
|
|
+ }
|
|
|
|
|
+ end("groupAnimation");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- end("groupAnimation");
|
|
|
|
|
}
|
|
}
|
|
|
if (arguments.DAEOutputEnabled())
|
|
if (arguments.DAEOutputEnabled())
|
|
|
{
|
|
{
|
|
@@ -306,6 +364,7 @@ void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments&
|
|
|
end("loadAnimations");
|
|
end("loadAnimations");
|
|
|
|
|
|
|
|
_gamePlayFile.adjust();
|
|
_gamePlayFile.adjust();
|
|
|
|
|
+ _gamePlayFile.renameAnimations(_tempGroupAnimationIds, "animations");
|
|
|
|
|
|
|
|
// Write the output file
|
|
// Write the output file
|
|
|
std::string outputFilePath = arguments.getOutputFilePath();
|
|
std::string outputFilePath = arguments.getOutputFilePath();
|
|
@@ -626,7 +685,7 @@ bool DAESceneEncoder::loadTarget(const domChannelRef& channelRef, AnimationChann
|
|
|
}
|
|
}
|
|
|
else if (type == domMatrix::ID())
|
|
else if (type == domMatrix::ID())
|
|
|
{
|
|
{
|
|
|
- // If the animation is targetting a matrix then convert it into
|
|
|
|
|
|
|
+ // If the animation is targeting a matrix then convert it into
|
|
|
// a scale, rotate, translate animation by decomposing the matrix.
|
|
// a scale, rotate, translate animation by decomposing the matrix.
|
|
|
targetProperty = Transform::ANIMATE_SCALE_ROTATE_TRANSLATE;
|
|
targetProperty = Transform::ANIMATE_SCALE_ROTATE_TRANSLATE;
|
|
|
|
|
|
|
@@ -1333,7 +1392,7 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
|
|
|
std::vector<std::string> list;
|
|
std::vector<std::string> list;
|
|
|
getJointNames(source, list);
|
|
getJointNames(source, list);
|
|
|
|
|
|
|
|
- // Go through the joint list and conver them from sid to id because the sid information is
|
|
|
|
|
|
|
+ // Go through the joint list and convert them from sid to id because the sid information is
|
|
|
// lost when converting to the gameplay binary format.
|
|
// lost when converting to the gameplay binary format.
|
|
|
for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); i++)
|
|
for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); i++)
|
|
|
{
|
|
{
|