Blame view

ios/cocos2d/cocos/3d/CCAnimationCurve.inl 3.71 KB
520389e3   xiaoyu   接入cocos源码,编译未通过,继续修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  #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