forked from g3n/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
animation.go
148 lines (114 loc) · 3.42 KB
/
animation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2016 The G3N Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package animation
package animation
// Animation is a keyframe animation, containing channels.
// Each channel animates a specific property of an object.
// Animations can span multiple objects and properties.
type Animation struct {
name string // Animation name
loop bool // Whether the animation loops
paused bool // Whether the animation is paused
start float32 // Initial time offset value
time float32 // Total running time
minTime float32 // Minimum time value across all channels
maxTime float32 // Maximum time value across all channels
speed float32 // Animation speed multiplier
channels []IChannel // List of channels
}
// NewAnimation creates and returns a pointer to a new Animation object.
func NewAnimation() *Animation {
anim := new(Animation)
anim.speed = 1
return anim
}
// SetName sets the animation name.
func (anim *Animation) SetName(name string) {
anim.name = name
}
// Name returns the animation name.
func (anim *Animation) Name() string {
return anim.name
}
// SetSpeed sets the animation speed.
func (anim *Animation) SetSpeed(speed float32) {
anim.speed = speed
}
// Speed returns the animation speed.
func (anim *Animation) Speed() float32 {
return anim.speed
}
// Reset resets the animation to the beginning.
func (anim *Animation) Reset() {
anim.time = anim.start
// Update all channels
for i := range anim.channels {
ch := anim.channels[i]
ch.Update(anim.start)
}
}
// SetPaused sets whether the animation is paused.
func (anim *Animation) SetPaused(state bool) {
anim.paused = state
}
// Paused returns whether the animation is paused.
func (anim *Animation) Paused() bool {
return anim.paused
}
// SetLoop sets whether the animation is looping.
func (anim *Animation) SetLoop(state bool) {
anim.loop = state
}
// Loop returns whether the animation is looping.
func (anim *Animation) Loop() bool {
return anim.loop
}
// SetStart sets the initial time offset value.
func (anim *Animation) SetStart(v float32) {
anim.start = v
}
// Update interpolates and updates the target values for each channel.
// If the animation is paused, returns false. If the animation is not paused,
// returns true if the input value is inside the key frames ranges or false otherwise.
func (anim *Animation) Update(delta float32) {
// Check if paused
if anim.paused {
return
}
// Check if input is less than minimum
anim.time = anim.time + delta * anim.speed
if anim.time < anim.minTime {
return
}
// Check if input is greater than maximum
if anim.time > anim.maxTime {
if anim.loop {
anim.time = anim.time - anim.maxTime
} else {
anim.time = anim.maxTime - 0.000001
anim.SetPaused(true)
}
}
// Update all channels
for i := range anim.channels {
ch := anim.channels[i]
ch.Update(anim.time)
}
}
// AddChannel adds a channel to the animation.
func (anim *Animation) AddChannel(ch IChannel) {
// TODO (maybe) prevent user from adding two channels of the same type that share target ?
// Add the channel
anim.channels = append(anim.channels, ch)
// Update maxTime and minTime values
kf := ch.Keyframes()
firstTime := kf[0]
if anim.minTime > firstTime {
anim.minTime = firstTime
}
lastTime := kf[len(kf)-1]
if anim.maxTime < lastTime {
anim.maxTime = lastTime
}
}