ts-code-AniCurve

AniCurve

unity的AnimactionCurve的ts实现

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
interface KeyFrame
{
value:number; // 帧的值
time:number; // 帧的时间
inTangent:number; // 内切值
outTangent:number; // 外切值
}

class AniCurve
{
private maxTime:number; // 最大的帧时间值
private arrFrame:KeyFrame[]; // 帧数据集合

public get MaxTime() { return this.maxTime; }

public constructor(arrFrame:KeyFrame[])
{
if (arrFrame != null && arrFrame.length > 0)
this.maxTime = arrFrame[arrFrame.length - 1].time;
else
this.maxTime = 0;

this.arrFrame = arrFrame;
}

// 计算值
// @time:时间
// return:该时间点的值
public Evaluate(time:number) : number
{
if(this.arrFrame.length < 1)
return 0;

if (time >= this.maxTime)
return this.arrFrame[this.arrFrame.length - 1].value;
else if (time <= 0)
return this.arrFrame[0].value;

// 这里计算出左边和右边的帧
let lFrame:KeyFrame = this.arrFrame[0];
let rFrame:KeyFrame = this.arrFrame[1];
for (let i = 1; i < this.arrFrame.length; ++i)
{
let kf:KeyFrame = this.arrFrame[i];
if (kf.time <= time)
{
lFrame = kf;
}
else if (kf.time > time)
{
rFrame = kf;
break;
}
}

return this.Evalute(time, lFrame, rFrame);
}

// 计算值
// @time:时间
// return:该时间点的值
public EvaluateLoop(time:number) : number
{
if(this.arrFrame.length < 1)
return 0;

let validTime = time;
if (validTime >= this.maxTime){
validTime %= this.maxTime;
}

return this.Evaluate(validTime);
}

// 计算曲线值
// @time:时间
// @lKf:左边的帧值
// @rKf:右边的帧值
private Evalute(time:number, lKf:KeyFrame, rKf:KeyFrame) : number
{
let totalTime:number = rKf.time - lKf.time;

if (totalTime <= 0.0001)
return lKf.value;

let timePct:number = (time - lKf.time) / totalTime;
let leftFactor:number = lKf.outTangent * totalTime;
let rightFactor:number = rKf.inTangent * totalTime;

return this.HermiteInterpolate(timePct, lKf.value, leftFactor, rightFactor, rKf.value);
}

// 埃尔米特插值
// @t:时间比重
// @p0:左值
// @m0:左值系数
// @m1:右值系数
// @p1:右值
private HermiteInterpolate(t:number, p0:number, m0:number, m1:number, p1:number) : number
{
let t2:number = t * t;
let t3:number = t2 * t;

let a:number = 2.0 * t3 - 3.0 * t2 + 1.0;
let b:number = t3 - 2.0 * t2 + t;
let c:number = t3 - t2;
let d:number = -2.0 * t3 + 3.0 * t2;

return a * p0 + b * m0 + c * m1 + d * p1;
}
}

AniCurves

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
class AniCurves
{
private maxTime:number; // 最大的帧时间值

private arrCurve:AniCurve[]; // 动画曲线集合

public get MaxTime() { return this.maxTime; }

// @arg:曲线帧数集合
constructor(...arg:any[])
{
this.arrCurve = [];
this.maxTime = 0;

for(let i = 0; i < arg.length; ++i){
let arrFrame:KeyFrame[] = arg[i];
let aniCurve = new AniCurve(arrFrame);

if(aniCurve.MaxTime > this.maxTime){
this.maxTime = aniCurve.MaxTime;
}

this.arrCurve.push(aniCurve);
}
}

// 计算曲线的值
// @time:时间
// return:该时间点的值的集合
public Evaluate(time:number) : number[]
{
let arrVal:number[] = [];
for(let i = 0; i < this.arrCurve.length; ++i){
let curve = this.arrCurve[i];
arrVal.push(curve.Evaluate(time));
}

return arrVal;
}

// 计算曲线的值
// @time:时间
// return:该时间点的值的集合
public EvaluateLoop(time:number) : number[]
{
let validTime = time % this.MaxTime;
return this.Evaluate(validTime);
}
}