123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
-
- using UnityEngine;
- using System.IO;
- [System.Serializable]
- public class MegaBezFloatKey
- {
- public float val;
- public float intan;
- public float outtan;
- public float intanx;
- public float outtanx;
- public float coef0;
- public float coef1;
- public float coef2;
- public float coef3;
- }
- [System.Serializable]
- public class MegaBezFloatKeyControl : MegaControl
- {
- public MegaBezFloatKey[] Keys;
- private const float SCALE = 4800.0f;
- public float f;
- //public float[] Times;
- //[HideInInspector]
- //public int lastkey = 0;
- //[HideInInspector]
- //public float lasttime = 0.0f;
- //public virtual float GetFloat(float time) { return 0.0f; }
- #if false
- int BinSearch(float t, int low, int high)
- {
- int probe = 0;
- while ( high - low > 1 )
- {
- probe = (high + low) / 2;
- if ( t < Times[probe] )
- high = probe;
- else
- {
- if ( t > Times[probe + 1] )
- low = probe;
- else
- break; // found
- }
- }
- return probe;
- }
- // get index
- // do a range check, anim code should keep the t in range
- public int GetKey(float t)
- {
- if ( t <= Times[1] )
- return 0;
- if ( t >= Times[Times.Length - 1] )
- return Times.Length - 2;
- // Cache result and then do a bin search
- int key = lastkey;
- if ( t >= Times[key] && t < Times[key + 1] )
- return key; // we get past this if out of time range of whole anim
- return BinSearch(t, -1, Times.Length - 1);
- }
- #endif
- public void InitKeys()
- {
- for ( int i = 0; i < Keys.Length - 1; i++ )
- {
- float dt = Times[i + 1] - Times[i];
- float hout = Keys[i].val + (Keys[i].outtan * SCALE) * (dt / 3.0f);
- float hin = Keys[i + 1].val + (Keys[i + 1].intan * SCALE) * (dt / 3.0f);
- Keys[i].coef1 = Keys[i + 1].val + 3.0f * (hout - hin) - Keys[i].val;
- Keys[i].coef2 = 3.0f * (hin - 2.0f * hout + Keys[i].val);
- Keys[i].coef3 = 3.0f * (hout - Keys[i].val);
- }
- }
- public void InitKeys(float scale)
- {
- for ( int i = 0; i < Keys.Length - 1; i++ )
- {
- float dt = Times[i + 1] - Times[i];
- float hout = Keys[i].val + (Keys[i].outtan * scale) * (dt / 3.0f);
- float hin = Keys[i + 1].val + (Keys[i + 1].intan * scale) * (dt / 3.0f);
- Keys[i].coef1 = Keys[i + 1].val + 3.0f * (hout - hin) - Keys[i].val;
- Keys[i].coef2 = 3.0f * (hin - 2.0f * hout + Keys[i].val);
- Keys[i].coef3 = 3.0f * (hout - Keys[i].val);
- }
- }
- public void InitKeysMaya()
- {
- for ( int i = 0; i < Keys.Length - 1; i++ )
- {
- float x0 = Times[i];
- float x1 = Times[i] + Keys[i].outtanx;
- float x2 = Times[i + 1] - Keys[i + 1].intanx;
- float x3 = Times[i + 1];
- float y0 = Keys[i].val;
- float y1 = Keys[i].val + Keys[i].outtan;
- float y2 = Keys[i + 1].val - Keys[i + 1].intan;
- float y3 = Keys[i + 1].val;
- float dx = x3 - x0;
- float dy = y3 - y0;
- float tan_x = x1 - x0;
- float m1 = 0.0f;
- float m2 = 0.0f;
- if ( tan_x != 0.0f )
- m1 = (y1 - y0) / tan_x;
- tan_x = x3 - x2;
- if ( tan_x != 0.0f )
- m2 = (y3 - y2) / tan_x;
- float length = 1.0f / (dx * dx);
- float d1 = dx * m1;
- float d2 = dx * m2;
- Keys[i].coef0 = (d1 + d2 - dy - dy) * length / dx;
- Keys[i].coef1 = (dy + dy + dy - d1 - d1 - d2) * length;
- Keys[i].coef2 = m1;
- Keys[i].coef3 = y0;
- }
- }
- public float GetHermiteFloat(float tt)
- {
- if ( Times.Length == 1 )
- return Keys[0].val;
- int key = GetKey(tt);
- float t = Mathf.Clamp01((tt - Times[key]) / (Times[key + 1] - Times[key]));
- t = Mathf.Lerp(Times[key], Times[key + 1], t) - Times[key];
- return (t * (t * (t * Keys[key].coef0 + Keys[key].coef1) + Keys[key].coef2) + Keys[key].coef3);
- }
- public void MakeKey(MegaBezFloatKey key, Vector2 pco, Vector2 pleft, Vector2 pright, Vector2 co, Vector2 left, Vector2 right)
- {
- float f1 = pco.y * 100.0f;
- float f2 = pright.y * 100.0f;
- float f3 = left.y * 100.0f;
- float f4 = co.y * 100.0f;
- key.val = f1;
- key.coef3 = 3.0f * (f2 - f1);
- key.coef2 = 3.0f * (f1 - 2.0f * f2 + f3);
- key.coef1 = f4 - f1 + 3.0f * (f2 - f3);
- }
- #if false
- public bool Parse(BinaryReader br, string id)
- {
- switch ( id )
- {
- case "Num":
- int num = br.ReadInt32();
- Keys = new MegaBezFloatKey[num];
- Times = new float[num];
- break;
- case "Keys":
- for ( int i = 0; i < Keys.Length; i++ )
- {
- Keys[i] = new MegaBezFloatKey();
- Keys[i].val = br.ReadSingle();
- Keys[i].intan = br.ReadSingle();
- Keys[i].outtan = br.ReadSingle();
- Times[i] = br.ReadSingle();
- }
- InitKeys();
- break;
- case "BKeys": // Blender keys
- Vector2 co = Vector2.zero;
- Vector2 left = Vector2.zero;
- Vector3 right = Vector2.zero;
- Vector2 pco = Vector2.zero;
- Vector2 pleft = Vector2.zero;
- Vector3 pright = Vector2.zero;
- for ( int i = 0; i < Keys.Length; i++ )
- {
- Keys[i] = new MegaBezFloatKey();
- co.x = br.ReadSingle();
- co.y = br.ReadSingle();
- left.x = br.ReadSingle();
- left.y = br.ReadSingle();
- right.x = br.ReadSingle();
- right.y = br.ReadSingle();
- if ( i > 0 )
- MakeKey(Keys[i - 1], pco, pleft, pright, co, left, right);
- pco = co;
- pleft = left;
- pright = right;
- Times[i] = co.x / 30.0f;
- }
- break;
- }
- return true;
- }
- #endif
- //public override void Interp(float alpha, int key)
- public void Interp(float alpha, int key)
- {
- if ( alpha == 0.0f )
- f = Keys[key].val;
- else
- {
- if ( alpha == 1.0f )
- f = Keys[key + 1].val;
- else
- {
- float tp2 = alpha * alpha;
- float tp3 = tp2 * alpha;
- f = Keys[key].coef1 * tp3 + Keys[key].coef2 * tp2 + Keys[key].coef3 * alpha + Keys[key].val;
- }
- }
- }
- public override float GetFloat(float t)
- {
- if ( Times.Length == 1 )
- {
- return Keys[0].val;
- }
- int key = GetKey(t);
- float alpha = (t - Times[key]) / (Times[key + 1] - Times[key]);
- if ( alpha < 0.0f )
- alpha = 0.0f;
- else
- {
- if ( alpha > 1.0f )
- alpha = 1.0f;
- }
- // Do ease and hermite here maybe
- Interp(alpha, key);
- lastkey = key;
- lasttime = t;
- return f;
- }
- }
|