Implemented animation splitting
--HG-- extra : source : e2686eec48ec9fa9da4359ce8fb75efa6ebba62c
This commit is contained in:
@@ -28,7 +28,8 @@
|
|||||||
// authors and should not be interpreted as representing official policies, either expressed
|
// authors and should not be interpreted as representing official policies, either expressed
|
||||||
// or implied, of Kearwood Gilbert.
|
// or implied, of Kearwood Gilbert.
|
||||||
//
|
//
|
||||||
|
#include <boost/tokenizer.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
#include "KRAnimation.h"
|
#include "KRAnimation.h"
|
||||||
#include "KRAnimationManager.h"
|
#include "KRAnimationManager.h"
|
||||||
#include "KRContext.h"
|
#include "KRContext.h"
|
||||||
@@ -44,6 +45,7 @@ KRAnimation::KRAnimation(KRContext &context, std::string name) : KRResource(cont
|
|||||||
m_playing = false;
|
m_playing = false;
|
||||||
m_local_time = 0.0f;
|
m_local_time = 0.0f;
|
||||||
m_duration = 0.0f;
|
m_duration = 0.0f;
|
||||||
|
m_start_time = 0.0f;
|
||||||
}
|
}
|
||||||
KRAnimation::~KRAnimation()
|
KRAnimation::~KRAnimation()
|
||||||
{
|
{
|
||||||
@@ -68,6 +70,7 @@ bool KRAnimation::save(KRDataBlock &data) {
|
|||||||
animation_node->SetAttribute("loop", m_loop ? "true" : "false");
|
animation_node->SetAttribute("loop", m_loop ? "true" : "false");
|
||||||
animation_node->SetAttribute("auto_play", m_auto_play ? "true" : "false");
|
animation_node->SetAttribute("auto_play", m_auto_play ? "true" : "false");
|
||||||
animation_node->SetAttribute("duration", m_duration);
|
animation_node->SetAttribute("duration", m_duration);
|
||||||
|
animation_node->SetAttribute("start_time", m_start_time);
|
||||||
|
|
||||||
for(unordered_map<std::string, KRAnimationLayer *>::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){
|
for(unordered_map<std::string, KRAnimationLayer *>::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){
|
||||||
(*itr).second->saveXML(animation_node);
|
(*itr).second->saveXML(animation_node);
|
||||||
@@ -93,6 +96,10 @@ KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDa
|
|||||||
new_animation->m_duration = 0.0f; // Default value
|
new_animation->m_duration = 0.0f; // Default value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(animation_node->QueryFloatAttribute("start_time", &new_animation->m_start_time) != tinyxml2::XML_SUCCESS) {
|
||||||
|
new_animation->m_start_time = 0.0f; // Default value
|
||||||
|
}
|
||||||
|
|
||||||
if(animation_node->QueryBoolAttribute("loop", &new_animation->m_loop) != tinyxml2::XML_SUCCESS) {
|
if(animation_node->QueryBoolAttribute("loop", &new_animation->m_loop) != tinyxml2::XML_SUCCESS) {
|
||||||
new_animation->m_loop = false; // Default value
|
new_animation->m_loop = false; // Default value
|
||||||
}
|
}
|
||||||
@@ -157,9 +164,9 @@ void KRAnimation::update(float deltaTime)
|
|||||||
KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute();
|
KRNode::node_attribute_type attribute_type = attribute->getTargetAttribute();
|
||||||
|
|
||||||
if(curve != NULL && target != NULL) {
|
if(curve != NULL && target != NULL) {
|
||||||
int frame_number = (int)(m_local_time * curve->getFrameRate());
|
int frame_number = (int)((m_local_time + m_start_time) * curve->getFrameRate());
|
||||||
if(frame_number < curve->getFrameStart()) {
|
if(frame_number < curve->getFrameStart()) {
|
||||||
target->SetAttribute(attribute_type, curve->getValue(0));
|
target->SetAttribute(attribute_type, curve->getValue(m_start_time));
|
||||||
} else if(frame_number - curve->getFrameStart() >= curve->getFrameCount()) {
|
} else if(frame_number - curve->getFrameStart() >= curve->getFrameCount()) {
|
||||||
target->SetAttribute(attribute_type, curve->getValue(curve->getFrameCount() - 1));
|
target->SetAttribute(attribute_type, curve->getValue(curve->getFrameCount() - 1));
|
||||||
} else {
|
} else {
|
||||||
@@ -203,6 +210,16 @@ void KRAnimation::setDuration(float duration)
|
|||||||
m_duration = duration;
|
m_duration = duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float KRAnimation::getStartTime()
|
||||||
|
{
|
||||||
|
return m_start_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRAnimation::setStartTime(float start_time)
|
||||||
|
{
|
||||||
|
m_start_time = start_time;
|
||||||
|
}
|
||||||
|
|
||||||
bool KRAnimation::isPlaying()
|
bool KRAnimation::isPlaying()
|
||||||
{
|
{
|
||||||
return m_playing;
|
return m_playing;
|
||||||
@@ -227,3 +244,62 @@ void KRAnimation::setLooping(bool looping)
|
|||||||
{
|
{
|
||||||
m_loop = looping;
|
m_loop = looping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KRAnimation *KRAnimation::split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes, bool clone_curves)
|
||||||
|
{
|
||||||
|
KRAnimation *new_animation = new KRAnimation(getContext(), name);
|
||||||
|
new_animation->setStartTime(start_time);
|
||||||
|
new_animation->setDuration(duration);
|
||||||
|
new_animation->m_loop = m_loop;
|
||||||
|
new_animation->m_auto_play = m_auto_play;
|
||||||
|
int new_curve_count = 0;
|
||||||
|
for(unordered_map<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
|
||||||
|
KRAnimationLayer *layer = (*layer_itr).second;
|
||||||
|
KRAnimationLayer *new_layer = new KRAnimationLayer(getContext());
|
||||||
|
new_layer->setName(layer->getName());
|
||||||
|
new_layer->setRotationAccumulationMode(layer->getRotationAccumulationMode());
|
||||||
|
new_layer->setScaleAccumulationMode(layer->getScaleAccumulationMode());
|
||||||
|
new_layer->setWeight(layer->getWeight());
|
||||||
|
new_animation->m_layers[new_layer->getName()] = new_layer;
|
||||||
|
for(std::vector<KRAnimationAttribute *>::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) {
|
||||||
|
KRAnimationAttribute *attribute = *attribute_itr;
|
||||||
|
KRAnimationCurve *curve = attribute->getCurve();
|
||||||
|
if(curve != NULL) {
|
||||||
|
bool include_attribute = true;
|
||||||
|
if(strip_unchanging_attributes) {
|
||||||
|
if(!curve->valueChanges(start_time, duration)) {
|
||||||
|
include_attribute = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(include_attribute) {
|
||||||
|
KRAnimationAttribute *new_attribute = new KRAnimationAttribute(getContext());
|
||||||
|
KRAnimationCurve *new_curve = curve;
|
||||||
|
if(clone_curves) {
|
||||||
|
std::string new_curve_name = name + "_curve" + boost::lexical_cast<std::string>(++new_curve_count);
|
||||||
|
new_curve = curve->split(new_curve_name, start_time, duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_attribute->setCurveName(new_curve->getName());
|
||||||
|
new_attribute->setTargetName(attribute->getTargetName());
|
||||||
|
new_layer->addAttribute(new_attribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getContext().getAnimationManager()->addAnimation(new_animation);
|
||||||
|
return new_animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRAnimation::deleteCurves()
|
||||||
|
{
|
||||||
|
for(unordered_map<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
|
||||||
|
KRAnimationLayer *layer = (*layer_itr).second;
|
||||||
|
for(std::vector<KRAnimationAttribute *>::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) {
|
||||||
|
KRAnimationAttribute *attribute = *attribute_itr;
|
||||||
|
attribute->deleteCurve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,13 @@ public:
|
|||||||
void setTime(float time);
|
void setTime(float time);
|
||||||
float getDuration();
|
float getDuration();
|
||||||
void setDuration(float duration);
|
void setDuration(float duration);
|
||||||
|
float getStartTime();
|
||||||
|
void setStartTime(float start_time);
|
||||||
bool isPlaying();
|
bool isPlaying();
|
||||||
|
|
||||||
|
KRAnimation *split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes = true, bool clone_curves = true);
|
||||||
|
void deleteCurves();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unordered_map<std::string, KRAnimationLayer *> m_layers;
|
unordered_map<std::string, KRAnimationLayer *> m_layers;
|
||||||
bool m_auto_play;
|
bool m_auto_play;
|
||||||
@@ -72,6 +78,7 @@ private:
|
|||||||
bool m_playing;
|
bool m_playing;
|
||||||
float m_local_time;
|
float m_local_time;
|
||||||
float m_duration;
|
float m_duration;
|
||||||
|
float m_start_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,8 @@ void KRAnimationAttribute::loadXML(tinyxml2::XMLElement *e)
|
|||||||
m_curve = NULL;
|
m_curve = NULL;
|
||||||
m_curve_name = e->Attribute("curve");
|
m_curve_name = e->Attribute("curve");
|
||||||
m_target_name = e->Attribute("target");
|
m_target_name = e->Attribute("target");
|
||||||
|
|
||||||
|
|
||||||
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE;
|
m_node_attribute = KRNode::KRENGINE_NODE_ATTRIBUTE_NONE;
|
||||||
|
|
||||||
const char *szAttribute = e->Attribute("attribute");
|
const char *szAttribute = e->Attribute("attribute");
|
||||||
@@ -267,4 +269,12 @@ KRAnimationCurve *KRAnimationAttribute::getCurve()
|
|||||||
return m_curve;
|
return m_curve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KRAnimationAttribute::deleteCurve()
|
||||||
|
{
|
||||||
|
KRAnimationCurve *curve = getCurve();
|
||||||
|
if(curve) {
|
||||||
|
getContext().getAnimationCurveManager()->deleteAnimationCurve(curve);
|
||||||
|
m_curve = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ public:
|
|||||||
KRNode *getTarget();
|
KRNode *getTarget();
|
||||||
KRAnimationCurve *getCurve();
|
KRAnimationCurve *getCurve();
|
||||||
|
|
||||||
|
void deleteCurve();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_target_name;
|
std::string m_target_name;
|
||||||
std::string m_curve_name;
|
std::string m_curve_name;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
// or implied, of Kearwood Gilbert.
|
// or implied, of Kearwood Gilbert.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "KRContext.h"
|
||||||
#include "KRAnimationCurve.h"
|
#include "KRAnimationCurve.h"
|
||||||
#include "KRDataBlock.h"
|
#include "KRDataBlock.h"
|
||||||
|
|
||||||
@@ -48,7 +49,6 @@ KRAnimationCurve::~KRAnimationCurve()
|
|||||||
m_pData->unload();
|
m_pData->unload();
|
||||||
delete m_pData;
|
delete m_pData;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KRAnimationCurve::load(KRDataBlock *data)
|
bool KRAnimationCurve::load(KRDataBlock *data)
|
||||||
{
|
{
|
||||||
m_pData->unload();
|
m_pData->unload();
|
||||||
@@ -152,3 +152,44 @@ float KRAnimationCurve::getValue(float local_time)
|
|||||||
return getValue((int)(local_time * getFrameRate()));
|
return getValue((int)(local_time * getFrameRate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KRAnimationCurve::valueChanges(float start_time, float duration)
|
||||||
|
{
|
||||||
|
return valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KRAnimationCurve::valueChanges(int start_frame, int frame_count)
|
||||||
|
{
|
||||||
|
|
||||||
|
float first_value = getValue(start_frame);
|
||||||
|
|
||||||
|
// Range of frames is not inclusive of last frame
|
||||||
|
for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count; frame_number++) {
|
||||||
|
if(getValue(frame_number) != first_value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
KRAnimationCurve *KRAnimationCurve::split(const std::string &name, float start_time, float duration)
|
||||||
|
{
|
||||||
|
return split(name, (int)(start_time * getFrameRate()), (int)(duration * getFrameRate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
KRAnimationCurve *KRAnimationCurve::split(const std::string &name, int start_frame, int frame_count)
|
||||||
|
{
|
||||||
|
KRAnimationCurve *new_curve = new KRAnimationCurve(getContext(), name);
|
||||||
|
|
||||||
|
new_curve->setFrameRate(getFrameRate());
|
||||||
|
new_curve->setFrameStart(start_frame);
|
||||||
|
new_curve->setFrameCount(frame_count);
|
||||||
|
|
||||||
|
// Range of frames is not inclusive of last frame
|
||||||
|
for(int frame_number = start_frame; frame_number < start_frame + frame_count; frame_number++) {
|
||||||
|
new_curve->setValue(frame_number, getValue(frame_number)); // TODO - MEMCPY here?
|
||||||
|
}
|
||||||
|
|
||||||
|
getContext().getAnimationCurveManager()->addAnimationCurve(new_curve);
|
||||||
|
return new_curve;
|
||||||
|
}
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ public:
|
|||||||
|
|
||||||
static KRAnimationCurve *Load(KRContext &context, const std::string &name, KRDataBlock *data);
|
static KRAnimationCurve *Load(KRContext &context, const std::string &name, KRDataBlock *data);
|
||||||
|
|
||||||
|
bool valueChanges(float start_time, float duration);
|
||||||
|
bool valueChanges(int start_frame, int frame_count);
|
||||||
|
|
||||||
|
KRAnimationCurve *split(const std::string &name, float start_time, float duration);
|
||||||
|
KRAnimationCurve *split(const std::string &name, int start_frame, int frame_count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KRDataBlock *m_pData;
|
KRDataBlock *m_pData;
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ KRAnimationCurveManager::~KRAnimationCurveManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KRAnimationCurveManager::deleteAnimationCurve(KRAnimationCurve *curve) {
|
||||||
|
m_animationCurves.erase(curve->getName());
|
||||||
|
delete curve;
|
||||||
|
}
|
||||||
|
|
||||||
KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const std::string &name, KRDataBlock *data) {
|
KRAnimationCurve *KRAnimationCurveManager::loadAnimationCurve(const std::string &name, KRDataBlock *data) {
|
||||||
KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, name, data);
|
KRAnimationCurve *pAnimationCurve = KRAnimationCurve::Load(*m_pContext, name, data);
|
||||||
m_animationCurves[name] = pAnimationCurve;
|
m_animationCurves[name] = pAnimationCurve;
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ public:
|
|||||||
void addAnimationCurve(KRAnimationCurve *new_animation_curve);
|
void addAnimationCurve(KRAnimationCurve *new_animation_curve);
|
||||||
unordered_map<std::string, KRAnimationCurve *> &getAnimationCurves();
|
unordered_map<std::string, KRAnimationCurve *> &getAnimationCurves();
|
||||||
|
|
||||||
|
void deleteAnimationCurve(KRAnimationCurve *curve);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unordered_map<std::string, KRAnimationCurve *> m_animationCurves;
|
unordered_map<std::string, KRAnimationCurve *> m_animationCurves;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -100,3 +100,12 @@ void KRAnimationManager::updateActiveAnimations(KRAnimation *animation)
|
|||||||
m_animationsToUpdate.insert(animation);
|
m_animationsToUpdate.insert(animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KRAnimationManager::deleteAnimation(KRAnimation *animation, bool delete_curves)
|
||||||
|
{
|
||||||
|
if(delete_curves)
|
||||||
|
{
|
||||||
|
animation->deleteCurves();
|
||||||
|
}
|
||||||
|
m_animations.erase(animation->getName());
|
||||||
|
delete animation;
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public:
|
|||||||
KRAnimation *getAnimation(const char *szName);
|
KRAnimation *getAnimation(const char *szName);
|
||||||
void addAnimation(KRAnimation *new_animation);
|
void addAnimation(KRAnimation *new_animation);
|
||||||
unordered_map<std::string, KRAnimation *> &getAnimations();
|
unordered_map<std::string, KRAnimation *> &getAnimations();
|
||||||
|
void deleteAnimation(KRAnimation *animation, bool delete_curves);
|
||||||
|
|
||||||
void startFrame(float deltaTime);
|
void startFrame(float deltaTime);
|
||||||
void endFrame(float deltaTime);
|
void endFrame(float deltaTime);
|
||||||
|
|||||||
Reference in New Issue
Block a user