|
@@ -19,13 +19,9 @@ AnimationController::~AnimationController()
|
|
|
Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, Curve::InterpolationType type)
|
|
Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, Curve::InterpolationType type)
|
|
|
{
|
|
{
|
|
|
assert(type != Curve::BEZIER && type != Curve::HERMITE);
|
|
assert(type != Curve::BEZIER && type != Curve::HERMITE);
|
|
|
- assert(id && keyCount >= 2 && keyTimes && keyValues);
|
|
|
|
|
- Animation* animation = getAnimation(id);
|
|
|
|
|
|
|
+ assert(keyCount >= 2 && keyTimes && keyValues && target);
|
|
|
|
|
|
|
|
- if (animation != NULL)
|
|
|
|
|
- return NULL;
|
|
|
|
|
-
|
|
|
|
|
- animation = new Animation(id, target, propertyId, keyCount, keyTimes, keyValues, type);
|
|
|
|
|
|
|
+ Animation* animation = new Animation(id, target, propertyId, keyCount, keyTimes, keyValues, type);
|
|
|
|
|
|
|
|
addAnimation(animation);
|
|
addAnimation(animation);
|
|
|
|
|
|
|
@@ -34,34 +30,24 @@ Animation* AnimationController::createAnimation(const char* id, AnimationTarget*
|
|
|
|
|
|
|
|
Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type)
|
|
Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type)
|
|
|
{
|
|
{
|
|
|
- assert(id && keyCount >= 2 && keyTimes && keyValues && keyInValue && keyOutValue);
|
|
|
|
|
- Animation* animation = getAnimation(id);
|
|
|
|
|
-
|
|
|
|
|
- if (animation != NULL)
|
|
|
|
|
- return NULL;
|
|
|
|
|
-
|
|
|
|
|
- animation = new Animation(id, target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
|
|
|
|
|
|
|
+ assert(target && keyCount >= 2 && keyTimes && keyValues && keyInValue && keyOutValue);
|
|
|
|
|
+ Animation* animation = new Animation(id, target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
|
|
|
|
|
|
|
|
addAnimation(animation);
|
|
addAnimation(animation);
|
|
|
|
|
|
|
|
return animation;
|
|
return animation;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, Properties* p)
|
|
|
|
|
|
|
+Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, const char* animationFile)
|
|
|
{
|
|
{
|
|
|
- Animation* animation = getAnimation(id);
|
|
|
|
|
-
|
|
|
|
|
- if (animation != NULL)
|
|
|
|
|
- return NULL;
|
|
|
|
|
|
|
+ assert(target && animationFile);
|
|
|
|
|
|
|
|
- // TODO: Implement loading from a properties object here.
|
|
|
|
|
- /*
|
|
|
|
|
- animation = new Animation(id, target, p);
|
|
|
|
|
|
|
+ Properties* p = Properties::create(animationFile);
|
|
|
|
|
+ assert(p);
|
|
|
|
|
|
|
|
- addAnimation(animation);
|
|
|
|
|
|
|
+ Animation* animation = createAnimation(id, target, p->getNextNamespace());
|
|
|
|
|
|
|
|
- target->addAnimation(animation);
|
|
|
|
|
- */
|
|
|
|
|
|
|
+ SAFE_DELETE(p);
|
|
|
|
|
|
|
|
return animation;
|
|
return animation;
|
|
|
}
|
|
}
|
|
@@ -125,7 +111,6 @@ void AnimationController::stopAllAnimations()
|
|
|
AnimationClip* clip = *clipIter;
|
|
AnimationClip* clip = *clipIter;
|
|
|
clip->_isPlaying = false;
|
|
clip->_isPlaying = false;
|
|
|
clip->onEnd();
|
|
clip->onEnd();
|
|
|
- clipIter = _runningClips.erase(clipIter);
|
|
|
|
|
SAFE_RELEASE(clip);
|
|
SAFE_RELEASE(clip);
|
|
|
}
|
|
}
|
|
|
_runningClips.clear();
|
|
_runningClips.clear();
|
|
@@ -133,6 +118,144 @@ void AnimationController::stopAllAnimations()
|
|
|
_state = IDLE;
|
|
_state = IDLE;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+Animation* AnimationController::createAnimation(const char* id, AnimationTarget* target, Properties* animationProperties)
|
|
|
|
|
+{
|
|
|
|
|
+ assert(target && animationProperties);
|
|
|
|
|
+ assert(std::strcmp(animationProperties->getNamespace(), "animation") == 0);
|
|
|
|
|
+
|
|
|
|
|
+ const char* propertyIdStr = animationProperties->getString("property");
|
|
|
|
|
+ assert(propertyIdStr);
|
|
|
|
|
+
|
|
|
|
|
+ // Get animation target property id
|
|
|
|
|
+ int propertyId = AnimationTarget::getPropertyId(target->_targetType, propertyIdStr);
|
|
|
|
|
+ assert(propertyId != -1);
|
|
|
|
|
+
|
|
|
|
|
+ unsigned int keyCount = animationProperties->getInt("keyCount");
|
|
|
|
|
+ assert(keyCount > 0);
|
|
|
|
|
+
|
|
|
|
|
+ const char* keyTimesStr = animationProperties->getString("keyTimes");
|
|
|
|
|
+ assert(keyTimesStr);
|
|
|
|
|
+
|
|
|
|
|
+ const char* keyValuesStr = animationProperties->getString("keyValues");
|
|
|
|
|
+ assert(keyValuesStr);
|
|
|
|
|
+
|
|
|
|
|
+ const char* curveStr = animationProperties->getString("curve");
|
|
|
|
|
+ assert(curveStr);
|
|
|
|
|
+
|
|
|
|
|
+ char delimeter = ' ';
|
|
|
|
|
+ unsigned int startOffset = 0;
|
|
|
|
|
+ unsigned int endOffset = std::string::npos;
|
|
|
|
|
+
|
|
|
|
|
+ unsigned long* keyTimes = new unsigned long[keyCount];
|
|
|
|
|
+ for (unsigned int i = 0; i < keyCount; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ endOffset = static_cast<std::string>(keyTimesStr).find_first_of(delimeter, startOffset);
|
|
|
|
|
+ if (endOffset != std::string::npos)
|
|
|
|
|
+ {
|
|
|
|
|
+ keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, endOffset - startOffset).c_str(), NULL, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, static_cast<std::string>(keyTimesStr).length()).c_str(), NULL, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ startOffset = endOffset + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ startOffset = 0;
|
|
|
|
|
+ endOffset = std::string::npos;
|
|
|
|
|
+
|
|
|
|
|
+ int componentCount = target->getAnimationPropertyComponentCount(propertyId);
|
|
|
|
|
+ assert(componentCount > 0);
|
|
|
|
|
+
|
|
|
|
|
+ unsigned int components = keyCount * componentCount;
|
|
|
|
|
+
|
|
|
|
|
+ float* keyValues = new float[components];
|
|
|
|
|
+ for (unsigned int i = 0; i < components; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ endOffset = static_cast<std::string>(keyValuesStr).find_first_of(delimeter, startOffset);
|
|
|
|
|
+ if (endOffset != std::string::npos)
|
|
|
|
|
+ {
|
|
|
|
|
+ keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, endOffset - startOffset).c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, static_cast<std::string>(keyValuesStr).length()).c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+ startOffset = endOffset + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const char* keyInStr = animationProperties->getString("keyIn");
|
|
|
|
|
+ float* keyIn = NULL;
|
|
|
|
|
+ if (keyInStr)
|
|
|
|
|
+ {
|
|
|
|
|
+ keyIn = new float[components];
|
|
|
|
|
+ startOffset = 0;
|
|
|
|
|
+ endOffset = std::string::npos;
|
|
|
|
|
+ for (unsigned int i = 0; i < components; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ endOffset = static_cast<std::string>(keyInStr).find_first_of(delimeter, startOffset);
|
|
|
|
|
+ if (endOffset != std::string::npos)
|
|
|
|
|
+ {
|
|
|
|
|
+ keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, endOffset - startOffset).c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, static_cast<std::string>(keyInStr).length()).c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+ startOffset = endOffset + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const char* keyOutStr = animationProperties->getString("keyOut");
|
|
|
|
|
+ float* keyOut = NULL;
|
|
|
|
|
+ if(keyOutStr)
|
|
|
|
|
+ {
|
|
|
|
|
+ keyOut = new float[components];
|
|
|
|
|
+ startOffset = 0;
|
|
|
|
|
+ endOffset = std::string::npos;
|
|
|
|
|
+ for (unsigned int i = 0; i < components; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ endOffset = static_cast<std::string>(keyOutStr).find_first_of(delimeter, startOffset);
|
|
|
|
|
+ if (endOffset != std::string::npos)
|
|
|
|
|
+ {
|
|
|
|
|
+ keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, endOffset - startOffset).c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, static_cast<std::string>(keyOutStr).length()).c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+ startOffset = endOffset + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int curve = Curve::getInterpolationType(curveStr);
|
|
|
|
|
+
|
|
|
|
|
+ Animation* animation = NULL;
|
|
|
|
|
+ if (keyIn && keyOut)
|
|
|
|
|
+ {
|
|
|
|
|
+ animation = createAnimation(id, target, propertyId, keyCount, keyTimes, keyValues, keyIn, keyOut, (Curve::InterpolationType)curve);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ animation = createAnimation(id, target, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ SAFE_DELETE(keyOut);
|
|
|
|
|
+ SAFE_DELETE(keyIn);
|
|
|
|
|
+ SAFE_DELETE(keyValues);
|
|
|
|
|
+ SAFE_DELETE(keyTimes);
|
|
|
|
|
+
|
|
|
|
|
+ Properties* pClip = animationProperties->getNextNamespace();
|
|
|
|
|
+ if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ int frameCount = animationProperties->getInt("frameCount");
|
|
|
|
|
+ assert(frameCount > 0);
|
|
|
|
|
+ animation->createClips(animationProperties, (unsigned int) frameCount);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return animation;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
AnimationController::State AnimationController::getState() const
|
|
AnimationController::State AnimationController::getState() const
|
|
|
{
|
|
{
|
|
|
return _state;
|
|
return _state;
|
|
@@ -201,20 +324,18 @@ void AnimationController::update(long elapsedTime)
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
std::list<AnimationClip*>::iterator clipIter = _runningClips.begin();
|
|
std::list<AnimationClip*>::iterator clipIter = _runningClips.begin();
|
|
|
- unsigned int clipCount = 0;
|
|
|
|
|
while (clipIter != _runningClips.end())
|
|
while (clipIter != _runningClips.end())
|
|
|
{
|
|
{
|
|
|
AnimationClip* clip = (*clipIter);
|
|
AnimationClip* clip = (*clipIter);
|
|
|
if (clip->update(elapsedTime))
|
|
if (clip->update(elapsedTime))
|
|
|
{
|
|
{
|
|
|
- clipIter = _runningClips.erase(clipIter);
|
|
|
|
|
SAFE_RELEASE(clip);
|
|
SAFE_RELEASE(clip);
|
|
|
|
|
+ clipIter = _runningClips.erase(clipIter);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
clipIter++;
|
|
clipIter++;
|
|
|
}
|
|
}
|
|
|
- clipCount++;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (_runningClips.empty())
|
|
if (_runningClips.empty())
|
|
@@ -235,8 +356,8 @@ void AnimationController::destroyAnimation(Animation* animation)
|
|
|
if (animation == *itr)
|
|
if (animation == *itr)
|
|
|
{
|
|
{
|
|
|
Animation* animation = *itr;
|
|
Animation* animation = *itr;
|
|
|
- SAFE_RELEASE(animation);
|
|
|
|
|
_animations.erase(itr);
|
|
_animations.erase(itr);
|
|
|
|
|
+ SAFE_RELEASE(animation);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
itr++;
|
|
itr++;
|