framework2

Форк
0
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

10
ofxAssimpAnimation::ofxAssimpAnimation(std::shared_ptr<const aiScene> scene, aiAnimation * animation) {
11
	this->scene = scene;
12
	this->animation = animation;
13
	animationCurrTime = 0;
14
	animationPrevTime = 0;
15
	bPlay = false;
16
	bPause = false;
17
	loopType = OF_LOOP_NONE;
18
	progress = 0;
19
	progressInSeconds = 0;
20
	progressInMilliSeconds = 0;
21
	durationInSeconds = 0;
22
	durationInMilliSeconds = 0;
23
	speed = 1;
24
	speedFactor = 1;
25

26
	if(animation != NULL) {
27
		durationInSeconds = animation->mDuration;
28
		durationInMilliSeconds = durationInSeconds * 1000;
29
	}
30
}
31

32
ofxAssimpAnimation::~ofxAssimpAnimation() {
33
	//
34
}
35

36
aiAnimation * ofxAssimpAnimation::getAnimation() {
37
	return animation;
38
}
39

40
void ofxAssimpAnimation::update() {
41
	animationPrevTime = animationCurrTime;
42
	animationCurrTime = ofGetElapsedTimef();
43
	double tps = animation->mTicksPerSecond ? animation->mTicksPerSecond : 25.f;
44
	animationCurrTime *= tps;
45

46
	if(!bPlay || bPause) {
47
		return;
48
	}
49

50
	float duration = getDurationInSeconds();
51
	float timeStep = animationCurrTime - animationPrevTime;
52
	float positionStep = timeStep / (float)duration;
53
	float position = getPosition() + positionStep * speed * speedFactor;
54

55
	if(position > 1.0 && loopType == OF_LOOP_NONE) {
56
		position = 1.0;
57
		stop();
58
	} else if(position > 1.0 && loopType == OF_LOOP_NORMAL) {
59
		position = fmod(position, 1.0f);
60
	} else if(position > 1.0 && loopType == OF_LOOP_PALINDROME) {
61
		speedFactor *= -1;
62
	} else if(position < 0.0 && loopType == OF_LOOP_PALINDROME) {
63
		speedFactor *= -1;
64
	}
65

66
	setPosition(position);
67
}
68

69
void ofxAssimpAnimation::updateAnimationNodes() {
70
	for(unsigned int i=0; i<animation->mNumChannels; i++) {
71
		const aiNodeAnim * channel = animation->mChannels[i];
72
		aiNode * targetNode = scene->mRootNode->FindNode(channel->mNodeName);
73

74
		aiVector3D presentPosition(0, 0, 0);
75
		if(channel->mNumPositionKeys > 0) {
76
			unsigned int frame = 0;
77
			while(frame < channel->mNumPositionKeys - 1) {
78
				if(progressInSeconds < channel->mPositionKeys[frame+1].mTime) {
79
					break;
80
				}
81
				frame++;
82
			}
83

84
			unsigned int nextFrame = (frame + 1) % channel->mNumPositionKeys;
85
			const aiVectorKey & key = channel->mPositionKeys[frame];
86
			const aiVectorKey & nextKey = channel->mPositionKeys[nextFrame];
87
			double diffTime = nextKey.mTime - key.mTime;
88
			if(diffTime < 0.0) {
89
				diffTime += getDurationInSeconds();
90
			}
91
			if(diffTime > 0) {
92
				float factor = float((progressInSeconds - key.mTime) / diffTime);
93
				presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
94
			} else {
95
				presentPosition = key.mValue;
96
			}
97
		}
98

99
		aiQuaternion presentRotation(1, 0, 0, 0);
100
		if(channel->mNumRotationKeys > 0) {
101
			unsigned int frame = 0;
102
			while(frame < channel->mNumRotationKeys - 1) {
103
				if(progressInSeconds < channel->mRotationKeys[frame+1].mTime) {
104
					break;
105
				}
106
				frame++;
107
			}
108

109
			unsigned int nextFrame = (frame + 1) % channel->mNumRotationKeys;
110
			const aiQuatKey& key = channel->mRotationKeys[frame];
111
			const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame];
112
			double diffTime = nextKey.mTime - key.mTime;
113
			if(diffTime < 0.0) {
114
				diffTime += getDurationInSeconds();
115
			}
116
			if(diffTime > 0) {
117
				float factor = float((progressInSeconds - key.mTime) / diffTime);
118
				aiQuaternion::Interpolate(presentRotation, key.mValue, nextKey.mValue, factor);
119
			} else {
120
				presentRotation = key.mValue;
121
			}
122
		}
123

124
		aiVector3D presentScaling(1, 1, 1);
125
		if(channel->mNumScalingKeys > 0) {
126
			unsigned int frame = 0;
127
			while(frame < channel->mNumScalingKeys - 1){
128
				if(progressInSeconds < channel->mScalingKeys[frame+1].mTime) {
129
					break;
130
				}
131
				frame++;
132
			}
133

134
			presentScaling = channel->mScalingKeys[frame].mValue;
135
		}
136

137
		aiMatrix4x4 mat = aiMatrix4x4(presentRotation.GetMatrix());
138
		mat.a1 *= presentScaling.x; mat.b1 *= presentScaling.x; mat.c1 *= presentScaling.x;
139
		mat.a2 *= presentScaling.y; mat.b2 *= presentScaling.y; mat.c2 *= presentScaling.y;
140
		mat.a3 *= presentScaling.z; mat.b3 *= presentScaling.z; mat.c3 *= presentScaling.z;
141
		mat.a4 = presentPosition.x; mat.b4 = presentPosition.y; mat.c4 = presentPosition.z;
142

143
		targetNode->mTransformation = mat;
144
	}
