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; }
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); }
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); }
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); }
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; }
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); } }
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; }
public EvaluateLoop(time:number) : number[] { let validTime = time % this.MaxTime; return this.Evaluate(validTime); } }
|