Skip to content

Commit 670b00b

Browse files
author
Avaer Kazmer
committed
Add main files
1 parent 0b18d42 commit 670b00b

File tree

8,816 files changed

+1833539
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

8,816 files changed

+1833539
-0
lines changed

AnimationSystem/AnimationSystem.cc

+1,287
Large diffs are not rendered by default.

AnimationSystem/AnimationSystem.h

+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#ifndef _ANIMATIONSYSTEM_H
2+
#define _ANIMATIONSYSTEM_H
3+
#include "physics.h"
4+
#include <iostream>
5+
#include "nlohmann/json.hpp"
6+
using json = nlohmann::json;
7+
8+
// --- actionInterpolants
9+
class ScalarInterpolant {
10+
public:
11+
bool evaluatee;
12+
float value;
13+
float minValue;
14+
float maxValue;
15+
ScalarInterpolant(float minValue, float maxValue) {
16+
this->value = minValue;
17+
this->minValue = minValue;
18+
this->maxValue = maxValue;
19+
}
20+
virtual float get() {
21+
return this->value;
22+
}
23+
virtual float getNormalized() {
24+
return this->value / (this->maxValue - this->minValue);
25+
}
26+
virtual float getInverse() {
27+
return this->maxValue - this->value;
28+
}
29+
virtual void update(float timeDiff, bool evaluatee) { }
30+
};
31+
class BiActionInterpolant: public ScalarInterpolant {
32+
public:
33+
using ScalarInterpolant::ScalarInterpolant;
34+
void update(float timeDiff, bool evaluatee) {
35+
this->value += (evaluatee ? 1 : -1) * timeDiff;
36+
this->value = fmin(fmax(this->value, this->minValue), this->maxValue);
37+
}
38+
};
39+
class UniActionInterpolant: public ScalarInterpolant {
40+
public:
41+
using ScalarInterpolant::ScalarInterpolant;
42+
void update(float timeDiff, bool evaluatee) {
43+
if (evaluatee) {
44+
this->value += timeDiff;
45+
this->value = fmin(fmax(this->value, this->minValue), this->maxValue);
46+
} else {
47+
this->value = this->minValue;
48+
}
49+
}
50+
};
51+
class InfiniteActionInterpolant: public ScalarInterpolant {
52+
public:
53+
InfiniteActionInterpolant(float minValue): ScalarInterpolant(minValue, std::numeric_limits<float>::infinity()) { }
54+
void update(float timeDiff, bool evaluatee) {
55+
if (evaluatee) {
56+
this->value += timeDiff;
57+
} else {
58+
this->value = this->minValue;
59+
}
60+
}
61+
};
62+
// --- End: actionInterpolants
63+
64+
namespace AnimationSystem {
65+
struct Interpolant;
66+
struct Animation;
67+
struct AnimationMapping;
68+
class Avatar;
69+
class AnimationNode;
70+
class AnimationMixer;
71+
72+
struct Interpolant {
73+
unsigned int numParameterPositions;
74+
float *parameterPositions;
75+
float resultBuffer[4];
76+
unsigned int numSampleValues;
77+
float *sampleValues;
78+
unsigned int valueSize;
79+
};
80+
struct Animation {
81+
float duration;
82+
std::vector<Interpolant *> interpolants;
83+
unsigned int currentInterpolantIndex = 0;
84+
unsigned int index;
85+
std::string name;
86+
};
87+
struct AnimationMapping { // spec
88+
float dst[4];
89+
bool isPosition;
90+
unsigned int index;
91+
std::string boneName;
92+
bool isTop;
93+
bool isArm;
94+
};
95+
96+
class Avatar {
97+
public:
98+
99+
std::unordered_map<std::string, json> actions;
100+
std::unordered_map<std::string, ScalarInterpolant *> actionInterpolants;
101+
102+
AnimationMixer *mixer;
103+
104+
// values
105+
float activateTime;
106+
float landTime;
107+
float fallLoopFactor;
108+
float fallLoopTime;
109+
float flyTime;
110+
float doubleJumpTime;
111+
float jumpTime;
112+
float narutoRunTime;
113+
float danceFactor;
114+
float emoteFactor;
115+
float lastEmoteTime;
116+
float idleWalkFactor;
117+
float useTime;
118+
float useAnimationEnvelopeLength;
119+
float hurtTime;
120+
float unuseTime;
121+
float aimTime;
122+
float aimMaxTime;
123+
float walkRunFactor;
124+
float crouchFactor;
125+
float pickUpTime;
126+
float forwardFactor;
127+
float backwardFactor;
128+
float leftFactor;
129+
float rightFactor;
130+
float mirrorLeftFactorReverse;
131+
float mirrorLeftFactor;
132+
float mirrorRightFactorReverse;
133+
float mirrorRightFactor;
134+
float landTimeS;
135+
float timeSinceLastMoveS;
136+
float swimTime;
137+
float movementsTime;
138+
float sprintFactor;
139+
float movementsTransitionFactor;
140+
141+
// states
142+
bool jumpState;
143+
bool doubleJumpState;
144+
bool flyState;
145+
bool crouchState;
146+
bool narutoRunState;
147+
bool sitState;
148+
bool holdState;
149+
bool pickUpState;
150+
bool swimState;
151+
bool activateState;
152+
bool useState;
153+
bool aimState;
154+
bool fallLoopState;
155+
bool danceState;
156+
bool emoteState;
157+
bool hurtState;
158+
bool rightHandState;
159+
bool leftHandState;
160+
bool sprintState;
161+
bool movementsState;
162+
163+
//
164+
bool landWithMoving;
165+
bool fallLoopFromJump;
166+
167+
int activateAnimationIndex;
168+
int sitAnimationIndex;
169+
int danceAnimationIndex;
170+
int emoteAnimationIndex;
171+
int useAnimationIndex;
172+
int useAnimationComboIndex;
173+
int hurtAnimationIndex;
174+
int unuseAnimationIndex;
175+
int aimAnimationIndex;
176+
177+
std::vector<int> useAnimationEnvelopeIndices;
178+
179+
//
180+
181+
void updateInterpolation(float timeDiff); // note: call before `update()`
182+
void update(float *scratchStack);
183+
void addAction(char *scratchStack, unsigned int stringByteLength);
184+
void removeAction(char *scratchStack, unsigned int stringByteLength);
185+
float getActionInterpolant(char *scratchStack, unsigned int stringByteLength, unsigned int type = 0); // 0: get(), 1: getNormalized(), 2: getInverse()
186+
};
187+
class AnimationMixer {
188+
public:
189+
static float nowS;
190+
191+
Avatar *avatar;
192+
float *animationValues;
193+
194+
float *update(float now, float nowS);
195+
};
196+
197+
// ------
198+
// need run in this order
199+
void createAnimationMapping(bool isPosition, unsigned int index, bool isTop, bool isArm, char *scratchStack, unsigned int nameByteLength);
200+
Animation *createAnimation(char *scratchStack, unsigned int nameByteLength, float duration);
201+
void createAnimationInterpolant(Animation *animation, unsigned int numParameterPositions, float *parameterPositions, unsigned int numSampleValues, float *sampleValues, unsigned int valueSize);
202+
unsigned int initAnimationSystem(char *scratchStack);
203+
AnimationMixer *createAnimationMixer();
204+
Avatar *createAnimationAvatar(AnimationMixer *mixer);
205+
// end: need run in this order
206+
};
207+
208+
#endif // _ANIMATIONSYSTEM_H