145
}
146

147
void ofxAssimpAnimation::play() {
148
	if(animation == NULL) {
149
		return;
150
	}
151
	if(bPlay) { // if already playing, ignore.
152
		bPause = false; // if paused, then unpause.
153
		return;
154
	}
155
	bPlay = true;
156
	bPause = false;
157

158
	setPosition(0);
159
}
160

161
void ofxAssimpAnimation::stop() {
162
	speedFactor = 1.0;
163
	if(!bPlay) {
164
		return;
165
	}
166
	bPlay = false;
167
	bPause = false;
168
}
169

170
void ofxAssimpAnimation::reset() {
171
	speedFactor = 1.0;
172
	setPosition(0);
173
}
174

175
bool ofxAssimpAnimation::isFrameNew() {
176
	return (bPlay && !bPause); // assume its always a new frame when playing and not paused.
177
}
178

179
bool ofxAssimpAnimation::isPaused() {
180
	return bPause;
181
}
182

183
bool ofxAssimpAnimation::isPlaying() {
184
	return bPlay;
185
}
186

187
bool ofxAssimpAnimation::isFinished() {
188
	return !bPlay && (getPosition() == 1.0);
189
}
190

191
float ofxAssimpAnimation::getPosition() {
192
	return progress;
193
}
194

195
float ofxAssimpAnimation::getPositionInSeconds() {
196
	return progressInSeconds;
197
}
198

199
int ofxAssimpAnimation::getPositionInMilliSeconds() {
200
	return progressInMilliSeconds;
201
}
202

203
float ofxAssimpAnimation::getSpeed() {
204
	return speed;
205
}
206

207
float ofxAssimpAnimation::getDurationInSeconds() {
208
	return durationInSeconds;
209
}
210

211
int ofxAssimpAnimation::getDurationInMilliSeconds() {
212
	return durationInMilliSeconds;
213
}
214

215
void ofxAssimpAnimation::setPaused(bool paused) {
216
	bPause = paused;
217
}
218

219
void ofxAssimpAnimation::setPosition(float position) {
220
	position = ofClamp(position, 0.0f, 1.0f);
221
	if(progress == position) {
222
		return;
223
	}
224
	progress = position;
225
	progressInSeconds = progress * getDurationInSeconds();
226
	progressInMilliSeconds = progress * getDurationInMilliSeconds();
227

228
	updateAnimationNodes();
229
}
230

231
void ofxAssimpAnimation::setLoopState(ofLoopType state) {
232
	loopType = state;
233
}
234

235
void ofxAssimpAnimation::setSpeed(float s) {
236
	speed = s;
237
}
238

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.