From 06861776c5a0a151e908e531a897e466f6df3ab1 Mon Sep 17 00:00:00 2001 From: kearwood Date: Sat, 1 Dec 2012 02:03:18 +0000 Subject: [PATCH] Animation system in progress --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40172 --- KREngine/KREngine.xcodeproj/project.pbxproj | 56 +++ KREngine/KREngine/Classes/KRAnimation.cpp | 68 ++++ KREngine/KREngine/Classes/KRAnimation.h | 38 ++ .../KREngine/Classes/KRAnimationCurve.cpp | 9 + KREngine/KREngine/Classes/KRAnimationCurve.h | 14 + .../KREngine/Classes/KRAnimationLayer.cpp | 154 ++++++++ KREngine/KREngine/Classes/KRAnimationLayer.h | 64 ++++ .../KREngine/Classes/KRAnimationManager.cpp | 42 +++ .../KREngine/Classes/KRAnimationManager.h | 40 ++ KREngine/KREngine/Classes/KRContext.cpp | 10 + KREngine/KREngine/Classes/KRContext.h | 3 + KREngine/KREngine/Classes/KRNode.cpp | 32 +- KREngine/KREngine/Classes/KRQuaternion.cpp | 1 + KREngine/KREngine/Classes/KRResource+fbx.cpp | 351 +++++++++++++----- 14 files changed, 768 insertions(+), 114 deletions(-) create mode 100644 KREngine/KREngine/Classes/KRAnimation.cpp create mode 100644 KREngine/KREngine/Classes/KRAnimation.h create mode 100644 KREngine/KREngine/Classes/KRAnimationCurve.cpp create mode 100644 KREngine/KREngine/Classes/KRAnimationCurve.h create mode 100644 KREngine/KREngine/Classes/KRAnimationLayer.cpp create mode 100644 KREngine/KREngine/Classes/KRAnimationLayer.h create mode 100644 KREngine/KREngine/Classes/KRAnimationManager.cpp create mode 100644 KREngine/KREngine/Classes/KRAnimationManager.h diff --git a/KREngine/KREngine.xcodeproj/project.pbxproj b/KREngine/KREngine.xcodeproj/project.pbxproj index ece8629..51147e5 100644 --- a/KREngine/KREngine.xcodeproj/project.pbxproj +++ b/KREngine/KREngine.xcodeproj/project.pbxproj @@ -17,6 +17,22 @@ E414BAE51435558900A668C4 /* KRInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E414BAE41435558800A668C4 /* KRInstance.cpp */; }; E414BAE7143557D200A668C4 /* KRScene.h in Headers */ = {isa = PBXBuildFile; fileRef = E414BAE6143557D200A668C4 /* KRScene.h */; }; E414BAE91435585A00A668C4 /* KRScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E414BAE81435585A00A668C4 /* KRScene.cpp */; }; + E428C2F21669610500A16EDF /* KRAnimationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E428C2F11669610500A16EDF /* KRAnimationManager.h */; }; + E428C2F31669610500A16EDF /* KRAnimationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E428C2F11669610500A16EDF /* KRAnimationManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E428C2F41669611600A16EDF /* KRAnimationManager.cpp */; }; + E428C2F61669611600A16EDF /* KRAnimationManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E428C2F41669611600A16EDF /* KRAnimationManager.cpp */; }; + E428C2F81669612500A16EDF /* KRAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = E428C2F71669612500A16EDF /* KRAnimation.h */; }; + E428C2F91669612500A16EDF /* KRAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = E428C2F71669612500A16EDF /* KRAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E428C2FA1669613200A16EDF /* KRAnimation.cpp */; }; + E428C2FC1669613200A16EDF /* KRAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E428C2FA1669613200A16EDF /* KRAnimation.cpp */; }; + E428C3041669627900A16EDF /* KRAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = E428C3031669627900A16EDF /* KRAnimationCurve.h */; }; + E428C3051669627900A16EDF /* KRAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = E428C3031669627900A16EDF /* KRAnimationCurve.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E428C3061669628A00A16EDF /* KRAnimationCurve.cpp */; }; + E428C3081669628A00A16EDF /* KRAnimationCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E428C3061669628A00A16EDF /* KRAnimationCurve.cpp */; }; + E428C311166971FF00A16EDF /* KRAnimationLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = E428C30F166971FE00A16EDF /* KRAnimationLayer.h */; }; + E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = E428C30F166971FE00A16EDF /* KRAnimationLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E428C313166971FF00A16EDF /* KRAnimationLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E428C310166971FE00A16EDF /* KRAnimationLayer.cpp */; }; + E428C314166971FF00A16EDF /* KRAnimationLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E428C310166971FE00A16EDF /* KRAnimationLayer.cpp */; }; E42CB1EC158446940066E0D8 /* KRQuaternion.h in Headers */ = {isa = PBXBuildFile; fileRef = E42CB1EB158446940066E0D8 /* KRQuaternion.h */; }; E42CB1ED158446940066E0D8 /* KRQuaternion.h in Headers */ = {isa = PBXBuildFile; fileRef = E42CB1EB158446940066E0D8 /* KRQuaternion.h */; settings = {ATTRIBUTES = (Public, ); }; }; E42CB1F0158446AB0066E0D8 /* KRQuaternion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E42CB1EF158446AB0066E0D8 /* KRQuaternion.cpp */; }; @@ -214,6 +230,14 @@ E414BAE81435585A00A668C4 /* KRScene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = KRScene.cpp; path = Classes/KRScene.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E41B841D16260C5600C7A771 /* sky_box.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = sky_box.fsh; path = Shaders/sky_box.fsh; sourceTree = ""; }; E41B842016260C6500C7A771 /* sky_box.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = sky_box.vsh; path = Shaders/sky_box.vsh; sourceTree = ""; }; + E428C2F11669610500A16EDF /* KRAnimationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRAnimationManager.h; path = Classes/KRAnimationManager.h; sourceTree = ""; }; + E428C2F41669611600A16EDF /* KRAnimationManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRAnimationManager.cpp; path = Classes/KRAnimationManager.cpp; sourceTree = ""; }; + E428C2F71669612500A16EDF /* KRAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRAnimation.h; path = Classes/KRAnimation.h; sourceTree = ""; }; + E428C2FA1669613200A16EDF /* KRAnimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRAnimation.cpp; path = Classes/KRAnimation.cpp; sourceTree = ""; }; + E428C3031669627900A16EDF /* KRAnimationCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRAnimationCurve.h; path = Classes/KRAnimationCurve.h; sourceTree = ""; }; + E428C3061669628A00A16EDF /* KRAnimationCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRAnimationCurve.cpp; path = Classes/KRAnimationCurve.cpp; sourceTree = ""; }; + E428C30F166971FE00A16EDF /* KRAnimationLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRAnimationLayer.h; path = Classes/KRAnimationLayer.h; sourceTree = ""; }; + E428C310166971FE00A16EDF /* KRAnimationLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRAnimationLayer.cpp; path = Classes/KRAnimationLayer.cpp; sourceTree = ""; }; E42CB1EB158446940066E0D8 /* KRQuaternion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRQuaternion.h; path = Classes/KRQuaternion.h; sourceTree = ""; }; E42CB1EF158446AB0066E0D8 /* KRQuaternion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRQuaternion.cpp; path = Classes/KRQuaternion.cpp; sourceTree = ""; }; E430D08015F8882F0010558D /* occlusion_test.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = occlusion_test.fsh; path = Shaders/occlusion_test.fsh; sourceTree = ""; }; @@ -377,6 +401,21 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + E428C2EF166960ED00A16EDF /* Animation */ = { + isa = PBXGroup; + children = ( + E428C30F166971FE00A16EDF /* KRAnimationLayer.h */, + E428C310166971FE00A16EDF /* KRAnimationLayer.cpp */, + E428C2F11669610500A16EDF /* KRAnimationManager.h */, + E428C2F41669611600A16EDF /* KRAnimationManager.cpp */, + E428C2F71669612500A16EDF /* KRAnimation.h */, + E428C2FA1669613200A16EDF /* KRAnimation.cpp */, + E428C3031669627900A16EDF /* KRAnimationCurve.h */, + E428C3061669628A00A16EDF /* KRAnimationCurve.cpp */, + ); + name = Animation; + sourceTree = ""; + }; E4324BA916444DCB0043185B /* Particle Systems */ = { isa = PBXGroup; children = ( @@ -483,6 +522,7 @@ E488399915F92BA300BD66D5 /* Managers */ = { isa = PBXGroup; children = ( + E428C2EF166960ED00A16EDF /* Animation */, E48839AB15F930E200BD66D5 /* Bundle */, E48839AA15F9309E00BD66D5 /* Material */, E48839A915F9307E00BD66D5 /* Model */, @@ -762,6 +802,10 @@ E4324BA416444C0D0043185B /* KRParticleSystem.h in Headers */, E4324BAB16444DEF0043185B /* KRParticleSystemNewtonian.h in Headers */, E460292616681CFF00261BB9 /* KRTextureAnimated.h in Headers */, + E428C2F21669610500A16EDF /* KRAnimationManager.h in Headers */, + E428C2F81669612500A16EDF /* KRAnimation.h in Headers */, + E428C3041669627900A16EDF /* KRAnimationCurve.h in Headers */, + E428C311166971FF00A16EDF /* KRAnimationLayer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -788,18 +832,22 @@ E4F975501536333500FD60B2 /* KRModel.h in Headers */, E488399F15F92BE000BD66D5 /* KRBundleManager.h in Headers */, E4AFC6BC15F7C95D00DDB4C8 /* KRSceneManager.h in Headers */, + E428C2F31669610500A16EDF /* KRAnimationManager.h in Headers */, E4D133661537685A0070068C /* KRShader.h in Headers */, E461A153152E54B500F2044A /* KRLight.h in Headers */, E4F97552153633EF00FD60B2 /* KRMaterialManager.h in Headers */, + E428C2F91669612500A16EDF /* KRAnimation.h in Headers */, E461A176152E5C5600F2044A /* KRPointLight.h in Headers */, E46F4A09155DF6E400CCF8B8 /* KRWorld.cpp in Headers */, E4F975541536340400FD60B2 /* KRTexture2D.h in Headers */, + E428C3051669627900A16EDF /* KRAnimationCurve.h in Headers */, E46F4A01155DF46700CCF8B8 /* KRWorld.h in Headers */, E48C697015374F5B00232E28 /* KRContext.h in Headers */, E46F4A10155E004100CCF8B8 /* KRDataBlock.cpp in Headers */, E46C214815364BC8009CABF3 /* tinyxml2.h in Headers */, E4D13365153767FF0070068C /* KRShaderManager.h in Headers */, E40BA45715EFF79500D7C3DD /* KRAABB.h in Headers */, + E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */, E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */, E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */, E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */, @@ -942,6 +990,10 @@ E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */, E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */, E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */, + E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */, + E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */, + E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */, + E428C313166971FF00A16EDF /* KRAnimationLayer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -992,6 +1044,10 @@ E4CA11791639CC90005D9400 /* KRViewport.cpp in Sources */, E4324BAF16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */, E4324BB0164458930043185B /* KRParticleSystem.cpp in Sources */, + E428C2F61669611600A16EDF /* KRAnimationManager.cpp in Sources */, + E428C2FC1669613200A16EDF /* KRAnimation.cpp in Sources */, + E428C3081669628A00A16EDF /* KRAnimationCurve.cpp in Sources */, + E428C314166971FF00A16EDF /* KRAnimationLayer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/KREngine/KREngine/Classes/KRAnimation.cpp b/KREngine/KREngine/Classes/KRAnimation.cpp new file mode 100644 index 0000000..8456256 --- /dev/null +++ b/KREngine/KREngine/Classes/KRAnimation.cpp @@ -0,0 +1,68 @@ +// +// KRAnimation.cpp +// KREngine +// +// Created by Kearwood Gilbert on 2012-11-30. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#include "KRAnimation.h" +#import "tinyxml2.h" + +KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(context, name) +{ + +} +KRAnimation::~KRAnimation() +{ + for(std::map::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){ + delete (*itr).second; + } +} + +std::string KRAnimation::getExtension() { + return "kranimation"; +} + +void KRAnimation::addLayer(KRAnimationLayer *layer) +{ + m_layers[layer->getName()] = layer; +} + +bool KRAnimation::save(const std::string& path) { + tinyxml2::XMLDocument doc; + tinyxml2::XMLElement *animation_node = doc.NewElement( "animation" ); + doc.InsertEndChild(animation_node); +// m_pRootNode->saveXML(animation_node); + + for(std::map::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){ + (*itr).second->saveXML(animation_node); + } + + doc.SaveFile(path.c_str()); + return true; +} + + +KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDataBlock *data) +{ + data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely + tinyxml2::XMLDocument doc; + doc.Parse((char *)data->getStart()); + KRAnimation *new_animation = new KRAnimation(context, name); + + tinyxml2::XMLElement *animation_node = doc.RootElement(); + + for(tinyxml2::XMLElement *child_element=animation_node->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { + if(strcmp(child_element->Name(), "layer") == 0) { + KRAnimationLayer *new_layer = new KRAnimationLayer(context); + new_animation->m_layers[new_layer->getName()] = new_layer; + } + } + +// KRNode *n = KRNode::LoadXML(*new_scene, scene_element->FirstChildElement()); + + delete data; + return new_animation; +} + diff --git a/KREngine/KREngine/Classes/KRAnimation.h b/KREngine/KREngine/Classes/KRAnimation.h new file mode 100644 index 0000000..8405aae --- /dev/null +++ b/KREngine/KREngine/Classes/KRAnimation.h @@ -0,0 +1,38 @@ +// +// KRAnimation.h +// KREngine +// +// Created by Kearwood Gilbert on 2012-11-30. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#ifndef KRANIMATION_H +#define KRANIMATION_H + +#import "KREngine-common.h" +#import "KRContextObject.h" +#import "KRDataBlock.h" +#import "KRResource.h" +#import "KRAnimationLayer.h" +#import + +class KRAnimation : public KRResource { + +public: + KRAnimation(KRContext &context, std::string name); + virtual ~KRAnimation(); + + virtual std::string getExtension(); + virtual bool save(const std::string& path); + + static KRAnimation *Load(KRContext &context, const std::string &name, KRDataBlock *data); + + void addLayer(KRAnimationLayer *layer); + +private: + std::map m_layers; +}; + + + +#endif diff --git a/KREngine/KREngine/Classes/KRAnimationCurve.cpp b/KREngine/KREngine/Classes/KRAnimationCurve.cpp new file mode 100644 index 0000000..04efb8f --- /dev/null +++ b/KREngine/KREngine/Classes/KRAnimationCurve.cpp @@ -0,0 +1,9 @@ +// +// KRAnimationCurve.cpp +// KREngine +// +// Created by Kearwood Gilbert on 2012-11-30. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#include "KRAnimationCurve.h" diff --git a/KREngine/KREngine/Classes/KRAnimationCurve.h b/KREngine/KREngine/Classes/KRAnimationCurve.h new file mode 100644 index 0000000..1278c5b --- /dev/null +++ b/KREngine/KREngine/Classes/KRAnimationCurve.h @@ -0,0 +1,14 @@ +// +// KRAnimationCurve.h +// KREngine +// +// Created by Kearwood Gilbert on 2012-11-30. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#ifndef KRANIMATIONCURVE_H +#define KRANIMATIONCURVE_H + + + +#endif diff --git a/KREngine/KREngine/Classes/KRAnimationLayer.cpp b/KREngine/KREngine/Classes/KRAnimationLayer.cpp new file mode 100644 index 0000000..dd25e2b --- /dev/null +++ b/KREngine/KREngine/Classes/KRAnimationLayer.cpp @@ -0,0 +1,154 @@ +// +// KRAnimationLayer.cpp +// KREngine +// +// Created by Kearwood Gilbert on 2012-11-30. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#include "KRAnimationLayer.h" + +KRAnimationLayer::KRAnimationLayer(KRContext &context) : KRContextObject(context) +{ + m_name = ""; + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; + m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; + m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE; +} + +KRAnimationLayer::~KRAnimationLayer() +{ + +} + +std::string KRAnimationLayer::getName() const +{ + return m_name; +} + +void KRAnimationLayer::setName(const std::string &name) +{ + m_name = name; +} + +tinyxml2::XMLElement *KRAnimationLayer::saveXML( tinyxml2::XMLNode *parent) +{ + tinyxml2::XMLDocument *doc = parent->GetDocument(); + tinyxml2::XMLElement *e = doc->NewElement("layer"); + tinyxml2::XMLNode *n = parent->InsertEndChild(e); + e->SetAttribute("name", m_name.c_str()); + e->SetAttribute("weight", m_weight); + + switch(m_blend_mode) { + case KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE: + e->SetAttribute("blend_mode", "additive"); + break; + case KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE: + e->SetAttribute("blend_mode", "override"); + break; + case KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH: + e->SetAttribute("blend_mode", "override_passthrough"); + break; + } + + switch(m_rotation_accumulation_mode) { + case KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL: + e->SetAttribute("rotation_accumulation_mode", "by_channel"); + break; + case KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER: + e->SetAttribute("rotation_accumulation_mode", "by_layer"); + break; + } + + switch(m_scale_accumulation_mode) { + case KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE: + e->SetAttribute("scale_accumulation_mode", "additive"); + break; + case KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY: + e->SetAttribute("scale_accumulation_mode", "multiply"); + break; + } + + return e; +} + +void KRAnimationLayer::loadXML(tinyxml2::XMLElement *e) +{ + m_name = e->Attribute("name"); + if(e->QueryFloatAttribute("weight", &m_weight) == tinyxml2::XML_SUCCESS) { + m_weight /= 100.0f; + } else { + m_weight = 1.0f; // default + } + + const char *szBlendMode = e->Attribute("blend_mode"); + if(strcmp(szBlendMode, "additive") == 0) { + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; + } else if(strcmp(szBlendMode, "override") == 0) { + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE; + } else if(strcmp(szBlendMode, "override_passthrough") == 0) { + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH; + } else { + m_blend_mode = KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE; // default + } + + const char *szRotationAccumulationMode = e->Attribute("rotation_accumulation_mode"); + if(strcmp(szRotationAccumulationMode, "by_channel") == 0) { + m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL; + } else if(strcmp(szRotationAccumulationMode, "by_layer") == 0) { + m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; + } else { + m_rotation_accumulation_mode = KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER; // default + } + + const char *szScaleAccumulationMode = e->Attribute("scale_accumulation_mode"); + if(strcmp(szScaleAccumulationMode, "additive") == 0) { + m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE; + } else if(strcmp(szScaleAccumulationMode, "multiply") == 0) { + m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY; + } else { + m_scale_accumulation_mode = KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE; // default + } +} + +float KRAnimationLayer::getWeight() const +{ + return m_weight; +} + +void KRAnimationLayer::setWeight(float weight) +{ + m_weight = weight; +} + + +KRAnimationLayer::blend_mode_t KRAnimationLayer::getBlendMode() const +{ + return m_blend_mode; +} + +void KRAnimationLayer::setBlendMode(const KRAnimationLayer::blend_mode_t &blend_mode) +{ + m_blend_mode = blend_mode; +} + +KRAnimationLayer::rotation_accumulation_mode_t KRAnimationLayer::getRotationAccumulationMode() const +{ + return m_rotation_accumulation_mode; +} + +void KRAnimationLayer::setRotationAccumulationMode(const KRAnimationLayer::rotation_accumulation_mode_t &rotation_accumulation_mode) +{ + m_rotation_accumulation_mode = rotation_accumulation_mode; +} + +KRAnimationLayer::scale_accumulation_mode_t KRAnimationLayer::getScaleAccumulationMode() const +{ + return m_scale_accumulation_mode; +} + +void KRAnimationLayer::setScaleAccumulationMode(const KRAnimationLayer::scale_accumulation_mode_t &scale_accumulation_mode) +{ + m_scale_accumulation_mode = scale_accumulation_mode; +} + diff --git a/KREngine/KREngine/Classes/KRAnimationLayer.h b/KREngine/KREngine/Classes/KRAnimationLayer.h new file mode 100644 index 0000000..f168ed6 --- /dev/null +++ b/KREngine/KREngine/Classes/KRAnimationLayer.h @@ -0,0 +1,64 @@ +// +// KRAnimationLayer.h +// KREngine +// +// Created by Kearwood Gilbert on 2012-11-30. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#ifndef KRANIMATIONLAYER_H +#define KRANIMATIONLAYER_H + +#import "KRContextObject.h" +#import "KREngine-common.h" +#import "tinyxml2.h" + +class KRAnimationLayer : public KRContextObject { +public: + KRAnimationLayer(KRContext &context); + ~KRAnimationLayer(); + + tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); + void loadXML(tinyxml2::XMLElement *e); + + std::string getName() const; + void setName(const std::string &name); + + float getWeight() const; + void setWeight(float weight); + + typedef enum { + KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE, + KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE, + KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH + } blend_mode_t; + + blend_mode_t getBlendMode() const; + void setBlendMode(const blend_mode_t &blend_mode); + + typedef enum { + KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER, + KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL + } rotation_accumulation_mode_t; + + rotation_accumulation_mode_t getRotationAccumulationMode() const; + void setRotationAccumulationMode(const rotation_accumulation_mode_t &rotation_accumulation_mode); + + typedef enum { + KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY, + KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE + } scale_accumulation_mode_t; + + scale_accumulation_mode_t getScaleAccumulationMode() const; + void setScaleAccumulationMode(const scale_accumulation_mode_t &scale_accumulation_mode); + + +private: + std::string m_name; + float m_weight; + blend_mode_t m_blend_mode; + rotation_accumulation_mode_t m_rotation_accumulation_mode; + scale_accumulation_mode_t m_scale_accumulation_mode; +}; + +#endif diff --git a/KREngine/KREngine/Classes/KRAnimationManager.cpp b/KREngine/KREngine/Classes/KRAnimationManager.cpp new file mode 100644 index 0000000..7c4b05d --- /dev/null +++ b/KREngine/KREngine/Classes/KRAnimationManager.cpp @@ -0,0 +1,42 @@ +// +// KRAnimationManager.cpp +// KREngine +// +// Created by Kearwood Gilbert on 2012-11-30. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#include "KRAnimationManager.h" +#include "KRAnimation.h" + +KRAnimationManager::KRAnimationManager(KRContext &context) : KRContextObject(context) +{ + +} + +KRAnimationManager::~KRAnimationManager() { + for(map::iterator itr = m_animations.begin(); itr != m_animations.end(); ++itr){ + delete (*itr).second; + } +} + +void KRAnimationManager::startFrame() +{ + +} + + +KRAnimation *KRAnimationManager::loadAnimation(const char *szName, KRDataBlock *data) { + KRAnimation *pAnimation = KRAnimation::Load(*m_pContext, szName, data); + m_animations[szName] = pAnimation; + return pAnimation; +} + +KRAnimation *KRAnimationManager::getAnimation(const char *szName) { + return m_animations[szName]; +} + +std::map KRAnimationManager::getAnimations() { + return m_animations; +} + diff --git a/KREngine/KREngine/Classes/KRAnimationManager.h b/KREngine/KREngine/Classes/KRAnimationManager.h new file mode 100644 index 0000000..bc7ed53 --- /dev/null +++ b/KREngine/KREngine/Classes/KRAnimationManager.h @@ -0,0 +1,40 @@ +// +// KRAnimationManager.h +// KREngine +// +// Created by Kearwood Gilbert on 2012-11-30. +// Copyright (c) 2012 Kearwood Software. All rights reserved. +// + +#ifndef KRANIMATIONMANAGER_H +#define KRANIMATIONMANAGER_H + +#import "KREngine-common.h" + +#include "KRAnimation.h" +#include "KRContextObject.h" +#include "KRDataBlock.h" + +#include +#import + +using std::map; + +class KRAnimationManager : public KRContextObject { +public: + KRAnimationManager(KRContext &context); + virtual ~KRAnimationManager(); + + KRAnimation *loadAnimation(const char *szName, KRDataBlock *data); + KRAnimation *getAnimation(const char *szName); + std::map getAnimations(); + + void startFrame(); + +private: + map m_animations; +}; + + + +#endif diff --git a/KREngine/KREngine/Classes/KRContext.cpp b/KREngine/KREngine/Classes/KRContext.cpp index 8f3b128..dd4a1e0 100644 --- a/KREngine/KREngine/Classes/KRContext.cpp +++ b/KREngine/KREngine/Classes/KRContext.cpp @@ -33,6 +33,7 @@ KRContext::KRContext() { m_pMaterialManager = new KRMaterialManager(*this, m_pTextureManager, m_pShaderManager); m_pModelManager = new KRModelManager(*this); m_pSceneManager = new KRSceneManager(*this); + m_pAnimationManager = new KRAnimationManager(*this); m_bDetectedExtensions = false; m_current_frame = 0; m_absolute_time = 0.0f; @@ -65,6 +66,11 @@ KRContext::~KRContext() { m_pShaderManager = NULL; } + if(m_pAnimationManager) { + delete m_pAnimationManager; + m_pAnimationManager = NULL; + } + // The bundles must be destroyed last, as the other objects may be using mmap'ed data from bundles if(m_pBundleManager) { delete m_pBundleManager; @@ -90,6 +96,9 @@ KRShaderManager *KRContext::getShaderManager() { KRModelManager *KRContext::getModelManager() { return m_pModelManager; } +KRAnimationManager *KRContext::getAnimationManager() { + return m_pAnimationManager; +} void KRContext::loadResource(const std::string &file_name, KRDataBlock *data) { std::string name = KRResource::GetFileBase(file_name); @@ -146,6 +155,7 @@ void KRContext::detectExtensions() { void KRContext::startFrame() { m_pTextureManager->startFrame(); + m_pAnimationManager->startFrame(); } void KRContext::endFrame(float deltaTime) diff --git a/KREngine/KREngine/Classes/KRContext.h b/KREngine/KREngine/Classes/KRContext.h index 2b407be..a00c23a 100644 --- a/KREngine/KREngine/Classes/KRContext.h +++ b/KREngine/KREngine/Classes/KRContext.h @@ -16,6 +16,7 @@ #import "KRMaterialManager.h" #import "KRShaderManager.h" #import "KRModelManager.h" +#import "KRAnimationManager.h" class KRContext { public: @@ -43,6 +44,7 @@ public: KRMaterialManager *getMaterialManager(); KRShaderManager *getShaderManager(); KRModelManager *getModelManager(); + KRAnimationManager *getAnimationManager(); KRCamera *createCamera(int width, int height); @@ -69,6 +71,7 @@ private: KRMaterialManager *m_pMaterialManager; KRShaderManager *m_pShaderManager; KRModelManager *m_pModelManager; + KRAnimationManager *m_pAnimationManager; void detectExtensions(); bool m_bDetectedExtensions; diff --git a/KREngine/KREngine/Classes/KRNode.cpp b/KREngine/KREngine/Classes/KRNode.cpp index a7e6c01..4830c00 100644 --- a/KREngine/KREngine/Classes/KRNode.cpp +++ b/KREngine/KREngine/Classes/KRNode.cpp @@ -212,23 +212,27 @@ const KRMat4 &KRNode::getModelMatrix() if(!m_modelMatrixValid) { m_modelMatrix = KRMat4(); - if(m_parentNode) { - m_modelMatrix *= m_parentNode->getModelMatrix(); - } - m_modelMatrix.translate(m_localTranslation); - m_modelMatrix.rotate(KRQuaternion(m_localRotation)); - m_modelMatrix.scale(m_localScale); - -// m_modelMatrix = KRMat4(); -// -// m_modelMatrix.scale(m_localScale); -// m_modelMatrix.rotate(KRQuaternion(m_localRotation)); -// m_modelMatrix.translate(m_localTranslation); -// + // if(m_parentNode) { // m_modelMatrix *= m_parentNode->getModelMatrix(); // } -// +// m_modelMatrix.translate(m_localTranslation); +// m_modelMatrix.rotate(m_localRotation.x, X_AXIS); +// m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); +// m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); +// m_modelMatrix.scale(m_localScale); + + + m_modelMatrix.scale(m_localScale); + m_modelMatrix.rotate(m_localRotation.x, X_AXIS); + m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); + m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); + m_modelMatrix.translate(m_localTranslation); + + if(m_parentNode) { + m_modelMatrix *= m_parentNode->getModelMatrix(); + } + m_modelMatrixValid = true; } diff --git a/KREngine/KREngine/Classes/KRQuaternion.cpp b/KREngine/KREngine/Classes/KRQuaternion.cpp index 8a383bc..47a3c7b 100644 --- a/KREngine/KREngine/Classes/KRQuaternion.cpp +++ b/KREngine/KREngine/Classes/KRQuaternion.cpp @@ -80,6 +80,7 @@ KRQuaternion::~KRQuaternion() { } void KRQuaternion::setEuler(const KRVector3 &euler) { + // ZYX Order! m_val[0] = cos(euler[0] / 2.0) * cos(euler[1] / 2.0) * cos(euler[2] / 2.0) + sin(euler[0] / 2.0) * sin(euler[1] / 2.0) * sin(euler[2] / 2.0); m_val[1] = sin(euler[0] / 2.0) * cos(euler[1] / 2.0) * cos(euler[2] / 2.0) - cos(euler[0] / 2.0) * sin(euler[1] / 2.0) * sin(euler[2] / 2.0); m_val[2] = cos(euler[0] / 2.0) * sin(euler[1] / 2.0) * cos(euler[2] / 2.0) + sin(euler[0] / 2.0) * cos(euler[1] / 2.0) * sin(euler[2] / 2.0); diff --git a/KREngine/KREngine/Classes/KRResource+fbx.cpp b/KREngine/KREngine/Classes/KRResource+fbx.cpp index 888d98a..b92b1f5 100644 --- a/KREngine/KREngine/Classes/KRResource+fbx.cpp +++ b/KREngine/KREngine/Classes/KRResource+fbx.cpp @@ -40,8 +40,10 @@ void InitializeSdkObjects(KFbxSdkManager*& pSdkManager, KFbxScene*& pScene); void DestroySdkObjects(KFbxSdkManager* pSdkManager); bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pFilename); +KRAnimation *LoadAnimation(KRContext &context, FbxAnimStack* pAnimStack); +KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer); void LoadNode(KRNode *parent_node, std::vector &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); -void BakeNode(KFbxNode* pNode); +//void BakeNode(KFbxNode* pNode); KRNode *LoadMesh(KRNode *parent_node, std::vector &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); KRNode *LoadLight(KRNode *parent_node, std::vector &resources, KFbxNode* pNode); @@ -54,8 +56,6 @@ std::vector KRResource::LoadFbx(KRContext &context, const std::str KRScene *pScene = new KRScene(context, KRResource::GetFileBase(path)); resources.push_back(pScene); - - KFbxSdkManager* lSdkManager = NULL; KFbxScene* pFbxScene = NULL; bool lResult; @@ -70,20 +70,31 @@ std::vector KRResource::LoadFbx(KRContext &context, const std::str // Load the scene. lResult = LoadScene(lSdkManager, pFbxScene, path.c_str()); + // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- - // ----====---- Walk Through Scene ----====---- - - int i; + printf("Baking pivots...\n"); KFbxNode* pNode = pFbxScene->GetRootNode(); + if(pNode) { + pNode->ResetPivotSetAndConvertAnimation(); + } + // ----====---- Import Scene Graph Nodes ----====---- if(pNode) { - for(i = 0; i < pNode->GetChildCount(); i++) + for(int i = 0; i < pNode->GetChildCount(); i++) { LoadNode(pScene->getRootNode(), resources, pGeometryConverter, pNode->GetChild(i)); } } + // ----====---- Import Animations ----====---- + + int animation_count = pFbxScene->GetSrcObjectCount(FBX_TYPE(FbxAnimStack)); + for(int i = 0; i < animation_count; i++) { +// FbxAnimStack* pAnimStack = FbxCast(pFbxScene->GetSrcObject(FBX_TYPE(FbxAnimStack), i)); + resources.push_back(LoadAnimation(context, pFbxScene->GetSrcObject(i))); + } + DestroySdkObjects(lSdkManager); return resources; @@ -137,7 +148,7 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF int lFileMajor, lFileMinor, lFileRevision; int lSDKMajor, lSDKMinor, lSDKRevision; //int lFileFormat = -1; - int i, lAnimStackCount; + int lAnimStackCount; bool lStatus; char lPassword[1024]; @@ -187,23 +198,6 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF printf(" Current Animation Stack: \"%s\"\n", lImporter->GetActiveAnimStackName().Buffer()); printf("\n"); - for(i = 0; i < lAnimStackCount; i++) - { - KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); - - printf(" Animation Stack %d\n", i); - printf(" Name: \"%s\"\n", lTakeInfo->mName.Buffer()); - printf(" Description: \"%s\"\n", lTakeInfo->mDescription.Buffer()); - - // Change the value of the import name if the animation stack should be imported - // under a different name. - printf(" Import Name: \"%s\"\n", lTakeInfo->mImportName.Buffer()); - - // Set the value of the import state to false if the animation stack should be not - // be imported. - printf(" Import State: %s\n", lTakeInfo->mSelect ? "true" : "false"); - printf("\n"); - } // Set the import states. By default, the import states are always set to // true. The code below shows how to change these states. @@ -238,23 +232,34 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF } } - // ----====---- Start: Bake pivots into transforms, as Kraken doesn't support them directly ----====---- - - printf("Baking pivots...\n"); - KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode(); -// BakeNode(pNode); - - for(i = 0; i < lAnimStackCount; i++) - { - KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); - - printf(" Animation: \"%s\"\n", lTakeInfo->mName.Buffer()); -// pNode->ConvertPivotAnimationRecursive(lTakeInfo->mName.Buffer(), KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE); - pNode->ResetPivotSetAndConvertAnimation(); - pNode->UpdatePropertiesFromPivotsAndLimits(); - } - - // ----====---- End: Bake pivots into transforms, as Kraken doesn't support them directly ----====---- +// // ----====---- Start: Bake pivots into transforms, as Kraken doesn't support them directly ----====---- +// +// printf("Baking pivots...\n"); +// KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode(); +//// BakeNode(pNode); +// +// for(i = 0; i < lAnimStackCount; i++) +// { +// KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); +// +// printf(" Animation: \"%s\"\n", lTakeInfo->mName.Buffer()); +// +// //pNode->ConvertPivotAnimationRecursive(lTakeInfo->mName.Buffer(), KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE); +// pNode->ResetPivotSetAndConvertAnimation(); +// +// } +//// pNode->ConvertPivotAnimationRecursive(NULL, KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE); +//// pNode->UpdatePropertiesFromPivotsAndLimits(); +// +// // ----====---- End: Bake pivots into transforms, as Kraken doesn't support them directly ----====---- + +// // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- +// +// printf("Baking pivots...\n"); +// KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode(); +// if(pNode) { +// pNode->ResetPivotSetAndConvertAnimation(); +// } // Destroy the importer. lImporter->Destroy(); @@ -262,52 +267,181 @@ bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pF return lStatus; } -void BakeNode(KFbxNode *pNode) { - pNode->SetPivotState(KFbxNode::eSourcePivot, KFbxNode::ePivotActive); - pNode->SetPivotState(KFbxNode::eDestinationPivot, KFbxNode::ePivotActive); +KRAnimation *LoadAnimation(KRContext &context, FbxAnimStack* pAnimStack) +{ - // Pass the current value to the source pivot. -// * - Rotation offset (Roff) -// * - Rotation pivot (Rp) -// * - Pre-rotation (Rpre) -// * - Post-rotation (Rpost) -// * - Scaling offset (Soff) -// * - Scaling pivot (Sp) -// * - Geometric translation (Gt) -// * - Geometric rotation (Gr) -// * - Geometric scaling (Gs) - pNode->SetPostRotation(KFbxNode::eSourcePivot, pNode->PostRotation.Get()); - pNode->SetPreRotation(KFbxNode::eSourcePivot, pNode->PreRotation.Get()); - pNode->SetRotationOffset(KFbxNode::eSourcePivot, pNode->RotationOffset.Get()); - pNode->SetScalingOffset(KFbxNode::eSourcePivot, pNode->ScalingOffset.Get()); - pNode->SetRotationPivot(KFbxNode::eSourcePivot, pNode->RotationPivot.Get()); - pNode->SetScalingPivot(KFbxNode::eSourcePivot, pNode->ScalingPivot.Get()); - pNode->SetGeometricRotation(KFbxNode::eSourcePivot, pNode->GeometricRotation.Get()); - pNode->SetGeometricTranslation(KFbxNode::eSourcePivot, pNode->GeometricTranslation.Get()); - pNode->SetGeometricScaling(KFbxNode::eSourcePivot, pNode->GeometricScaling.Get()); - pNode->SetRotationOrder(KFbxNode::eSourcePivot, pNode->RotationOrder.Get()); - // We want to set all these to 0 and bake them into the transforms. - KFbxVector4 lZero(0, 0, 0); - KFbxVector4 lOne(1.0, 1.0, 1.0); - pNode->SetPostRotation(KFbxNode::eDestinationPivot, lZero); - pNode->SetPreRotation(KFbxNode::eDestinationPivot, lZero); - pNode->SetRotationOffset(KFbxNode::eDestinationPivot, lZero); - pNode->SetScalingOffset(KFbxNode::eDestinationPivot, lZero); - pNode->SetRotationPivot(KFbxNode::eDestinationPivot, lZero); - pNode->SetScalingPivot(KFbxNode::eDestinationPivot, lZero); - pNode->SetGeometricRotation(KFbxNode::eDestinationPivot, lZero); - pNode->SetGeometricTranslation(KFbxNode::eDestinationPivot, lZero); - pNode->SetGeometricScaling(KFbxNode::eDestinationPivot, lOne); - pNode->SetRotationOrder(KFbxNode::eDestinationPivot, eEULER_XYZ); - - // Bake child nodes - for(int i = 0; i < pNode->GetChildCount(); i++) - { - BakeNode(pNode->GetChild(i)); + printf("Loading animation: \"%s\"\n", pAnimStack->GetName()); + + KRAnimation *new_animation = new KRAnimation(context, pAnimStack->GetName()); + int cLayers = pAnimStack->GetMemberCount(); + for(int iLayer=0; iLayer < cLayers; iLayer++) { + new_animation->addLayer(LoadAnimationLayer(context, pAnimStack->GetMember(iLayer))); } + return new_animation; } + +KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer) +{ + KRAnimationLayer *new_layer = new KRAnimationLayer(context); + new_layer->setName(pAnimLayer->GetName()); + new_layer->setWeight(pAnimLayer->Weight.Get()); + switch(pAnimLayer->BlendMode.Get()) { + case FbxAnimLayer::eBlendAdditive: + new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE); + break; + case FbxAnimLayer::eBlendOverride: + new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE); + break; + case FbxAnimLayer::eBlendOverridePassthrough: + new_layer->setBlendMode(KRAnimationLayer::KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH); + break; + } + switch(pAnimLayer->RotationAccumulationMode.Get()) { + case FbxAnimLayer::eRotationByLayer: + new_layer->setRotationAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER); + break; + case FbxAnimLayer::eRotationByChannel: + new_layer->setRotationAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL); + break; + } + switch(pAnimLayer->ScaleAccumulationMode.Get()) { + case FbxAnimLayer::eScaleAdditive: + new_layer->setScaleAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE); + break; + case FbxAnimLayer::eScaleMultiply: + new_layer->setScaleAccumulationMode(KRAnimationLayer::KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY); + break; + } + return new_layer; +} +// +//void BakeNode(KFbxNode *pNode) { +// +// pNode->SetPivotState(KFbxNode::eSourcePivot, KFbxNode::ePivotActive); +// pNode->SetPivotState(KFbxNode::eDestinationPivot, KFbxNode::ePivotActive); +// +// // Pass the current value to the source pivot. +//// * - Rotation offset (Roff) +//// * - Rotation pivot (Rp) +//// * - Pre-rotation (Rpre) +//// * - Post-rotation (Rpost) +//// * - Scaling offset (Soff) +//// * - Scaling pivot (Sp) +//// * - Geometric translation (Gt) +//// * - Geometric rotation (Gr) +//// * - Geometric scaling (Gs) +// /* +// pNode->SetPostRotation(KFbxNode::eSourcePivot, pNode->PostRotation.Get()); +// pNode->SetPreRotation(KFbxNode::eSourcePivot, pNode->PreRotation.Get()); +// pNode->SetRotationOffset(KFbxNode::eSourcePivot, pNode->RotationOffset.Get()); +// pNode->SetScalingOffset(KFbxNode::eSourcePivot, pNode->ScalingOffset.Get()); +// pNode->SetRotationPivot(KFbxNode::eSourcePivot, pNode->RotationPivot.Get()); +// pNode->SetScalingPivot(KFbxNode::eSourcePivot, pNode->ScalingPivot.Get()); +// pNode->SetGeometricRotation(KFbxNode::eSourcePivot, pNode->GeometricRotation.Get()); +// pNode->SetGeometricTranslation(KFbxNode::eSourcePivot, pNode->GeometricTranslation.Get()); +// pNode->SetGeometricScaling(KFbxNode::eSourcePivot, pNode->GeometricScaling.Get()); +// pNode->SetRotationOrder(KFbxNode::eSourcePivot, pNode->RotationOrder.Get()); +// */ +// +// // We want to set all these to 0 and bake them into the transforms. +// KFbxVector4 lZero(0.0, 0.0, 0.0); +// KFbxVector4 lOne(1.0, 1.0, 1.0); +// pNode->SetPostRotation(KFbxNode::eDestinationPivot, lZero); +// pNode->SetPreRotation(KFbxNode::eDestinationPivot, lZero); +// pNode->SetRotationOffset(KFbxNode::eDestinationPivot, lZero); +// pNode->SetScalingOffset(KFbxNode::eDestinationPivot, lZero); +// pNode->SetRotationPivot(KFbxNode::eDestinationPivot, lZero); +// pNode->SetScalingPivot(KFbxNode::eDestinationPivot, lZero); +// pNode->SetGeometricRotation(KFbxNode::eDestinationPivot, lZero); +// pNode->SetGeometricTranslation(KFbxNode::eDestinationPivot, lZero); +// pNode->SetGeometricScaling(KFbxNode::eDestinationPivot, lOne); +// pNode->SetRotationOrder(KFbxNode::eDestinationPivot, eEULER_XYZ); +// +// +// /* +// FbxVector4 lZero(0,0,0); +// FbxVector4 lOne(1,1,1); +// pNode->SetPivotState(FbxNode::eSourcePivot, FbxNode::ePivotActive); +// pNode->SetPivotState(FbxNode::eDestinationPivot, FbxNode::ePivotActive); +// +// EFbxRotationOrder lRotationOrder; +// pNode->GetRotationOrder(FbxNode::eSourcePivot , lRotationOrder); +// pNode->SetRotationOrder(FbxNode::eDestinationPivot , lRotationOrder); +// +// //For cameras and lights (without targets) let's compensate the postrotation. +// if( pNode->GetCamera() || pNode->GetLight() ) +// { +// if( !pNode->GetTarget() ) +// { +// FbxVector4 lRV(90, 0, 0); +// if( pNode->GetCamera() ) +// lRV.Set(0, 90, 0); +// +// FbxVector4 prV = pNode->GetPostRotation(FbxNode::eSourcePivot); +// FbxAMatrix lSourceR; +// FbxAMatrix lR(lZero, lRV, lOne); +// FbxVector4 res = prV; +// +// // Rotation order don't affect post rotation, so just use the default XYZ order +// FbxRotationOrder rOrder; +// rOrder.V2M(lSourceR, res); +// +// lR = lSourceR * lR; +// rOrder.M2V(res, lR); +// prV = res; +// pNode->SetPostRotation(FbxNode::eSourcePivot, prV); +// pNode->SetRotationActive(true); +// } +// +// // Point light do not need to be adjusted (since they radiate in all the directions). +// if( pNode->GetLight() && pNode->GetLight()->LightType.Get() == FbxLight::ePoint ) +// { +// pNode->SetPostRotation(FbxNode::eSourcePivot, FbxVector4(0,0,0,0)); +// } +// } +// // apply Pre rotations only on bones / end of chains +// if( pNode->GetNodeAttribute() && pNode->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eSkeleton +// || (pNode->GetMarker() && pNode->GetMarker()->GetType() == FbxMarker::eEffectorFK) +// || (pNode->GetMarker() && pNode->GetMarker()->GetType() == FbxMarker::eEffectorIK) ) +// { +// if( pNode->GetRotationActive() ) +// { +// pNode->SetPreRotation(FbxNode::eDestinationPivot, pNode->GetPreRotation(FbxNode::eSourcePivot)); +// } +// +// // No pivots on bones +// pNode->SetRotationPivot(FbxNode::eDestinationPivot, lZero); +// pNode->SetScalingPivot(FbxNode::eDestinationPivot, lZero); +// pNode->SetRotationOffset(FbxNode::eDestinationPivot,lZero); +// pNode->SetScalingOffset(FbxNode::eDestinationPivot, lZero); +// } +// else +// { +// // any other type: no pre-rotation support but... +// pNode->SetPreRotation(FbxNode::eDestinationPivot, lZero); +// +// // support for rotation and scaling pivots. +// pNode->SetRotationPivot(FbxNode::eDestinationPivot, pNode->GetRotationPivot(FbxNode::eSourcePivot)); +// pNode->SetScalingPivot(FbxNode::eDestinationPivot, pNode->GetScalingPivot(FbxNode::eSourcePivot)); +// // Rotation and scaling offset are supported +// pNode->SetRotationOffset(FbxNode::eDestinationPivot, pNode->GetRotationOffset(FbxNode::eSourcePivot)); +// pNode->SetScalingOffset(FbxNode::eDestinationPivot, pNode->GetScalingOffset(FbxNode::eSourcePivot)); +// // +// // If we don't "support" scaling pivots, we can simply do: +// // pNode->SetRotationPivot(FbxNode::eDestinationPivot, lZero); +// // pNode->SetScalingPivot(FbxNode::eDestinationPivot, lZero); +// } +// */ +// +// // Bake child nodes +// for(int i = 0; i < pNode->GetChildCount(); i++) +// { +// BakeNode(pNode->GetChild(i)); +// } +//} + void LoadNode(KRNode *parent_node, std::vector &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { KFbxVector4 lTmpVector; pNode->UpdatePropertiesFromPivotsAndLimits(); @@ -316,32 +450,48 @@ void LoadNode(KRNode *parent_node, std::vector &resources, FbxGeom fbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot); fbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSourcePivot); -// fbxDouble3 post_rotation = pNode->PostRotation.Get(); -// fbxDouble3 pre_rotation = pNode->PreRotation.Get(); -// fbxDouble3 rotation_offset = pNode->RotationOffset.Get(); -// fbxDouble3 scaling_offset = pNode->ScalingOffset.Get(); -// fbxDouble3 rotation_pivot = pNode->RotationPivot.Get(); -// fbxDouble3 scaling_pivot = pNode->ScalingPivot.Get(); -// fbxDouble3 geometric_rotation = pNode->GeometricRotation.Get(); -// fbxDouble3 geometric_translation = pNode->GeometricTranslation.Get(); -// fbxDouble3 geometric_scaling = pNode->GeometricScaling.Get(); -// ERotationOrder rotation_order = pNode->RotationOrder.Get(); + fbxDouble3 post_rotation = pNode->PostRotation.Get(); + fbxDouble3 pre_rotation = pNode->PreRotation.Get(); + fbxDouble3 rotation_offset = pNode->RotationOffset.Get(); + fbxDouble3 scaling_offset = pNode->ScalingOffset.Get(); + fbxDouble3 rotation_pivot = pNode->RotationPivot.Get(); + fbxDouble3 scaling_pivot = pNode->ScalingPivot.Get(); + fbxDouble3 geometric_rotation = pNode->GeometricRotation.Get(); + fbxDouble3 geometric_translation = pNode->GeometricTranslation.Get(); + fbxDouble3 geometric_scaling = pNode->GeometricScaling.Get(); + ERotationOrder rotation_order = pNode->RotationOrder.Get(); + + + KFbxVector4 lZero(0.0, 0.0, 0.0); + KFbxVector4 lOne(1.0, 1.0, 1.0); + + assert(post_rotation == lZero); + assert(pre_rotation == lZero); + assert(rotation_offset == lZero); + assert(scaling_offset == lZero); + assert(rotation_pivot == lZero); + assert(scaling_pivot == lZero); + assert(geometric_rotation == lZero); + assert(geometric_translation == lZero); + assert(geometric_scaling == lOne); + assert(rotation_order == eEulerXYZ); // // bool rotation_active = pNode->RotationActive.Get(); // KRVector3 node_translation = KRVector3(local_translation[0] + rotation_offset[0] + rotation_pivot[0], local_translation[1] + rotation_offset[1] + rotation_pivot[1], local_translation[2] + rotation_offset[2] + rotation_pivot[2]); // T * Roff * Rp KRVector3 node_translation = KRVector3(local_translation[0], local_translation[1], local_translation[2]); // T * Roff * Rp - KRVector3 node_rotation = KRQuaternion(KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI).euler(); // R +// KRVector3 node_rotation = KRQuaternion(KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI).euler(); // R + KRVector3 node_rotation = KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI; // if(rotation_active) { // node_rotation = (KRQuaternion(KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI) * KRQuaternion(KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI) * KRQuaternion(KRVector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI)).euler(); // Rpre * R * Rpost // } KRVector3 node_scale = KRVector3(local_scale[0], local_scale[1], local_scale[2]); - printf(" Local Translation: %f %f %f\n", local_translation[0], local_translation[1], local_translation[2]); - printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]); - printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]); +// printf(" Local Translation: %f %f %f\n", local_translation[0], local_translation[1], local_translation[2]); +// printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]); +// printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]); KRNode *new_node = NULL; @@ -642,11 +792,12 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector &resources, FbxG printf("Warning! Layered textures not supported.\n"); } - texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId); + + texture_count = pProperty.GetSrcObjectCount(); if(texture_count > 1) { printf("Error! Multiple normal map textures not supported.\n"); } else if(texture_count == 1) { - KFbxTexture* pTexture = FbxCast (pProperty.GetSrcObject(KFbxTexture::ClassId,0)); + KFbxTexture* pTexture = pProperty.GetSrcObject(0); KFbxFileTexture *pFileTexture = FbxCast(pTexture); if(pFileTexture) { new_material->setNormalMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV())); @@ -654,7 +805,6 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector &resources, FbxG } bool bFound = false; - vector::iterator resource_itr = resources.begin(); for(vector::iterator resource_itr = resources.begin(); resource_itr != resources.end(); resource_itr++) { KRResource *pResource = (*resource_itr); if(pResource->getName() == new_material->getName() && pResource->getExtension() == new_material->getExtension()) { @@ -735,6 +885,7 @@ KRNode *LoadLight(KRNode *parent_node, std::vector &resources, KFb new_light = l; } break; + case KFbxLight::eVolume: case KFbxLight::eArea: // Not supported yet break;