]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/anim/keyframe.qc
Merge branch 'master' into Mario/bulldozer
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / anim / keyframe.qc
1 #ifndef ANIM_KEYFRAME_H
2         #define ANIM_KEYFRAME_H
3         #include "animation.qc"
4         CLASS(Keyframe, Animation)
5                 METHOD(Keyframe, addEasing, entity(entity, float, float, float(float, float, float, float)));
6                 METHOD(Keyframe, addAnim, void(entity, entity));
7                 METHOD(Keyframe, calcValue, float(entity, float, float, float, float));
8                 ATTRIB(Keyframe, currentChild, entity, NULL)
9                 ATTRIB(Keyframe, firstChild, entity, NULL)
10                 ATTRIB(Keyframe, lastChild, entity, NULL)
11         ENDCLASS(Keyframe)
12         entity makeHostedKeyframe(entity, void(entity, float), float, float, float);
13         entity makeKeyframe(entity, void(entity, float), float, float, float);
14         float getNewChildStart(entity);
15         float getNewChildDuration(entity, float);
16         float getNewChildValue(entity);
17 #endif
18
19 #ifdef IMPLEMENTATION
20         entity makeHostedKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd)
21         {
22                 entity this = makeKeyframe(obj, objSetter, animDuration, animStart, animEnd);
23                 anim.addAnim(anim, this);
24                 return this;
25         }
26
27         entity makeKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd)
28         {
29                 entity this = NEW(Keyframe);
30                 this.configureAnimation(this, obj, objSetter, time, animDuration, animStart, animEnd);
31                 return this;
32         }
33
34         METHOD(Keyframe, addEasing, entity(entity this, float animDurationTime, float animEnd, float(float, float, float, float) func))
35         {
36                 entity other = makeEasing(this.object, this.setter, func, getNewChildStart(this), getNewChildDuration(this, animDurationTime), getNewChildValue(this), animEnd);
37                 this.addAnim(this, other);
38                 return other;
39         }
40
41         float getNewChildStart(entity this)
42         {
43                 if (this.lastChild) return this.lastChild.startTime + this.lastChild.duration;
44                 else return 0;
45         }
46
47         float getNewChildDuration(entity this, float durationTime)
48         {
49                 float maxDura = this.duration;
50                 if (this.lastChild) maxDura = maxDura - (this.lastChild.startTime + this.lastChild.duration);
51                 float dura = durationTime;
52                 if (0 >= dura || dura > maxDura) dura = maxDura;
53                 return dura;
54         }
55
56         float getNewChildValue(entity this)
57         {
58                 if (this.lastChild) return this.lastChild.startValue + this.lastChild.delta;
59                 else return this.startValue;
60         }
61
62         METHOD(Keyframe, addAnim, void(entity this, entity other))
63         {
64                 if (other.parent) error("Can't add already added anim!");
65
66                 if (other.isFinished(other)) error("Can't add finished anim!");
67
68                 other.parent = this;
69
70                 entity l = this.lastChild;
71
72                 if (l)
73                 {
74                         l.nextSibling = other;
75                 }
76                 else
77                 {
78                         this.currentChild = other;
79                         this.firstChild = other;
80                 }
81
82                 other.prevSibling = l;
83                 other.nextSibling = NULL;
84                 this.lastChild = other;
85         }
86
87         METHOD(Keyframe, calcValue, float(entity this, float tickTime, float animDuration, float animStartValue, float animDelta))
88         {
89                 if (this.currentChild)
90                         if (this.currentChild.isFinished(this.currentChild)) this.currentChild = this.currentChild.nextSibling;
91
92                 if (this.currentChild)
93                 {
94                         this.currentChild.tick(this.currentChild, tickTime);
95                         return this.currentChild.value;
96                 }
97
98                 return animStartValue + animDelta;
99         }
100 #endif