AnimationSystem/CubicBezierEasing.h

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#ifndef _CUBIC_BEZIER_EASING_H
2+
#define _CUBIC_BEZIER_EASING_H
3+
// #pragma once
4+
namespace CubicBezierEasing {
5+
6+
/**
7+
* https://github.com/gre/bezier-easing
8+
* BezierEasing - use bezier curve for transition easing function
9+
* by Gaëtan Renaudeau 2014 - 2015 – MIT License
10+
*/
11+
12+
// These values are established by empiricism with tests (tradeoff: performance VS precision)
13+
unsigned int NEWTON_ITERATIONS = 4;
14+
float NEWTON_MIN_SLOPE = 0.001;
15+
float SUBDIVISION_PRECISION = 0.0000001;
16+
unsigned int SUBDIVISION_MAX_ITERATIONS = 10;
17+
18+
unsigned int kSplineTableSize = 11;
19+
float kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
20+
21+
// cache init() reaults
22+
float _mX1, _mX2, _mY1, _mY2;
23+
float *sampleValues;
24+
bool isLinearEasing;
25+
// end: cache init() reaults
26+
27+
float A (float aA1, float aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
28+
float B (float aA1, float aA2) { return 3.0 * aA2 - 6.0 * aA1; }
29+
float C (float aA1) { return 3.0 * aA1; }
30+
31+
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
32+
float calcBezier (float aT, float aA1, float aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
33+
34+
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
35+
float getSlope (float aT, float aA1, float aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
36+
37+
float binarySubdivide (float aX, float aA, float aB, float mX1, float mX2) {
38+
float currentX, currentT, i = 0;
39+
do {
40+
currentT = aA + (aB - aA) / 2.0;
41+
currentX = calcBezier(currentT, mX1, mX2) - aX;
42+
if (currentX > 0.0) {
43+
aB = currentT;
44+
} else {
45+
aA = currentT;
46+
}
47+
} while (abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
48+
return currentT;
49+
}
50+
51+
float newtonRaphsonIterate (float aX, float aGuessT, float mX1, float mX2) {
52+
for (unsigned int i = 0; i < NEWTON_ITERATIONS; ++i) {
53+
float currentSlope = getSlope(aGuessT, mX1, mX2);
54+
if (currentSlope == 0.0) {
55+
return aGuessT;
56+
}
57+
float currentX = calcBezier(aGuessT, mX1, mX2) - aX;
58+
aGuessT -= currentX / currentSlope;
59+
}
60+
return aGuessT;
61+
}
62+
63+
float LinearEasing (float x) {
64+
return x;
65+
}
66+
67+
float getTForX (float aX) {
68+
float intervalStart = 0.0;
69+
unsigned int currentSample = 1;
70+
unsigned int lastSample = kSplineTableSize - 1;
71+
72+
for (; currentSample != lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
73+
intervalStart += kSampleStepSize;
74+
}
75+
--currentSample;
76+
77+
// Interpolate to provide an initial guess for t
78+
float dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
79+
float guessForT = intervalStart + dist * kSampleStepSize;
80+
81+
float initialSlope = getSlope(guessForT, _mX1, _mX2);
82+
if (initialSlope >= NEWTON_MIN_SLOPE) {
83+
return newtonRaphsonIterate(aX, guessForT, _mX1, _mX2);
84+
} else if (initialSlope == 0.0) {
85+
return guessForT;
86+
} else {
87+
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, _mX1, _mX2);
88+
}
89+
}
90+
91+
float cubicBezier(float x) {
92+
if (isLinearEasing) {
93+
return LinearEasing(x);
94+
} else {
95+
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
96+
if (x == 0 || x == 1) { // Keep this check to prevent values inputed from js are imprecise ?
97+
return x;
98+
}
99+
return calcBezier(getTForX(x), _mY1, _mY2);
100+
}
101+
}
102+
103+
void init(float mX1, float mY1, float mX2, float mY2) {
104+
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
105+
std::cerr << "bezier x values must be in [0, 1] range" << std::endl;
106+
}
107+
108+
if (mX1 == mY1 && mX2 == mY2) {
109+
isLinearEasing = true;
110+
return;
111+
} else {
112+
isLinearEasing = false;
113+
}
114+
115+
_mX1 = mX1;
116+
_mX2 = mX2;
117+
_mY1 = mY1;
118+
_mY2 = mY2;
119+
120+
// Precompute samples table
121+
sampleValues = new float[kSplineTableSize];
122+
for (unsigned int i = 0; i < kSplineTableSize; ++i) {
123+
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
124+
}
125+
};
126+
127+
};
128+
#endif // _CUBIC_BEZIER_EASING_H

0 commit comments

Comments
 (0)