Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[submodule "dependencies/OpenCOLLADA/OpenCOLLADA"]
path = dependencies/OpenCOLLADA/OpenCOLLADA
url = https://github.com/KhronosGroup/OpenCOLLADA.git
url = https://github.com/COLLADA2GLTF/OpenCOLLADA.git
[submodule "dependencies/rapidjson"]
path = GLTF/dependencies/rapidjson
url = https://github.com/miloyip/rapidjson.git
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Change Log
##### Additions :tada:
* Added support for morph targets [#166](https://github.com/KhronosGroup/COLLADA2GLTF/issues/166)
* Support converting models with transparency [#168](https://github.com/KhronosGroup/COLLADA2GLTF/issues/168)
* Added support for exporting COLLADA animation clips as groups [#227](https://github.com/KhronosGroup/COLLADA2GLTF/pull/227)

### v2.1.4 - 2018-08-29

Expand Down
1 change: 1 addition & 0 deletions GLTF/include/GLTFAsset.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ namespace GLTF {
std::vector<GLTF::Image*> getAllImages();
std::vector<GLTF::Accessor*> getAllPrimitiveAccessors(GLTF::Primitive* primitive) const;
void mergeAnimations();
void mergeAnimations(std::vector<std::vector<size_t>> groups);
void removeUnusedSemantics();
void removeUnusedNodes(GLTF::Options* options);
GLTF::Buffer* packAccessors();
Expand Down
51 changes: 44 additions & 7 deletions GLTF/src/GLTFAsset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,20 +378,57 @@ std::vector<GLTF::BufferView*> GLTF::Asset::getAllCompressedBufferView() {
}

void GLTF::Asset::mergeAnimations() {
return this->mergeAnimations(std::vector<std::vector<size_t>>());
}

void GLTF::Asset::mergeAnimations(std::vector<std::vector<size_t>> groups) {
if (animations.size() == 0) { return; }

GLTF::Animation* mergedAnimation = new GLTF::Animation();
std::vector<GLTF::Animation*> mergedAnimations;

// Merge all animations. In the future, animations should be grouped
// according to COLLADA <animation_clip/> nodes.
for (GLTF::Animation* animation : animations) {
for (GLTF::Animation::Channel* channel : animation->channels) {
mergedAnimation->channels.push_back(channel);
// Keep track of which animations we've written
std::set<size_t> animationIndexes;
for (size_t i = 0; i < animations.size(); i++) {
animationIndexes.insert(i);
}

// Merge animations by the specified groups
for (std::vector<size_t> group : groups) {
if (group.size() == 0) { continue; }

GLTF::Animation* mergedAnimation = new GLTF::Animation();
for (size_t index : group) {
GLTF::Animation* animation = animations[index];
if (mergedAnimation->name == "") {
mergedAnimation->name = animation->name;
}
animationIndexes.erase(index);
for (GLTF::Animation::Channel* channel : animation->channels) {
mergedAnimation->channels.push_back(channel);
}
mergedAnimations.push_back(mergedAnimation);
}
}

// Merge any leftovers
if (animationIndexes.size() > 0) {
GLTF::Animation* mergedAnimation = new GLTF::Animation();
for (size_t index : animationIndexes) {
GLTF::Animation* animation = animations[index];
if (mergedAnimation->name == "") {
mergedAnimation->name = animation->name;
}
for (GLTF::Animation::Channel* channel : animation->channels) {
mergedAnimation->channels.push_back(channel);
}
mergedAnimations.push_back(mergedAnimation);
}
}

animations.clear();
animations.push_back(mergedAnimation);
for (GLTF::Animation* animation : mergedAnimations) {
animations.push_back(animation);
}
}

void GLTF::Asset::removeUncompressedBufferViews() {
Expand Down
2 changes: 1 addition & 1 deletion dependencies/OpenCOLLADA/OpenCOLLADA
Submodule OpenCOLLADA updated 40 files
+1 −0 CODE_OF_CONDUCT.md
+2 −2 COLLADABaseUtils/src/COLLADABUNativeString.cpp
+17 −13 COLLADABaseUtils/src/COLLADABUUtils.cpp
+2 −0 COLLADAFramework/CMakeLists.txt
+1 −0 COLLADAFramework/include/COLLADAFW.h
+57 −0 COLLADAFramework/include/COLLADAFWAnimationClip.h
+5 −0 COLLADAFramework/include/COLLADAFWIWriter.h
+2 −0 COLLADAFramework/scripts/COLLADAFramework.vcxproj
+6 −0 COLLADAFramework/scripts/COLLADAFramework.vcxproj.filters
+19 −0 COLLADAFramework/src/COLLADAFWAnimationClip.cpp
+234 −7 COLLADAMax/COLLADAMax.sln
+4 −0 COLLADAMax/include/COLLADAMaxDocumentImporter.h
+7 −0 COLLADAMax/include/COLLADAMaxPrerequisites.h
+2 −0 COLLADAMax/include/COLLADAMaxStableHeaders.h
+546 −13 COLLADAMax/scripts/COLLADAMax.vcxproj
+4 −1 COLLADAMax/src/COLLADAMaxGeometryExporter.cpp
+33 −1 COLLADAMaya/COLLADAMaya.xcodeproj/project.pbxproj
+6 −0 COLLADASaxFrameworkLoader/CMakeLists.txt
+28 −0 COLLADASaxFrameworkLoader/COLLADASaxFrameworkLoader.xcodeproj/project.pbxproj
+71 −0 COLLADASaxFrameworkLoader/include/COLLADASaxFWLLibraryAnimationClipsLoader.h
+2 −1 COLLADASaxFrameworkLoader/include/COLLADASaxFWLLoader.h
+3 −0 COLLADASaxFrameworkLoader/include/COLLADASaxFWLRootParser14.h
+3 −0 COLLADASaxFrameworkLoader/include/COLLADASaxFWLRootParser15.h
+15 −0 COLLADASaxFrameworkLoader/include/COLLADASaxFWLXmlTypes.h
+45 −0 COLLADASaxFrameworkLoader/include/generated14/COLLADASaxFWLLibraryAnimationClipsLoader14.h
+45 −0 COLLADASaxFrameworkLoader/include/generated15/COLLADASaxFWLLibraryAnimationClipsLoader15.h
+6 −158 COLLADASaxFrameworkLoader/scripts/COLLADASaxFrameworkLoader.vcxproj
+18 −0 COLLADASaxFrameworkLoader/scripts/COLLADASaxFrameworkLoader.vcxproj.filters
+95 −0 COLLADASaxFrameworkLoader/src/COLLADASaxFWLLibraryAnimationClipsLoader.cpp
+1 −1 COLLADASaxFrameworkLoader/src/COLLADASaxFWLLibraryAnimationsLoader.cpp
+9 −0 COLLADASaxFrameworkLoader/src/COLLADASaxFWLRootParser14.cpp
+9 −0 COLLADASaxFrameworkLoader/src/COLLADASaxFWLRootParser15.cpp
+54 −0 COLLADASaxFrameworkLoader/src/generated14/COLLADASaxFWLLibraryAnimationClipsLoader14.cpp
+54 −0 COLLADASaxFrameworkLoader/src/generated15/COLLADASaxFWLLibraryAnimationClipsLoader15.cpp
+7 −0 COLLADAValidator/include/Writer.h
+1 −1 GeneratedSaxParser/include/GeneratedSaxParserPrerequisites.h
+0 −166 common/libftoa/scripts/libftoa.vcxproj
+4 −0 dae23ds/include/DAE23dsWriter.h
+4 −0 dae2ma/include/DAE2MADocumentImporter.h
+4 −0 dae2ogre/include/DAE2OgreOgreWriter.h
21 changes: 17 additions & 4 deletions include/COLLADA2GLTFWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace COLLADA2GLTF {
class Writer : public COLLADAFW::IWriter {
private:
COLLADASaxFWL::Loader* _loader;
GLTF::Asset* _asset;
COLLADA2GLTF::Options* _options;
COLLADA2GLTF::ExtrasHandler* _extrasHandler;
Expand All @@ -24,6 +25,7 @@ namespace COLLADA2GLTF {
std::map<COLLADAFW::UniqueId, GLTF::Camera*> _cameraInstances;
std::map<COLLADAFW::UniqueId, GLTF::Mesh*> _meshInstances;
std::map<COLLADAFW::UniqueId, GLTF::Node*> _nodeInstances;
std::map<COLLADAFW::UniqueId, GLTF::Animation*> _animationInstances;
std::map<COLLADAFW::UniqueId, std::vector<GLTF::Node*>> _nodeInstanceTargets;
std::map<COLLADAFW::UniqueId, std::map<int, std::set<GLTF::Primitive*>>> _meshMaterialPrimitiveMapping;
std::map<COLLADAFW::UniqueId, GLTF::MaterialCommon::Light*> _lightInstances;
Expand All @@ -41,18 +43,25 @@ namespace COLLADA2GLTF {
std::map<COLLADAFW::UniqueId, std::tuple<std::vector<float>, std::vector<float>>> _animationData;
std::map<COLLADAFW::UniqueId, std::map<std::string, GLTF::Texture*>> _effectTextureMapping;
std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> _meshMorphTargets;
std::map<std::string, std::vector<COLLADAFW::UniqueId>> _animationClips;

bool writeNodeToGroup(std::vector<GLTF::Node*>* group, const COLLADAFW::Node* node);
bool writeNodesToGroup(std::vector<GLTF::Node*>* group, const COLLADAFW::NodePointerArray& nodes);
GLTF::Texture* fromColladaTexture(const COLLADAFW::EffectCommon* effectCommon, COLLADAFW::SamplerID samplerId);
GLTF::Texture* fromColladaTexture(const COLLADAFW::EffectCommon* effectCommon, COLLADAFW::Texture texture);

public:
Writer(GLTF::Asset* asset, COLLADA2GLTF::Options* options, COLLADA2GLTF::ExtrasHandler* handler);
Writer(COLLADASaxFWL::Loader* loader, GLTF::Asset* asset, COLLADA2GLTF::Options* options, COLLADA2GLTF::ExtrasHandler* handler);

/** Deletes the entire scene.
@param errorMessage A message containing informations about the error that occurred.
*/
/**
* Get animation groupings (from animation clips) by index.
*/
std::vector<std::vector<size_t>> getAnimationGroups();

/**
* Deletes the entire scene.
* @param errorMessage A message containing informations about the error that occurred.
*/
void cancel(const std::string& errorMessage);

/** Prepare to receive data.*/
Expand Down Expand Up @@ -107,6 +116,10 @@ namespace COLLADA2GLTF {
@return True on succeeded, false otherwise.*/
virtual bool writeAnimation(const COLLADAFW::Animation* animation);

/** Writes the animation clip.
@return True on succeeded, false otherwise.*/
virtual bool writeAnimationClip(const COLLADAFW::AnimationClip* animationClip);

/** Writes the animation.
@return True on succeeded, false otherwise.*/
virtual bool writeAnimationList(const COLLADAFW::AnimationList* animationList);
Expand Down
68 changes: 67 additions & 1 deletion src/COLLADA2GLTFWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,28 @@

const double PI = 3.14159;

COLLADA2GLTF::Writer::Writer(GLTF::Asset* asset, COLLADA2GLTF::Options* options, COLLADA2GLTF::ExtrasHandler* extrasHandler) : _asset(asset), _options(options), _extrasHandler(extrasHandler) {}
COLLADA2GLTF::Writer::Writer(COLLADASaxFWL::Loader* loader, GLTF::Asset* asset, COLLADA2GLTF::Options* options, COLLADA2GLTF::ExtrasHandler* extrasHandler) : _loader(loader), _asset(asset), _options(options), _extrasHandler(extrasHandler) {}

std::vector<std::vector<size_t>> COLLADA2GLTF::Writer::getAnimationGroups() {
std::map<GLTF::Animation*, size_t> animationIndexes;
for (size_t i = 0; i < _asset->animations.size(); i++) {
animationIndexes[_asset->animations[i]] = i;
}

std::vector<std::vector<size_t>> groups;
for (const auto& clip : _animationClips) {
std::vector<size_t> group;
for (COLLADAFW::UniqueId id : clip.second) {
GLTF::Animation* animation = _animationInstances[id];
if (animation) {
animation->name = clip.first;
group.push_back(animationIndexes[animation]);
}
}
groups.push_back(group);
}
return groups;
}

void COLLADA2GLTF::Writer::cancel(const std::string& errorMessage) {

Expand Down Expand Up @@ -1311,6 +1332,46 @@ void interpolateTranslation(float* base, std::vector<float> input, std::vector<f
translationOut[offset] = (float)value;
}

/**
* Read the <COLLADAFW::AnimationClip> and store its animation group
* associations.
*
* Currently, animations that target the same node cannot be split apart by
* animation clip. This is because COLLADA animations often target for example,
* X, Y, and Z translations as seperate animations and we flatten them together
* because glTF doesn't have the ability to target these channels seperately
* and it would take 3x the space to store them.
*
* This is also done because in practice, animations targetting nodes are
* usually intended to be run together, and if two animations target the
* same node, it is unclear what order their transforms should be applied in
* if there are overlapping keyframes in the animations. To avoid this
* potentially undefined case, node affinity trumps animation clip groups.
*
* However, you could imagine the case (game assets, etc.) where a skinned
* figure has multiple different animations representing different actions
* to be taken. The current animation approach does not handle this, and I
* think it would have to be done as a COLLADA2GLTF::Options because separating
* these animations is non-trivial. They may not even be grouped by clip,
* so that probably isn't a reliable way to do separation.
*
* @return True on succeeded, false otherwise.
*/
bool COLLADA2GLTF::Writer::writeAnimationClip(const COLLADAFW::AnimationClip* animationClip) {
std::vector<COLLADAFW::UniqueId> animationIds;
const COLLADAFW::UniqueIdArray& instanceAnimationUniqueIds = animationClip->getInstanceAnimationUniqueIds();
for (size_t i = 0; i < instanceAnimationUniqueIds.getCount(); i++) {
const COLLADAFW::UniqueId animationId = instanceAnimationUniqueIds[i];
animationIds.push_back(animationId);
}
std::string name = animationClip->getName();
if (name == "") {
name = "animation_clip_" + std::to_string(_animationClips.size());
}
_animationClips[name] = animationIds;
return true;
}

/**
* Reads a <COLLADAFW::AnimationList> and writes a <GLTF::Animation> object.
*
Expand Down Expand Up @@ -1634,6 +1695,11 @@ bool COLLADA2GLTF::Writer::writeAnimationList(const COLLADAFW::AnimationList* an
channel->sampler = sampler;
animation->channels.push_back(channel);
}
// Map unique ids to the written animation instances
for (size_t i = 0; i < bindings.getCount(); i++) {
const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
_animationInstances[binding.animation] = animation;
}
_asset->animations.push_back(animation);
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,15 @@ int main(int argc, const char **argv) {

COLLADASaxFWL::Loader* loader = new COLLADASaxFWL::Loader();
COLLADA2GLTF::ExtrasHandler* extrasHandler = new COLLADA2GLTF::ExtrasHandler(loader);
COLLADA2GLTF::Writer* writer = new COLLADA2GLTF::Writer(asset, options, extrasHandler);
COLLADA2GLTF::Writer* writer = new COLLADA2GLTF::Writer(loader, asset, options, extrasHandler);
loader->registerExtraDataCallbackHandler((COLLADASaxFWL::IExtraDataCallbackHandler*)extrasHandler);
COLLADAFW::Root root(loader, writer);
if (!root.loadDocument(options->inputPath)) {
std::cout << "ERROR: Unable to load input from path '" << options->inputPath << "'" << std::endl;
return -1;
}

asset->mergeAnimations();
asset->mergeAnimations(writer->getAnimationGroups());
asset->removeUnusedNodes(options);
asset->removeUnusedSemantics();

Expand Down
2 changes: 1 addition & 1 deletion test/src/COLLADA2GLTFWriterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ COLLADA2GLTFWriterTest::COLLADA2GLTFWriterTest() {
options = new COLLADA2GLTF::Options();
COLLADASaxFWL::Loader* loader = new COLLADASaxFWL::Loader();
extrasHandler = new COLLADA2GLTF::ExtrasHandler(loader);
writer = new COLLADA2GLTF::Writer(asset, options, extrasHandler);
writer = new COLLADA2GLTF::Writer(loader, asset, options, extrasHandler);
}

COLLADA2GLTFWriterTest::~COLLADA2GLTFWriterTest() {
Expand Down