framework2
237 строк · 5.9 Кб
1//
2// ofxAssimpAnimation.cpp
3// Created by Lukasz Karluk on 4/12/12.
4//
5
6#include "ofxAssimpAnimation.h"
7#include "ofAppRunner.h"
8#include "ofMath.h"
9
10ofxAssimpAnimation::ofxAssimpAnimation(std::shared_ptr<const aiScene> scene, aiAnimation * animation) {
11this->scene = scene;
12this->animation = animation;
13animationCurrTime = 0;
14animationPrevTime = 0;
15bPlay = false;
16bPause = false;
17loopType = OF_LOOP_NONE;
18progress = 0;
19progressInSeconds = 0;
20progressInMilliSeconds = 0;
21durationInSeconds = 0;
22durationInMilliSeconds = 0;
23speed = 1;
24speedFactor = 1;
25
26if(animation != NULL) {
27durationInSeconds = animation->mDuration;
28durationInMilliSeconds = durationInSeconds * 1000;
29}
30}
31
32ofxAssimpAnimation::~ofxAssimpAnimation() {
33//
34}
35
36aiAnimation * ofxAssimpAnimation::getAnimation() {
37return animation;
38}
39
40void ofxAssimpAnimation::update() {
41animationPrevTime = animationCurrTime;
42animationCurrTime = ofGetElapsedTimef();
43double tps = animation->mTicksPerSecond ? animation->mTicksPerSecond : 25.f;
44animationCurrTime *= tps;
45
46if(!bPlay || bPause) {
47return;
48}
49
50float duration = getDurationInSeconds();
51float timeStep = animationCurrTime - animationPrevTime;
52float positionStep = timeStep / (float)duration;
53float position = getPosition() + positionStep * speed * speedFactor;
54
55if(position > 1.0 && loopType == OF_LOOP_NONE) {
56position = 1.0;
57stop();
58} else if(position > 1.0 && loopType == OF_LOOP_NORMAL) {
59position = fmod(position, 1.0f);
60} else if(position > 1.0 && loopType == OF_LOOP_PALINDROME) {
61speedFactor *= -1;
62} else if(position < 0.0 && loopType == OF_LOOP_PALINDROME) {
63speedFactor *= -1;
64}
65
66setPosition(position);
67}
68
69void ofxAssimpAnimation::updateAnimationNodes() {
70for(unsigned int i=0; i<animation->mNumChannels; i++) {
71const aiNodeAnim * channel = animation->mChannels[i];
72aiNode * targetNode = scene->mRootNode->FindNode(channel->mNodeName);
73
74aiVector3D presentPosition(0, 0, 0);
75if(channel->mNumPositionKeys > 0) {
76unsigned int frame = 0;
77while(frame < channel->mNumPositionKeys - 1) {
78if(progressInSeconds < channel->mPositionKeys[frame+1].mTime) {
79break;
80}
81frame++;
82}
83
84unsigned int nextFrame = (frame + 1) % channel->mNumPositionKeys;
85const aiVectorKey & key = channel->mPositionKeys[frame];
86const aiVectorKey & nextKey = channel->mPositionKeys[nextFrame];
87double diffTime = nextKey.mTime - key.mTime;
88if(diffTime < 0.0) {
89diffTime += getDurationInSeconds();
90}
91if(diffTime > 0) {
92float factor = float((progressInSeconds - key.mTime) / diffTime);
93presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
94} else {
95presentPosition = key.mValue;
96}
97}
98
99aiQuaternion presentRotation(1, 0, 0, 0);
100if(channel->mNumRotationKeys > 0) {
101unsigned int frame = 0;
102while(frame < channel->mNumRotationKeys - 1) {
103if(progressInSeconds < channel->mRotationKeys[frame+1].mTime) {
104break;
105}
106frame++;
107}
108
109unsigned int nextFrame = (frame + 1) % channel->mNumRotationKeys;
110const aiQuatKey& key = channel->mRotationKeys[frame];
111const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame];
112double diffTime = nextKey.mTime - key.mTime;
113if(diffTime < 0.0) {
114diffTime += getDurationInSeconds();
115}
116if(diffTime > 0) {
117float factor = float((progressInSeconds - key.mTime) / diffTime);
118aiQuaternion::Interpolate(presentRotation, key.mValue, nextKey.mValue, factor);
119} else {
120presentRotation = key.mValue;
121}
122}
123
124aiVector3D presentScaling(1, 1, 1);
125if(channel->mNumScalingKeys > 0) {
126unsigned int frame = 0;
127while(frame < channel->mNumScalingKeys - 1){
128if(progressInSeconds < channel->mScalingKeys[frame+1].mTime) {
129break;
130}
131frame++;
132}
133
134presentScaling = channel->mScalingKeys[frame].mValue;
135}
136
137aiMatrix4x4 mat = aiMatrix4x4(presentRotation.GetMatrix());
138mat.a1 *= presentScaling.x; mat.b1 *= presentScaling.x; mat.c1 *= presentScaling.x;
139mat.a2 *= presentScaling.y; mat.b2 *= presentScaling.y; mat.c2 *= presentScaling.y;
140mat.a3 *= presentScaling.z; mat.b3 *= presentScaling.z; mat.c3 *= presentScaling.z;
141mat.a4 = presentPosition.x; mat.b4 = presentPosition.y; mat.c4 = presentPosition.z;
142
143targetNode->mTransformation = mat;
144}
145}
146
147void ofxAssimpAnimation::play() {
148if(animation == NULL) {
149return;
150}
151if(bPlay) { // if already playing, ignore.
152bPause = false; // if paused, then unpause.
153return;
154}
155bPlay = true;
156bPause = false;
157
158setPosition(0);
159}
160
161void ofxAssimpAnimation::stop() {
162speedFactor = 1.0;
163if(!bPlay) {
164return;
165}
166bPlay = false;
167bPause = false;
168}
169
170void ofxAssimpAnimation::reset() {
171speedFactor = 1.0;
172setPosition(0);
173}
174
175bool ofxAssimpAnimation::isFrameNew() {
176return (bPlay && !bPause); // assume its always a new frame when playing and not paused.
177}
178
179bool ofxAssimpAnimation::isPaused() {
180return bPause;
181}
182
183bool ofxAssimpAnimation::isPlaying() {
184return bPlay;
185}
186
187bool ofxAssimpAnimation::isFinished() {
188return !bPlay && (getPosition() == 1.0);
189}
190
191float ofxAssimpAnimation::getPosition() {
192return progress;
193}
194
195float ofxAssimpAnimation::getPositionInSeconds() {
196return progressInSeconds;
197}
198
199int ofxAssimpAnimation::getPositionInMilliSeconds() {
200return progressInMilliSeconds;
201}
202
203float ofxAssimpAnimation::getSpeed() {
204return speed;
205}
206
207float ofxAssimpAnimation::getDurationInSeconds() {
208return durationInSeconds;
209}
210
211int ofxAssimpAnimation::getDurationInMilliSeconds() {
212return durationInMilliSeconds;
213}
214
215void ofxAssimpAnimation::setPaused(bool paused) {
216bPause = paused;
217}
218
219void ofxAssimpAnimation::setPosition(float position) {
220position = ofClamp(position, 0.0f, 1.0f);
221if(progress == position) {
222return;
223}
224progress = position;
225progressInSeconds = progress * getDurationInSeconds();
226progressInMilliSeconds = progress * getDurationInMilliSeconds();
227
228updateAnimationNodes();
229}
230
231void ofxAssimpAnimation::setLoopState(ofLoopType state) {
232loopType = state;
233}
234
235void ofxAssimpAnimation::setSpeed(float s) {
236speed = s;
237}
238