public override bool OnInitialize() { _keyframes = null; if ((_name == null) && (Header->_stringOffset != 0)) { _name = Header->ResourceString; } _code = Header->Code; _useModelScale = _code.UseModelScale; _useModelRotate = _code.UseModelRot; _useModelTranslate = _code.UseModelTrans; _scaleCompApply = _code.ScaleCompApply; _scaleCompParent = _code.ScaleCompParent; _classicScaleOff = _code.ClassicScaleOff; return(false); }
private void Start() { _obj = gameObject.transform; _rb = GetComponent <Rigidbody2D>(); _anim = GetComponentInChildren <AnimationCode>(); }
private static int EvaluateCHR0Group(ref AnimationCode code, KeyframeCollection kf, int group, ref int entrySize) { int index = group * 3; int numFrames = kf.FrameCount; int dataLen = 0; int maxEntries; int evalCount; int scaleSpan; //bool useLinear = group == 1; bool exist = false; bool isotropic = group == 0; AnimDataFormat format = AnimDataFormat.None; KeyframeEntry[] roots = new KeyframeEntry[3]; KeyframeEntry[][] arr = new KeyframeEntry[3][]; int* count = stackalloc int[3]; bool* isExist = stackalloc bool[3]; bool* isFixed = stackalloc bool[3]; bool* isScalable = stackalloc bool[3]; float* floor = stackalloc float[3]; float* ceil = stackalloc float[3]; KeyframeEntry entry; int eCount = 0; float min; float max; int maxIndex = 0; //Initialize values for (int i = 0; i < 3; i++) { entry = roots[i] = kf._keyRoots[index + i]; count[i] = kf._keyCounts[index + i]; isExist[i] = count[i] > 0; isFixed[i] = count[i] <= 1; if (!isFixed[i]) { min = float.MaxValue; max = float.MinValue; for (entry = entry._next; entry._index != -1; entry = entry._next) { min = Math.Min(entry._value, min); max = Math.Max(entry._value, max); } floor[i] = min; ceil[i] = max; maxIndex = Math.Max(entry._prev._index, maxIndex); } } if (exist = isExist[0] || isExist[1] || isExist[2]) { if (group == 0) { if ((isFixed[0] != isFixed[1]) || (isFixed[0] != isFixed[2])) isotropic = false; else if ((count[0] != count[1]) || (count[0] != count[2])) isotropic = false; else { KeyframeEntry e1 = roots[0], e2 = roots[1], e3 = roots[2]; for (int i = count[0]; i-- > 0; ) { e1 = e1._next; e2 = e2._next; e3 = e3._next; if ((e1._index != e2._index) || (e1._index != e3._index) || (e1._value != e2._value) || (e1._value != e3._value)) { isotropic = false; break; } } } } if (isotropic) { evalCount = 1; maxEntries = count[0]; } else { evalCount = 3; maxEntries = Math.Max(Math.Max(count[0], count[1]), count[2]); //useLinear &= (count[0] == numFrames) && (count[1] == numFrames) && (count[2] == numFrames); } scaleSpan = (group == 1) ? 255 : (maxIndex <= 255) ? 4095 : (maxIndex <= 2047) ? 65535 : -1; //scaleSpan = useLinear ? 255 : 4095; //Determine if values are scalable for (int i = 0; i < evalCount; i++) { isScalable[i] = true; if ((isFixed[i]) || (scaleSpan == -1)) continue; //float* pValue = value[i]; eCount = count[i]; float basev, range, step, distance, val; basev = floor[i]; range = ceil[i] - basev; //Evaluate spans until we reach a success. //A success means that compression using that span is possible. //No further evaluation necessary. SpanBegin: int span = scaleSpan; int spanEval = scaleSpan - 32; float tanScale = scaleSpan == 4095 ? 32.0f : 256.0f; if (scaleSpan != 255) { for (entry = roots[i]._next; entry._index != -1; entry = entry._next) { //Ignore entries that don't need interp. if (((entry._index - entry._prev._index >= 1) && (entry._prev._index != -1)) || ((entry._next._index - entry._index >= 1) && (entry._next._index != -1))) { val = entry._tangent * tanScale; val += val < 0 ? -0.5f : 0.5f; if (Math.Abs(((int)val / tanScale) - entry._tangent) > tanError) { span = spanEval; break; } } } } if ((span > spanEval) && (range == 0.0f)) continue; SpanStep: if (span > spanEval) { step = range / span; //if span <= 255, check every frame instead! if (span <= 255) { for (int x = 0; x < numFrames; x++) { val = kf[KeyFrameMode.ScaleX + index + i, x]; distance = ((val - basev) / step) + 0.5f; distance = Math.Abs(val - (basev + ((int)distance * step))); //If distance is too large change span and retry if (distance > scaleError) { span--; goto SpanStep; } } } else { for (entry = roots[i]._next; entry._index != -1; entry = entry._next) { val = entry._value; distance = ((val - basev) / step) + 0.5f; distance = Math.Abs(val - (basev + ((int)distance * step))); //If distance is too large change span and retry if (distance > scaleError) { span--; goto SpanStep; } } } } else { if ((scaleSpan <= 255) && (maxIndex <= 255)) scaleSpan = 4095; else if ((scaleSpan <= 4095) && (maxIndex <= 2047)) scaleSpan = 65535; else { scaleSpan = -1; isScalable[i] = false; continue; } goto SpanBegin; } } //Determine format only if there are unfixed entries if (!isFixed[0] || !isFixed[1] || !isFixed[2]) { bool scale = (isotropic) ? isScalable[0] : (isScalable[0] && isScalable[1] && isScalable[2]); float frameSpan = (float)numFrames / maxEntries; if (scale) { if ((group == 1) && (scaleSpan <= 255) && (frameSpan < 4.0f)) format = AnimDataFormat.L1; else if ((scaleSpan <= 4095) && (maxIndex <= 255)) format = AnimDataFormat.I4; else if ((frameSpan > 1.5f) && (maxIndex <= 2047)) format = AnimDataFormat.I6; else if ((group == 1) && (frameSpan <= 3.0f)) format = AnimDataFormat.L4; else format = AnimDataFormat.I12; } else if ((group == 1) && (frameSpan <= 3.0f)) format = AnimDataFormat.L4; else format = AnimDataFormat.I12; } //calculate size for (int i = 0; i < evalCount; i++) { entrySize += 4; if (!isFixed[i]) { switch (format) { case AnimDataFormat.I12: dataLen += 8 + (count[i] * 12); break; case AnimDataFormat.I4: dataLen += 16 + (count[i] * 4); break; case AnimDataFormat.I6: dataLen += (16 + (count[i] * 6)).Align(4); break; case AnimDataFormat.L1: dataLen += (8 + numFrames).Align(4); break; case AnimDataFormat.L4: dataLen += numFrames * 4; break; } } } //Should we compress here? } else //Set isotropic to true, so it sets the default value. isotropic = true; if (group == 0) code.IgnoreScale = !exist; code.SetExists(group, exist); code.SetIsIsotropic(group, isotropic); for (int i = 0; i < 3; i++) code.SetIsFixed(index + i, isFixed[i]); code.SetFormat(group, format); return dataLen; }