channel.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package animation
  5. import (
  6. "github.com/g3n/engine/core"
  7. "github.com/g3n/engine/math32"
  8. )
  9. // A Channel associates an animation parameter channel to an interpolation sampler
  10. type Channel struct {
  11. keyframes math32.ArrayF32 // Input keys (usually time)
  12. values math32.ArrayF32 // Outputs values for the keys
  13. interpType InterpolationType // Interpolation type
  14. interpAction func(idx int, k float32) // Combined function for interpolation and update
  15. updateInterpAction func() // Function to update interpAction based on interpolation type
  16. inTangent math32.ArrayF32 // Origin tangents for Spline interpolation
  17. outTangent math32.ArrayF32 // End tangents for Spline interpolation
  18. }
  19. // SetBuffers sets the keyframe and value buffers.
  20. func (c *Channel) SetBuffers(keyframes, values math32.ArrayF32) {
  21. c.keyframes = keyframes
  22. c.values = values
  23. }
  24. // Keyframes returns the keyframe buffer.
  25. func (c *Channel) Keyframes() math32.ArrayF32 {
  26. return c.keyframes
  27. }
  28. // Values returns the value buffer.
  29. func (c *Channel) Values() math32.ArrayF32 {
  30. return c.values
  31. }
  32. // SetInterpolationTangents sets the interpolation tangents.
  33. func (c *Channel) SetInterpolationTangents(inTangent, outTangent math32.ArrayF32) {
  34. c.inTangent = inTangent
  35. c.outTangent = outTangent
  36. }
  37. // InterpolationTangents sets the interpolation tangents
  38. func (c *Channel) InterpolationTangents() (inTangent, outTangent math32.ArrayF32) {
  39. return c.inTangent, c.outTangent
  40. }
  41. // SetInterpolationType sets the interpolation type for this channel.
  42. func (c *Channel) SetInterpolationType(it InterpolationType) {
  43. // Don't update function if not needed
  44. if c.interpType == it {
  45. return
  46. }
  47. // Save interpolation type
  48. c.interpType = it
  49. // Call specialized function that updates the interpAction function
  50. c.updateInterpAction()
  51. }
  52. // InterpolationType returns the current interpolation type.
  53. func (c *Channel) InterpolationType() InterpolationType {
  54. return c.interpType
  55. }
  56. // Update finds the keyframe preceding the specified time.
  57. // Then, calls a stored function to interpolate the relevant values and update the target.
  58. func (c *Channel) Update(time float32) {
  59. // Test limits
  60. if (len(c.keyframes) < 2) || (time < c.keyframes[0]) || (time > c.keyframes[len(c.keyframes)-1]) {
  61. return
  62. }
  63. // Find key frame interval
  64. var idx int
  65. for idx = 0; idx < len(c.keyframes)-1; idx++ {
  66. if time >= c.keyframes[idx] && time < c.keyframes[idx+1] {
  67. break
  68. }
  69. }
  70. // Check if last keyframe
  71. if idx >= len(c.keyframes)-1 {
  72. return
  73. }
  74. // Interpolate and update
  75. relativeDelta := (time-c.keyframes[idx])/(c.keyframes[idx+1]-c.keyframes[idx])
  76. c.interpAction(idx, relativeDelta)
  77. }
  78. // IChannel is the interface for all channel types.
  79. type IChannel interface {
  80. Update(time float32)
  81. Keyframes() math32.ArrayF32
  82. Values() math32.ArrayF32
  83. SetInterpolationType(it InterpolationType)
  84. }
  85. // NodeChannel is the IChannel for all node transforms.
  86. type NodeChannel struct {
  87. Channel
  88. target core.INode
  89. }
  90. // PositionChannel is the animation channel for a node's position.
  91. type PositionChannel NodeChannel
  92. func NewPositionChannel(node core.INode) *PositionChannel {
  93. pc := new(PositionChannel)
  94. pc.target = node
  95. pc.updateInterpAction = func() {
  96. // Get node
  97. node := pc.target.GetNode()
  98. // Update interpolation function
  99. switch pc.interpType {
  100. case STEP:
  101. pc.interpAction = func(idx int, k float32) {
  102. var v math32.Vector3
  103. pc.values.GetVector3(idx*3, &v)
  104. node.SetPositionVec(&v)
  105. }
  106. case LINEAR:
  107. pc.interpAction = func(idx int, k float32) {
  108. var v1, v2 math32.Vector3
  109. pc.values.GetVector3(idx*3, &v1)
  110. pc.values.GetVector3((idx+1)*3, &v2)
  111. v1.Lerp(&v2, k)
  112. node.SetPositionVec(&v1)
  113. }
  114. }
  115. }
  116. pc.SetInterpolationType(LINEAR)
  117. return pc
  118. }
  119. // RotationChannel is the animation channel for a node's rotation.
  120. type RotationChannel NodeChannel
  121. func NewRotationChannel(node core.INode) *RotationChannel {
  122. rc := new(RotationChannel)
  123. rc.target = node
  124. rc.updateInterpAction = func() {
  125. // Get node
  126. node := rc.target.GetNode()
  127. // Update interpolation function
  128. switch rc.interpType {
  129. case STEP:
  130. rc.interpAction = func(idx int, k float32) {
  131. var q math32.Vector4
  132. rc.values.GetVector4(idx*4, &q)
  133. node.SetQuaternionVec(&q)
  134. }
  135. case LINEAR:
  136. rc.interpAction = func(idx int, k float32) {
  137. var q1, q2 math32.Vector4
  138. rc.values.GetVector4(idx*4, &q1)
  139. rc.values.GetVector4((idx+1)*4, &q2)
  140. quat1 := math32.NewQuaternion(q1.X, q1.Y, q1.Z, q1.W)
  141. quat2 := math32.NewQuaternion(q2.X, q2.Y, q2.Z, q2.W)
  142. quat1.Slerp(quat2, k)
  143. node.SetQuaternionQuat(quat1)
  144. }
  145. }
  146. }
  147. rc.SetInterpolationType(LINEAR)
  148. return rc
  149. }
  150. // ScaleChannel is the animation channel for a node's scale.
  151. type ScaleChannel NodeChannel
  152. func NewScaleChannel(node core.INode) *ScaleChannel {
  153. sc := new(ScaleChannel)
  154. sc.target = node
  155. sc.updateInterpAction = func() {
  156. // Get node
  157. node := sc.target.GetNode()
  158. // Update interpolation function
  159. switch sc.interpType {
  160. case STEP:
  161. sc.interpAction = func(idx int, k float32) {
  162. var v math32.Vector3
  163. sc.values.GetVector3(idx*3, &v)
  164. node.SetScaleVec(&v)
  165. }
  166. case LINEAR:
  167. sc.interpAction = func(idx int, k float32) {
  168. var v1, v2 math32.Vector3
  169. sc.values.GetVector3(idx*3, &v1)
  170. sc.values.GetVector3((idx+1)*3, &v2)
  171. v1.Lerp(&v2, k)
  172. node.SetScaleVec(&v1)
  173. }
  174. }
  175. }
  176. sc.SetInterpolationType(LINEAR)
  177. return sc
  178. }
  179. // InterpolationType specifies the interpolation type.
  180. type InterpolationType int
  181. // The various interpolation types.
  182. const (
  183. STEP = InterpolationType(iota) // The animated values remain constant to the output of the first keyframe, until the next keyframe.
  184. LINEAR // The animated values are linearly interpolated between keyframes. Spherical linear interpolation (slerp) is used to interpolate quaternions.
  185. CUBICSPLINE // TODO
  186. )