diff --git a/KREngine/KREngine/Classes/KRAnimation.cpp b/KREngine/KREngine/Classes/KRAnimation.cpp index 9947557..5730376 100644 --- a/KREngine/KREngine/Classes/KRAnimation.cpp +++ b/KREngine/KREngine/Classes/KRAnimation.cpp @@ -32,6 +32,9 @@ #include "KRAnimation.h" #include "KRAnimationManager.h" #include "KRContext.h" +#include "KRNode.h" +#include "KRAnimationCurve.h" + #import "tinyxml2.h" KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(context, name) @@ -130,9 +133,27 @@ void KRAnimation::update(float deltaTime) if(m_playing) { m_local_time += deltaTime; } - if(m_local_time > m_duration) { + while(m_local_time > m_duration) { m_local_time -= m_duration; } + + for(std::map::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) { + KRAnimationLayer *layer = (*layer_itr).second; + for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { + KRAnimationAttribute *attribute = *attribute_itr; + + + // TODO - Currently only a single layer supported per animation -- need to either implement combining of multiple layers or ask the FBX sdk to bake all layers into one + KRAnimationCurve *curve = attribute->getCurve(); + KRNode *target = attribute->getTarget(); + KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute(); + + if(curve != NULL && target != NULL) { + target->SetAttribute(attribute_type, curve->getValue(m_local_time)); + } + + } + } } void KRAnimation::Play() diff --git a/KREngine/KREngine/Classes/KRAnimationAttribute.cpp b/KREngine/KREngine/Classes/KRAnimationAttribute.cpp index 857ee78..715d484 100644 --- a/KREngine/KREngine/Classes/KRAnimationAttribute.cpp +++ b/KREngine/KREngine/Classes/KRAnimationAttribute.cpp @@ -30,11 +30,16 @@ // #include "KRAnimationAttribute.h" +#include "KRContext.h" +#include "KRAnimationManager.h" +#include "KRAnimationCurveManager.h" KRAnimationAttribute::KRAnimationAttribute(KRContext &context) : KRContextObject(context) { m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; + m_target = NULL; + m_curve = NULL; } KRAnimationAttribute::~KRAnimationAttribute() @@ -89,36 +94,48 @@ tinyxml2::XMLElement *KRAnimationAttribute::saveXML( tinyxml2::XMLNode *parent) void KRAnimationAttribute::loadXML(tinyxml2::XMLElement *e) { + m_target = NULL; + m_curve = NULL; m_curve_name = e->Attribute("curve"); m_target_name = e->Attribute("target"); - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; const char *szAttribute = e->Attribute("attribute"); if(strcmp(szAttribute, "none") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; } else if(strcmp(szAttribute, "translate_x") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X; } else if(strcmp(szAttribute, "translate_y") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y; } else if(strcmp(szAttribute, "translate_z") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z; } else if(strcmp(szAttribute, "rotate_x") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_X; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_X; } else if(strcmp(szAttribute, "rotate_y") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Y; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Y; } else if(strcmp(szAttribute, "rotate_z") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z; } else if(strcmp(szAttribute, "scale_x") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_X; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_X; } else if(strcmp(szAttribute, "scale_y") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y; } else if(strcmp(szAttribute, "scale_z") == 0) { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z; } else { - m_target_attribute_name = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; + m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE; } } +KRNode::node_attribute_type KRAnimationAttribute::getTargetAttribute() const +{ + return m_node_attribute; +} + +void KRAnimationAttribute::setTargetAttribute(KRNode::node_attribute_type target_attribute) +{ + m_node_attribute = target_attribute; +} + std::string KRAnimationAttribute::getTargetName() const { return m_target_name; @@ -127,19 +144,9 @@ std::string KRAnimationAttribute::getTargetName() const void KRAnimationAttribute::setTargetName(const std::string &target_name) { m_target_name = target_name; + m_target = NULL; } -std::string KRAnimationAttribute::getTargetAttributeName() const -{ - return m_target_attribute_name; -} - -void KRAnimationAttribute::setTargetAttributeName(const std::string &target_attribute_name) -{ - m_target_attribute_name = target_attribute_name; -} - - std::string KRAnimationAttribute::getCurveName() const { return m_curve_name; @@ -148,6 +155,23 @@ std::string KRAnimationAttribute::getCurveName() const void KRAnimationAttribute::setCurveName(const std::string &curve_name) { m_curve_name = curve_name; + m_curve = NULL; +} + +KRNode *KRAnimationAttribute::getTarget() +{ + if(m_target == NULL) { + m_target = getContext().getSceneManager()->getFirstScene()->getRootNode()->findChild(m_target_name); // FINDME, HACK! - This won't work with multiple scenes in a context; we should move the animations out of KRAnimationManager and attach them to the parent nodes of the animated KRNode's + } + return m_target; +} + +KRAnimationCurve *KRAnimationAttribute::getCurve() +{ + if(m_curve == NULL) { + m_curve = getContext().getAnimationCurveManager()->getAnimationCurve(m_curve_name.c_str()); + } + return m_curve; } diff --git a/KREngine/KREngine/Classes/KRAnimationAttribute.h b/KREngine/KREngine/Classes/KRAnimationAttribute.h index e0c9056..0a23eed 100644 --- a/KREngine/KREngine/Classes/KRAnimationAttribute.h +++ b/KREngine/KREngine/Classes/KRAnimationAttribute.h @@ -36,6 +36,7 @@ #import "KREngine-common.h" #import "tinyxml2.h" #import "KRNode.h" +#import "KRAnimationCurve.h" class KRAnimationAttribute : public KRContextObject { public: @@ -51,14 +52,19 @@ public: std::string getTargetName() const; void setTargetName(const std::string &target_name); - std::string getTargetAttributeName() const; - void setTargetAttributeName(const std::string &target_attribute_name); + KRNode::node_attribute_type getTargetAttribute() const; + void setTargetAttribute(KRNode::node_attribute_type target_attribute); + + KRNode *getTarget(); + KRAnimationCurve *getCurve(); private: std::string m_target_name; std::string m_curve_name; KRNode::node_attribute_type m_node_attribute; - std::string m_target_attribute_name; + + KRNode *m_target; + KRAnimationCurve *m_curve; }; #endif diff --git a/KREngine/KREngine/Classes/KRAnimationCurve.cpp b/KREngine/KREngine/Classes/KRAnimationCurve.cpp index 4fbda0e..4dbf0f2 100644 --- a/KREngine/KREngine/Classes/KRAnimationCurve.cpp +++ b/KREngine/KREngine/Classes/KRAnimationCurve.cpp @@ -139,3 +139,10 @@ void KRAnimationCurve::setValue(int frame_number, float value) } } +float KRAnimationCurve::getValue(float local_time) +{ + // TODO - Need to add interpolation for time values between frames. + // Must consider looping animations when determining which two frames to interpolate between. + return getValue((int)(local_time * getFrameRate())); +} + diff --git a/KREngine/KREngine/Classes/KRAnimationCurve.h b/KREngine/KREngine/Classes/KRAnimationCurve.h index b6b6290..9c01df9 100644 --- a/KREngine/KREngine/Classes/KRAnimationCurve.h +++ b/KREngine/KREngine/Classes/KRAnimationCurve.h @@ -54,6 +54,7 @@ public: void setFrameStart(int frame_number); int getFrameCount(); void setFrameCount(int frame_count); + float getValue(float local_time); float getValue(int frame_number); void setValue(int frame_number, float value); diff --git a/KREngine/KREngine/Classes/KRAnimationLayer.cpp b/KREngine/KREngine/Classes/KRAnimationLayer.cpp index 69efe2c..2056eb8 100644 --- a/KREngine/KREngine/Classes/KRAnimationLayer.cpp +++ b/KREngine/KREngine/Classes/KRAnimationLayer.cpp @@ -191,3 +191,8 @@ void KRAnimationLayer::addAttribute(KRAnimationAttribute *attribute) { m_attributes.push_back(attribute); } + +std::vector &KRAnimationLayer::getAttributes() +{ + return m_attributes; +} diff --git a/KREngine/KREngine/Classes/KRAnimationLayer.h b/KREngine/KREngine/Classes/KRAnimationLayer.h index 2516069..8652436 100644 --- a/KREngine/KREngine/Classes/KRAnimationLayer.h +++ b/KREngine/KREngine/Classes/KRAnimationLayer.h @@ -77,6 +77,7 @@ public: void setScaleAccumulationMode(const scale_accumulation_mode_t &scale_accumulation_mode); void addAttribute(KRAnimationAttribute *attribute); + std::vector &getAttributes(); private: std::string m_name; diff --git a/KREngine/KREngine/Classes/KRAnimationManager.cpp b/KREngine/KREngine/Classes/KRAnimationManager.cpp index 4413dc2..25db664 100644 --- a/KREngine/KREngine/Classes/KRAnimationManager.cpp +++ b/KREngine/KREngine/Classes/KRAnimationManager.cpp @@ -59,7 +59,7 @@ void KRAnimationManager::endFrame(float deltaTime) KRAnimation *KRAnimationManager::loadAnimation(const char *szName, KRDataBlock *data) { KRAnimation *pAnimation = KRAnimation::Load(*m_pContext, szName, data); - m_animations[szName] = pAnimation; + addAnimation(pAnimation); return pAnimation; } diff --git a/KREngine/KREngine/Classes/KRContext.cpp b/KREngine/KREngine/Classes/KRContext.cpp index 165d8e5..61f8c78 100644 --- a/KREngine/KREngine/Classes/KRContext.cpp +++ b/KREngine/KREngine/Classes/KRContext.cpp @@ -123,7 +123,7 @@ void KRContext::loadResource(const std::string &file_name, KRDataBlock *data) { m_pSceneManager->loadScene(name.c_str(), data); } else if(extension.compare("kranimation") == 0) { m_pAnimationManager->loadAnimation(name.c_str(), data); - } else if(extension.compare("kranimatinocurve") == 0) { + } else if(extension.compare("kranimationcurve") == 0) { m_pAnimationCurveManager->loadAnimationCurve(name.c_str(), data); } else if(extension.compare("pvr") == 0) { m_pTextureManager->loadTexture(name.c_str(), extension.c_str(), data); diff --git a/KREngine/KREngine/Classes/KRNode.cpp b/KREngine/KREngine/Classes/KRNode.cpp index d0bad7a..20b6ff4 100644 --- a/KREngine/KREngine/Classes/KRNode.cpp +++ b/KREngine/KREngine/Classes/KRNode.cpp @@ -272,13 +272,28 @@ void KRNode::SetAttribute(node_attribute_type attrib, float v) setLocalScale(KRVector3(m_localScale.x, m_localScale.y, v)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_X: - setLocalRotation(KRVector3(v, m_localRotation.y, m_localRotation.z)); + setLocalRotation(KRVector3(v / M_PI_2, m_localRotation.y, m_localRotation.z)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_Y: - setLocalRotation(KRVector3(m_localRotation.x, v, m_localRotation.z)); + setLocalRotation(KRVector3(m_localRotation.x, v / M_PI_2, m_localRotation.z)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_Z: - setLocalRotation(KRVector3(m_localRotation.x, m_localRotation.y, v)); + setLocalRotation(KRVector3(m_localRotation.x, m_localRotation.y, v / M_PI_2)); break; } +} + + +KRNode *KRNode::findChild(const std::string &name) +{ + if(m_name == name) { + return this; + } else { + for(std::vector::iterator child_itr = m_childNodes.begin(); child_itr != m_childNodes.end(); child_itr++) { + KRNode *match = (*child_itr)->findChild(name); + if(match) return match; + } + } + + return NULL; } \ No newline at end of file diff --git a/KREngine/KREngine/Classes/KRNode.h b/KREngine/KREngine/Classes/KRNode.h index a8c38ec..3a5c293 100644 --- a/KREngine/KREngine/Classes/KRNode.h +++ b/KREngine/KREngine/Classes/KRNode.h @@ -53,6 +53,8 @@ public: void addChild(KRNode *child); const std::vector &getChildren(); + KRNode *findChild(const std::string &name); + void setLocalTranslation(const KRVector3 &v); void setLocalScale(const KRVector3 &v); void setLocalRotation(const KRVector3 &v); diff --git a/KREngine/KREngine/Classes/KRResource+fbx.cpp b/KREngine/KREngine/Classes/KRResource+fbx.cpp index c7c13f7..6b2d14c 100644 --- a/KREngine/KREngine/Classes/KRResource+fbx.cpp +++ b/KREngine/KREngine/Classes/KRResource+fbx.cpp @@ -538,7 +538,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("rotate_x"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_X); pAnimationLayer->addAttribute(new_attribute); } @@ -547,7 +547,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("rotate_y"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Y); pAnimationLayer->addAttribute(new_attribute); } @@ -556,7 +556,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("rotate_z"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_ROTATE_Z); pAnimationLayer->addAttribute(new_attribute); } @@ -565,7 +565,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("translate_x"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X); pAnimationLayer->addAttribute(new_attribute); } @@ -574,7 +574,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("translate_y"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y); pAnimationLayer->addAttribute(new_attribute); } @@ -583,7 +583,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("translate_z"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z); pAnimationLayer->addAttribute(new_attribute); } @@ -592,7 +592,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("scale_x"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_X); pAnimationLayer->addAttribute(new_attribute); } @@ -601,7 +601,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("scale_y"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Y); pAnimationLayer->addAttribute(new_attribute); } @@ -610,7 +610,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorgetContext()); new_attribute->setCurveName(GetFbxObjectName(pAnimCurve, "fbx_curve")); new_attribute->setTargetName(pNode->GetName()); - new_attribute->setTargetAttributeName("scale_z"); + new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_SCALE_Z); pAnimationLayer->addAttribute(new_attribute); } }