Ogre实现不同动画之间的混合.docx
- 文档编号:7757188
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:28
- 大小:21.93KB
Ogre实现不同动画之间的混合.docx
《Ogre实现不同动画之间的混合.docx》由会员分享,可在线阅读,更多相关《Ogre实现不同动画之间的混合.docx(28页珍藏版)》请在冰豆网上搜索。
Ogre实现不同动画之间的混合
动画混合--实现两个动画的切换,一个动画逐渐消逝,另一个动画逐渐显示来实现.主要通过动画状态的权重来实现
通过三种方式来实现两个动画的混合:
-BlendSwitch-直接切换至目标动画
-BlendWhileAnimating-混合的过程中目标动画也更新帧,实现动画
-BlendThenAnimate-用源动画的当前帧混合目标动画的第一个帧
源码理解,主要代码位于下面两个函数
AnimationBlender:
:
blend函数根据传入的参数设置新转换的源动画和目标动画
AnimationBlender:
:
add函数则更新源动画和目标动画(如存在)的状态和权重
AnimationBlender:
:
blend函数
1.如果动画转换类型为AnimationBlender:
:
BlendSwitch
直接将源动画转换成目标动画
2.如果不是这个转换类型AnimationBlender:
:
BlendSwitch
如果上次的动画转换还未完成
如果新的目标动画等于上次转换的源动画
则反向转换
如果新的目标动画不等于上次转换的源动画和目标动画
根据上次转换的剩余时间设置是显示上次转换的源动画还是目标动画,并将其设置为新转换的源动画
显示新转换的目标动画,并设置其权重
假设上次的动画转换已经完成了转换
设置转换时间,转换类型,目标动画和其权重
AnimationBlender:
:
addTime函数
1.如有动画在运行
如果存在转换
更新剩余时间
如剩余时间小于0
禁止源动画
将目标动画设置为源动画,继续运行
如剩余时间不小于0
更新源动画和目标动画的权重
如转换类型为AnimationBlender:
:
BlendWhileAnimating
更新目标动画
判断动画是否完成
更新源动画
完整代码和Demo代码
AnimationBlender.h
[cpp]viewplaincopyprint?
1.#ifndef __ANIMATION_BLENDER_H__
2.
3.#define __ANIMATION_BLENDER_H__
4.
5.#include
6.
7.usingnamespace Ogre;
8.
9.classAnimationBlender
10.
11.{
12.
13.public:
14.
15. enumBlendingTransition
16.
17. {
18.
19. BlendSwitch, // stop source and start dest
20.
21. BlendWhileAnimating, // cross fade, blend source animation out while blending destination animation in
22.
23. BlendThenAnimate // blend source to first frame of dest, when done, start dest anim
24.
25. };
26.
27.private:
28.
29. Entity *mEntity;
30.
31. AnimationState *mSource;
32.
33. AnimationState *mTarget;
34.
35. BlendingTransition mTransition;
36.
37. boolloop;
38.
39. ~AnimationBlender() {}
40.
41.public:
42.
43. Real mTimeleft, mDuration;
44.
45. boolcomplete;
46.
47. voidblend( constString &animation, BlendingTransition transition, Real duration,bool l=true);
48.
49. voidaddTime( Real );
50.
51. Real getProgress() {return mTimeleft/ mDuration; }
52.
53. AnimationState *getSource() {return mSource; }
54.
55. AnimationState *getTarget() {return mTarget; }
56.
57. AnimationBlender( Entity *);
58.
59. voidinit( const String &animation, bool l=true );
60.
61.};
62.
63.#endif
#ifndef__ANIMATION_BLENDER_H__
#define__ANIMATION_BLENDER_H__
#include
usingnamespaceOgre;
classAnimationBlender
{
public:
enumBlendingTransition
{
BlendSwitch,//stopsourceandstartdest
BlendWhileAnimating,//crossfade,blendsourceanimationoutwhileblendingdestinationanimationin
BlendThenAnimate//blendsourcetofirstframeofdest,whendone,startdestanim
};
private:
Entity*mEntity;
AnimationState*mSource;
AnimationState*mTarget;
BlendingTransitionmTransition;
boolloop;
~AnimationBlender(){}
public:
RealmTimeleft,mDuration;
boolcomplete;
voidblend(constString&animation,BlendingTransitiontransition,Realduration,booll=true);
voidaddTime(Real);
RealgetProgress(){returnmTimeleft/mDuration;}
AnimationState*getSource(){returnmSource;}
AnimationState*getTarget(){returnmTarget;}
AnimationBlender(Entity*);
voidinit(constString&animation,booll=true);
};
#endif
AnimationBlender.cpp
[cpp]viewplaincopyprint?
1.#include "AnimationBlender.h"
2.
3.void AnimationBlender:
:
init(const String &animation, bool l)
4.
5.{
6.
7. // 初始化, 将所有的动画禁止, 只允许参数中的动画运行.
8.
9. AnimationStateSet *set = mEntity->getAllAnimationStates();
10.
11. AnimationStateIterator it = set->getAnimationStateIterator();
12.
13. while(it.hasMoreElements())
14.
15. {
16.
17. AnimationState *anim = it.getNext();
18.
19. anim->setEnabled(false);
20.
21. anim->setWeight(0);
22.
23. anim->setTimePosition(0);
24.
25. }
26.
27. mSource = mEntity->getAnimationState( animation );
28.
29. mSource->setEnabled(true);
30.
31. mSource->setWeight
(1);
32.
33. mTimeleft = 0;
34.
35. mDuration = 1;
36.
37. mTarget = 0;
38.
39. complete =false;
40.
41. loop = l;
42.
43.}
44.
45.voidAnimationBlender:
:
blend( constString &animation, BlendingTransition transition, Real duration,bool l )
46.
47.{
48.
49. loop = l;
50.
51. if( transition == AnimationBlender:
:
BlendSwitch )
52.
53. {
54.
55. if( mSource !
= 0 )
56.
57. mSource->setEnabled(false);
58.
59. mSource = mEntity->getAnimationState( animation );
60.
61. mSource->setEnabled(true);
62.
63. mSource->setWeight
(1);
64.
65. mSource->setTimePosition(0);
66.
67. mTimeleft = 0;
68.
69. }
70.
71. else
72.
73. {
74.
75. AnimationState *newTarget = mEntity->getAnimationState( animation );
76.
77. if( mTimeleft > 0 )
78.
79. {
80.
81. // oops, weren't finished yet
82.
83. if( newTarget == mTarget )
84.
85. {
86.
87. // nothing to do!
(ignoring duration here)
88.
89. }
90.
91. else if( newTarget == mSource )
92.
93. {
94.
95. // going back to the source state, so let's switch
96.
97. mSource = mTarget;
98.
99. mTarget = newTarget;
100.
101. mTimeleft = mDuration - mTimeleft; // i'm ignoring the new duration here
102.
103. }
104.
105. else
106.
107. {
108.
109. // ok, newTarget is really new, so either we simply replace the target with this one, or
110.
111. // we make the target the new source
112.
113. if( mTimeleft < mDuration * 0.5 )
114.
115. {
116.
117. // simply replace the target with this one
118.
119. mTarget->setEnabled(false);
120.
121. mTarget->setWeight(0);
122.
123. }
124.
125. else
126.
127. {
128.
129. // old target becomes new source
130.
131. mSource->setEnabled(false);
132.
133. mSource->setWeight(0);
134.
135. mSource = mTarget;
136.
137. }
138.
139. mTarget = newTarget;
140.
141. mTarget->setEnabled(true);
142.
143. mTarget->setWeight( 1.0 - mTimeleft / mDuration );
144.
145. mTarget->setTimePosition(0);
146.
147. }
148.
149. }
150.
151. else
152.
153. {
154.
155. // assert( target == 0, "target should be 0 when not blending" )
156.
157. // mSource->setEnabled(true);
158.
159. // mSource->setWeight
(1);
160.
161. mTransition = transition;
162.
163. mTimeleft = mDuration = duration;
164.
165. mTarget = newTarget;
166.
167. mTarget->setEnabled(true);
168.
169. mTarget->setWeight(0);
170.
171. mTarget->setTimePosition(0);
172.
173. }
174.
175. }
176.
177.}
178.
179.voidAnimationBlender:
:
addTime( Real time)
180.
181.{
182.
183. if( mSource !
= 0 )
184.
185. {
186.
187. if( mTimeleft > 0 )
188.
189. {
190.
191. mTimeleft -= time;
192.
193. if( mTimeleft < 0 )
194.
195. {
196.
197. // finish blending
198.
199. mSource->setEnabled(false);
200.
201. mSource->setWeight(0);
202.
203. mSource = mTarget;
204.
205. mSource->setEnabled(true);
206.
207. mSource->setWeight
(1);
208.
209. mTarget = 0;
210.
211. }
212.
213. else
214.
215. {
216.
217. // still blending, advance weights
218.
219. mSource->setWeight(mTimeleft / mDuration);
220.
221. mTarget->setWeight(1.0 - mTimeleft / mDuration);
222.
223. if(mTransition == AnimationBlender:
:
BlendWhileAnimating)
224.
225. mTarget->addTime(time);
226.
227. }
228.
229. }
230.
231. if (mSource->getTimePosition() >= mSource->getLength())
232.
233. {
234.
235. complete = true;
236.
237. }
238.
239. else
240.
241. {
242.
243. complete = false;
244.
245. }
246.
247. mSource->addTime(time);
248.
249. mSource->setLoop(loop);
250.
251. }
252.
253.}
254.
255.AnimationBlender:
:
AnimationBlender( Entity *entity ) :
mEntity(entity)
256.
257.{
258.
259.}
#include"AnimationBlender.h"
voidAnimationBlender:
:
init(constString&animation,booll)
{
//初始化,将所有的动画禁止,只允许参数
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Ogre 实现 不同 动画 之间 混合