123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- #include "3d/CCAnimationCurve.h"
- NS_CC_BEGIN
- template <int componentSize>
- void AnimationCurve<componentSize>::evaluate(float time, float* dst, EvaluateType type) const
- {
- if (_count == 1 || time <= _keytime[0])
- {
- memcpy(dst, _value, _componentSizeByte);
- return;
- }
- else if (time >= _keytime[_count - 1])
- {
- memcpy(dst, &_value[(_count - 1) * componentSize], _componentSizeByte);
- return;
- }
-
- unsigned int index = determineIndex(time);
-
- float scale = (_keytime[index + 1] - _keytime[index]);
- float t = (time - _keytime[index]) / scale;
-
- float* fromValue = &_value[index * componentSize];
- float* toValue = fromValue + componentSize;
-
- switch (type) {
- case EvaluateType::INT_LINEAR:
- {
- for (auto i = 0; i < componentSize; i++) {
- dst[i] = fromValue[i] + (toValue[i] - fromValue[i]) * t;
- }
- }
- break;
- case EvaluateType::INT_NEAR:
- {
- float* src = std::abs(t) > 0.5f ? toValue : fromValue;
- memcpy(dst, src, _componentSizeByte);
- }
- break;
- case EvaluateType::INT_QUAT_SLERP:
- {
- // Evaluate.
- Quaternion quat;
- if (t >= 0)
- Quaternion::slerp(Quaternion(fromValue), Quaternion(toValue), t, &quat);
- else
- Quaternion::slerp(Quaternion(toValue), Quaternion(fromValue), t, &quat);
-
- dst[0] = quat.x;
- dst[1] = quat.y;
- dst[2] = quat.z;
- dst[3] = quat.w;
- }
- break;
- case EvaluateType::INT_USER_FUNCTION:
- {
- if (_evaluateFun)
- _evaluateFun(time, dst);
- }
- break;
-
- default:
- break;
- }
- }
- template <int componentSize>
- void AnimationCurve<componentSize>::setEvaluateFun(std::function<void(float time, float* dst)> fun)
- {
- _evaluateFun = fun;
- }
- //create animation curve
- template <int componentSize>
- AnimationCurve<componentSize>* AnimationCurve<componentSize>::create(float* keytime, float* value, int count)
- {
- int floatSize = sizeof(float);
- AnimationCurve* curve = new (std::nothrow) AnimationCurve();
- curve->_keytime = new float[count];
- memcpy(curve->_keytime, keytime, count * floatSize);
-
- int compoentSizeByte = componentSize * floatSize;
- int totalByte = count * compoentSizeByte;
- curve->_value = new float[totalByte / floatSize];
- memcpy(curve->_value, value, totalByte);
-
- curve->_count = count;
- curve->_componentSizeByte = compoentSizeByte;
-
- curve->autorelease();
- return curve;
- }
- template <int componentSize>
- float AnimationCurve<componentSize>::getStartTime() const
- {
- return _keytime[0];
- }
- template <int componentSize>
- float AnimationCurve<componentSize>::getEndTime() const
- {
- return _keytime[_count - 1];
- }
- template <int componentSize>
- AnimationCurve<componentSize>::AnimationCurve()
- : _value(nullptr)
- , _keytime(nullptr)
- , _count(0)
- , _componentSizeByte(0)
- , _evaluateFun(nullptr)
- {
-
- }
- template <int componentSize>
- AnimationCurve<componentSize>::~AnimationCurve()
- {
- CC_SAFE_DELETE_ARRAY(_keytime);
- CC_SAFE_DELETE_ARRAY(_value);
- }
- template <int componentSize>
- int AnimationCurve<componentSize>::determineIndex(float time) const
- {
- unsigned int min = 0;
- unsigned int max = _count - 1;
- unsigned int mid = 0;
-
- do
- {
- mid = (min + max) >> 1;
-
- if (time >= _keytime[mid] && time <= _keytime[mid + 1])
- return mid;
- else if (time < _keytime[mid])
- max = mid - 1;
- else
- min = mid + 1;
- } while (min <= max);
-
- // We should never hit this!
- return -1;
- }
- NS_CC_END
|