1+ pc . anim . InterpolatedKey = function InterpolatedKey ( ) {
2+ this . _keyFrames = [ ] ;
3+
4+ // Result of interpolation
5+ this . _quat = pc . math . quat . create ( 0 , 0 , 0 , 0 ) ;
6+ this . _pos = pc . math . vec3 . create ( 0 , 0 , 0 ) ;
7+ this . _scale = pc . math . vec3 . create ( 0 , 0 , 0 ) ;
8+
9+ // Optional destination for interpolated keyframe
10+ this . _targetNode = null ;
11+ }
12+
13+ pc . anim . InterpolatedKey . prototype . getTarget = function ( ) {
14+ return this . _targetNode ;
15+ }
16+
17+ pc . anim . InterpolatedKey . prototype . setTarget = function ( node ) {
18+ this . _targetNode = node ;
19+ }
20+
21+ pc . extend ( pc . anim , function ( ) {
22+ /**
23+ * @name pc.anim.Skeleton
24+ * @class A skeleton.
25+ */
26+ var Skeleton = function Skeleton ( numNodes ) {
27+ this . _animation = null ;
28+ this . _time = 0 ;
29+ this . _interpolatedKeys = [ ] ;
30+ for ( var i = 0 ; i < numNodes ; i ++ ) {
31+ this . _interpolatedKeys [ i ] = new pc . anim . InterpolatedKey ( ) ;
32+ }
33+ this . looping = true ;
34+ } ;
35+
36+ /**
37+ * @function
38+ * @name pc.anim.Skeleton#addTime
39+ * @description
40+ * @param {number } delta
41+ * @author Will Eastcott
42+ */
43+ Skeleton . prototype . addTime = function ( delta ) {
44+ if ( this . _animation !== null ) {
45+ this . _time += delta ;
46+ var duration = this . _animation . getDuration ( ) ;
47+ if ( this . _time > duration ) {
48+ this . _time = this . looping ? 0.0 : duration ;
49+ }
50+
51+ var nodes = this . _animation . getNodes ( ) ;
52+ for ( var i = 0 ; i < nodes . length ; i ++ ) {
53+ var keys = nodes [ i ] ;
54+
55+ // Find keyframe pair
56+ for ( var currKeyIndex = 0 ; currKeyIndex < keys . length - 1 ; currKeyIndex ++ ) {
57+ var k1 = keys [ currKeyIndex ] ;
58+ var k2 = keys [ currKeyIndex + 1 ] ;
59+
60+ if ( ( k1 . _time <= this . _time ) && ( k2 . _time >= this . _time ) ) {
61+ var alpha = ( this . _time - k1 . _time ) / ( k2 . _time - k1 . _time ) ;
62+
63+ pc . math . quat . slerp ( k1 . _quat , k2 . _quat , alpha , this . _interpolatedKeys [ i ] . _quat ) ;
64+ pc . math . vec3 . lerp ( k1 . _pos , k2 . _pos , alpha , this . _interpolatedKeys [ i ] . _pos ) ;
65+ pc . math . vec3 . lerp ( k1 . _scale , k2 . _scale , alpha , this . _interpolatedKeys [ i ] . _scale ) ;
66+ }
67+ }
68+ }
69+ }
70+ } ;
71+
72+ /**
73+ * @function
74+ * @name pc.anim.Skeleton#blend
75+ * @description Blends two skeletons together.
76+ * @param {pc.anim.Skeleton } a Skeleton holding the first pose to be blended.
77+ * @param {pc.anim.Skeleton } b Skeleton holding the second pose to be blended.
78+ * @author Will Eastcott
79+ */
80+ Skeleton . prototype . blend = function ( a , b , alpha ) {
81+ var numNodes = this . _interpolatedKeys . length ;
82+ for ( var i = 0 ; i < numNodes ; i ++ ) {
83+ pc . math . quat . slerp ( a . _interpolatedKeys [ i ] . _quat , b . _interpolatedKeys [ i ] . _quat , alpha , this . _interpolatedKeys [ i ] . _quat ) ;
84+ pc . math . vec3 . lerp ( a . _interpolatedKeys [ i ] . _pos , b . _interpolatedKeys [ i ] . _pos , alpha , this . _interpolatedKeys [ i ] . _pos ) ;
85+ pc . math . vec3 . lerp ( a . _interpolatedKeys [ i ] . _scale , b . _interpolatedKeys [ i ] . _scale , alpha , this . _interpolatedKeys [ i ] . _scale ) ;
86+ }
87+ } ;
88+
89+ /**
90+ * @function
91+ * @name pc.anim.Skeleton#getAnimation
92+ * @description
93+ * @returns {pc.anim.Animation }
94+ * @author Will Eastcott
95+ */
96+ Skeleton . prototype . getAnimation = function ( ) {
97+ return this . _animation ;
98+ } ;
99+
100+ /**
101+ * @function
102+ * @name pc.anim.Skeleton#getCurrentTime
103+ * @description Returns the current time of the currently active animation as set on
104+ * the specified skeleton. This value will be between zero and the duration of the
105+ * animation.
106+ * @returns {number } The current time of the animation set on the skeleton.
107+ * @author Will Eastcott
108+ */
109+ Skeleton . prototype . getCurrentTime = function ( ) {
110+ return this . _time ;
111+ }
112+
113+ /**
114+ * @function
115+ * @name pc.anim.Skeleton#setCurrentTime
116+ * @description Sets the current time of the currently active animation as set on
117+ * the specified skeleton. This value must be between zero and the duration of the
118+ * animation.
119+ * @param {number } The current time of the animation set on the skeleton.
120+ * @author Will Eastcott
121+ */
122+ Skeleton . prototype . setCurrentTime = function ( time ) {
123+ this . _time = time ;
124+ }
125+
126+ /**
127+ * @function
128+ * @name pc.anim.Skeleton#getNumNodes
129+ * @description Returns the number of nodes held by the specified skeleton.
130+ * @returns {number } The number of nodes held by the specified skeleton.
131+ * @author Will Eastcott
132+ */
133+ Skeleton . prototype . getNumNodes = function ( ) {
134+ return this . _interpolatedKeys . length ;
135+ }
136+
137+ /**
138+ * @function
139+ * @name pc.anim.Skeleton#setAnimation
140+ * @description
141+ * @param {pc.anim.Animation } animation
142+ * @author Will Eastcott
143+ */
144+ Skeleton . prototype . setAnimation = function ( animation ) {
145+ this . _animation = animation ;
146+ this . _time = 0 ;
147+ } ;
148+
149+ /**
150+ * @function
151+ * @name pc.anim.Skeleton#setGraph
152+ * @description
153+ * @param {pc.scene.GraphNode } graph
154+ * @author Will Eastcott
155+ */
156+ Skeleton . prototype . setGraph = function ( graph ) {
157+ var nodeIndex = 0 ;
158+ var setGraph = function ( skeleton , node ) {
159+ skeleton . _interpolatedKeys [ nodeIndex ++ ] . setTarget ( node ) ;
160+ var children = node . getChildren ( ) ;
161+ for ( var i = 0 ; i < children . length ; i ++ ) {
162+ setGraph ( skeleton , children [ i ] ) ;
163+ }
164+ }
165+ setGraph ( this , graph ) ;
166+ } ;
167+
168+ /**
169+ * @function
170+ * @name pc.anim.Skeleton#updateGraph
171+ * @description
172+ * @author Will Eastcott
173+ */
174+ Skeleton . prototype . updateGraph = function ( ) {
175+ logASSERT ( ( this . _animation !== null ) , "Skeleton requires an animation in order to update a scene graph" ) ;
176+
177+ var nodes = this . _animation . getNodes ( ) ;
178+ for ( var i = 0 ; i < nodes . length ; i ++ ) {
179+ if ( nodes [ i ] . length > 0 ) {
180+ var interpKey = this . _interpolatedKeys [ i ] ;
181+
182+ var ltm = interpKey . getTarget ( ) . getLocalTransform ( ) ;
183+ pc . math . quat . toMat4 ( interpKey . _quat , ltm ) ;
184+ ltm [ 0 ] *= interpKey . _scale [ 0 ] ;
185+ ltm [ 4 ] *= interpKey . _scale [ 0 ] ;
186+ ltm [ 8 ] *= interpKey . _scale [ 0 ] ;
187+ ltm [ 1 ] *= interpKey . _scale [ 1 ] ;
188+ ltm [ 5 ] *= interpKey . _scale [ 1 ] ;
189+ ltm [ 9 ] *= interpKey . _scale [ 1 ] ;
190+ ltm [ 2 ] *= interpKey . _scale [ 2 ] ;
191+ ltm [ 6 ] *= interpKey . _scale [ 2 ] ;
192+ ltm [ 10 ] *= interpKey . _scale [ 2 ] ;
193+ ltm [ 12 ] = interpKey . _pos [ 0 ] ;
194+ ltm [ 13 ] = interpKey . _pos [ 1 ] ;
195+ ltm [ 14 ] = interpKey . _pos [ 2 ] ;
196+ }
197+ }
198+ } ;
199+
200+ /**
201+ * @function
202+ * @name pc.anim.Skeleton#setLooping
203+ * @param looping {boolean}
204+ * @description
205+ * @author Will Eastcott
206+ */
207+ Skeleton . prototype . setLooping = function ( looping ) {
208+ this . looping = looping ;
209+ } ;
210+
211+ /**
212+ * @function
213+ * @name pc.anim.Skeleton#getLooping
214+ * @return {boolean }
215+ * @description
216+ * @author Will Eastcott
217+ */
218+ Skeleton . prototype . getLooping = function ( ) {
219+ return this . looping ;
220+ } ;
221+
222+ return {
223+ Skeleton : Skeleton
224+ } ;
225+ } ( ) ) ;
0 commit comments