/// <summary> /// Remove a keyframe of component. /// </summary> public void RemoveKeyframe(SpriteAnimationKeyFrame kf) { List <SpriteAnimationKeyFrame> tmp = new List <SpriteAnimationKeyFrame>(keyFrames); tmp.Remove(kf); tmp.Sort(SpriteAnimationKeyFrameComparerByFrameIndex.comparer); keyFrames = tmp.ToArray(); CalcCurve(null); }
/// <summary> /// Add a keyframe of component. /// </summary> public void AddKeyframe(SpriteAnimationKeyFrame kf) { float tick = 1f / clip.frameRate; kf.time = kf.frameIndex * tick; List <SpriteAnimationKeyFrame> tmp = new List <SpriteAnimationKeyFrame>(keyFrames); tmp.Add(kf); tmp.Sort(SpriteAnimationKeyFrameComparerByFrameIndex.comparer); keyFrames = tmp.ToArray(); CalcCurve(kf); }
internal SpriteAnimationKeyFrame EvaluateAddtive(float time, SpriteTransform transform, float[] transformProperty) { int idx = (int)curves[0].curve.Evaluate(time); SpriteAnimationKeyFrame kf = keyFrames[idx]; SpriteAnimationCurve curve = null; for (int i = 1, e = curves.Length; i < e; i++) { curve = curves[i]; transformProperty[(int)curve.type] = curve.length == 0 ? 0f : (curve.curve.Evaluate(time) - curve.defaultValue); } return(kf); }
internal SpriteAnimationKeyFrame EvaluateBlending(float time, SpriteTransform transform, float[] transformProperty) { int idx = (int)curves[0].curve.Evaluate(time); SpriteAnimationKeyFrame kf = keyFrames[idx]; if (!transform.isSpriteValid && kf.isSpriteValid) { transform._sprite = kf.sprite; transform.isSpriteValid = true; } float v = 0f; foreach (SpriteAnimationCurve curve in curves) { transformProperty[(int)curve.type] = curve.length == 0 ? curve.defaultValue : curve.curve.Evaluate(time); } return(kf); }
/// <summary> /// Clone all field from another keyframe. /// </summary> public void Clone(SpriteAnimationKeyFrame other) { if (other == null) { return; } //frameIndex = other.frameIndex; //time = other.time; sprite = other.sprite; position = other.position; rotation = other.rotation; scale = other.scale; shear = other.shear; color = other.color; refClip = other.refClip; isSpriteValid = other.isSpriteValid; isRefClip = other.isRefClip; }
internal SpriteAnimationKeyFrame EvaluateBlending(float time, SpriteTransform transform, float[] transformProperty) { int idx = (int)curves[0].curve.Evaluate(time); SpriteAnimationKeyFrame kf = keyFrames[idx]; if (!transform.isSpriteValid) { transform.sprite = kf.sprite; } float v = 0f; SpriteAnimationCurve curve = null; for (int i = 1, e = curves.Length; i < e; i++) { curve = curves[i]; transformProperty[(int)curve.type] = curve.length == 0 ? curve.defaultValue : curve.curve.Evaluate(time); } return(kf); }
/// <summary> /// Evaluate the component state at time. /// </summary> public SpriteAnimationKeyFrame Evaluate(float time, ref Vector2 position, ref float rotation, ref Vector2 scale, ref Vector2 shear, ref Color color, ref Sprite spr, ref SpriteAnimationClip refClip) { SpriteAnimationKeyFrame ret = keyFrames[0]; foreach (SpriteAnimationCurve curve in curves) { switch (curve.type) { case SpriteAnimationCurveType.KeyframeIndex: { int idx = (int)curve.curve.Evaluate(time); if ((keyFrames.Length - 1) >= idx) { ret = keyFrames[idx]; spr = ret.sprite; refClip = ret.refClip; } } break; case SpriteAnimationCurveType.PositionX: position.x = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.PositionY: position.y = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.Rotate: rotation = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.ScaleX: scale.x = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.ScaleY: scale.y = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.ShearX: shear.x = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.ShearY: shear.y = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.ColorR: color.r = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.ColorG: color.g = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.ColorB: color.b = curve.curve.Evaluate(time); break; case SpriteAnimationCurveType.ColorA: color.a = curve.curve.Evaluate(time); break; } } return(ret); }
/// <summary> /// Calculate the curves of component. /// </summary> public void CalcCurve(SpriteAnimationKeyFrame newKf) { _maxIndex = GetMaxIndex(); List <SpriteAnimationKeyFrame> tmp = new List <SpriteAnimationKeyFrame>(keyFrames); tmp.Sort(SpriteAnimationKeyFrameComparerByFrameIndex.comparer); keyFrames = tmp.ToArray(); ApplyCurveChangeToKeyframe(); List <SpriteAnimationCurve> tmpCurves = new List <SpriteAnimationCurve>(); for (int i = (int)SpriteAnimationCurveType.KeyframeIndex, e = (int)SpriteAnimationCurveType.ShearY; i <= e; i++) { SpriteAnimationCurve curve = new SpriteAnimationCurve(); curve.type = (SpriteAnimationCurveType)i; curve.curve = new AnimationCurve(); foreach (SpriteAnimationCurve _curve in curves) { if (_curve.type == curve.type) { curve.interpolation = _curve.interpolation; } } tmpCurves.Add(curve); } float tick = 1f / clip.frameRate; int idx = 0; tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex].curve = new AnimationCurve(); tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex].interpolation = true; foreach (SpriteAnimationKeyFrame kf in keyFrames) { float time = kf.frameIndex * tick;; kf.isSpriteValid = kf.sprite != null; bool needSmooth = kf == newKf; AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex], time, idx + 0.005f, false, 0, false); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.PositionX], time, kf.position.x, true, 1, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.PositionY], time, kf.position.y, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.Rotate], time, kf.rotation, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ScaleX], time, kf.scale.x, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ScaleY], time, kf.scale.y, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ShearX], time, kf.shear.x, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ShearY], time, kf.shear.y, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ColorR], time, kf.color.r, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ColorG], time, kf.color.g, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ColorB], time, kf.color.b, true, 0, needSmooth); AddKeyToCurve(tmpCurves[(int)SpriteAnimationCurveType.ColorA], time, kf.color.a, true, 0, needSmooth); idx++; } //for (int i = 0, e = tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex].curve.keys.Length; i < e; i++) // tmpCurves[(int)SpriteAnimationCurveType.KeyframeIndex].curve.SmoothTangents(i, 1f); //remove curves if values never change tmpCurves.RemoveAll(delegate(SpriteAnimationCurve curve) { if (curve.type == SpriteAnimationCurveType.KeyframeIndex) { return(false); } bool ret = true; Keyframe fkf = curve.curve.keys[0]; curve.defaultValue = fkf.value; bool isFkDef = fkf.value == GetDefaultValue(curve.type); foreach (Keyframe kf in curve.curve.keys) { if (fkf.value != kf.value) { return(false); } } if (!isFkDef) { curve.length = 0; return(false); } return(ret); }); foreach (SpriteAnimationCurve curve in tmpCurves) { if (curve.type == SpriteAnimationCurveType.KeyframeIndex) { continue; } if (!curve.interpolation) { Keyframe[] kfs = curve.curve.keys; curve.curve = new AnimationCurve(); for (int i = 0, e = kfs.Length; i < e; i++) { Keyframe kf = kfs[i]; kf.inTangent = float.PositiveInfinity; kf.outTangent = float.NegativeInfinity; curve.curve.AddKey(kf); } } } curves = tmpCurves.ToArray(); }
private void EvaluateCompoment() { for (int i = 0; i < spriteRenderer.GetAttachSpriteCount(); i++) { SpriteTransform sprTransform = spriteRenderer.GetSpriteTransform(i); sprTransform.ZeroTransform(); foreach (SpriteTransform.StateComponentPair pair in sprTransform.attachStateComponent) { SpriteAnimationKeyFrame kf = null; if (pair.state.blendMode == AnimationBlendMode.Additive) { //reset buffer transformPropertys[1] = transformPropertys[2] = transformPropertys[3] = 0f; transformPropertys[4] = transformPropertys[5] = transformPropertys[6] = transformPropertys[7] = transformPropertys[8] = transformPropertys[9] = 0f; transformPropertys[10] = transformPropertys[11] = 0f; kf = pair.component.EvaluateAddtive(pair.state.lastEvaluateTime, sprTransform, transformPropertys); } else { //reset buffer transformPropertys[1] = transformPropertys[2] = transformPropertys[3] = 0f; transformPropertys[4] = transformPropertys[5] = transformPropertys[6] = transformPropertys[7] = transformPropertys[8] = transformPropertys[9] = 1f; transformPropertys[10] = transformPropertys[11] = 0f; kf = pair.component.EvaluateBlending(pair.state.lastEvaluateTime, sprTransform, transformPropertys); } if (pair.applyTo.lastRefClip != kf.refClip) { if (pair.applyTo.lastRefClip != null) { string name = pair.state.name + "_" + pair.applyTo.lastRefClip.name; SpriteAnimationState state = this[name]; if (state != null) { Stop(state); } } if (kf.refClip != null) { string name = pair.state.name + "_" + kf.refClip.name; if (!animationStates.ContainsKey(name)) { AddClip(kf.refClip, name); SpriteAnimationState state = this[name]; state.parentTransform = spriteRenderer.GetSpriteTransformByFullPathHash(pair.component._fullPathHash); state.parentComponentLayer = (int)pair.component.layer; state.removeAfterStop = true; state.layer = pair.state.layer; state.weight = pair.state.weight; state.enabled = true; state.lastTime = 0f; state.lastFrameIndex = -1; state.lastEvaluateTime = 0; pair.applyTo.lastRefClip = kf.refClip; } } } float weight = pair.weight; { sprTransform.position.x += transformPropertys[1] * weight; sprTransform.position.y += transformPropertys[2] * weight; sprTransform.rotation += transformPropertys[3] * weight; sprTransform.scale.x += transformPropertys[4] * weight; sprTransform.scale.y += transformPropertys[5] * weight; sprTransform.color.r += transformPropertys[6] * weight; sprTransform.color.g += transformPropertys[7] * weight; sprTransform.color.b += transformPropertys[8] * weight; sprTransform.color.a += transformPropertys[9] * weight; sprTransform.shear.x += transformPropertys[10] * weight; sprTransform.shear.y += transformPropertys[11] * weight; } } } if (preTransformUpdate != null) { preTransformUpdate(this); } }
internal void EvaluateTransform(SpriteTransform sprTransform) { sprTransform.ZeroTransform(); for (int idx = 0; idx < sprTransform.attachStateComponent.Count; idx++) { SpriteTransform.StateComponentPair pair = sprTransform.attachStateComponent[idx]; SpriteAnimationKeyFrame kf = null; if (pair.state.blendMode == AnimationBlendMode.Additive) { //reset buffer transformPropertys[1] = transformPropertys[2] = transformPropertys[3] = 0f; transformPropertys[4] = transformPropertys[5] = transformPropertys[6] = transformPropertys[7] = transformPropertys[8] = transformPropertys[9] = 0f; transformPropertys[10] = transformPropertys[11] = 0f; kf = pair.component.EvaluateAddtive(pair.state.lastEvaluateTime, sprTransform, transformPropertys); } else { //reset buffer transformPropertys[1] = transformPropertys[2] = transformPropertys[3] = 0f; transformPropertys[4] = transformPropertys[5] = transformPropertys[6] = transformPropertys[7] = transformPropertys[8] = transformPropertys[9] = 1f; transformPropertys[10] = transformPropertys[11] = 0f; kf = pair.component.EvaluateBlending(pair.state.lastEvaluateTime, sprTransform, transformPropertys); } if (pair.lastRefClip != kf.refClip) { if (pair.lastRefClip != null) { string name = pair.state.name + "_" + pair.component.fullPath + "_" + pair.lastRefClip.name; SpriteAnimationState state = this[name]; if (state != null) { Stop(state); } pair.lastRefClip = null; } if (kf.refClip != null) { string name = pair.state.name + "_" + pair.component.fullPath + "_" + kf.refClip.name; if (!animationStates.ContainsKey(name)) { AddClip(kf.refClip, name); SpriteAnimationState state = this[name]; state.parentState = pair.state; state.parentTransform = pair.applyTo; state.parentComponentLayer = (int)pair.component.layer; state.removeAfterStop = true; state.layer = pair.state.layer; state.weight = pair.state.weight; state.lastTime = 0f; state.lastFrameIndex = -1; state.lastEvaluateTime = 0; pair.lastRefClip = kf.refClip; state.parentState.subClipState.Add(state); state.enabled = true; } } } float weight = pair.weight; { sprTransform.position.x += transformPropertys[1] * weight; sprTransform.position.y += transformPropertys[2] * weight; sprTransform.rotation += transformPropertys[3] * weight; sprTransform.scale.x += transformPropertys[4] * weight; sprTransform.scale.y += transformPropertys[5] * weight; sprTransform.color.r += transformPropertys[6] * weight; sprTransform.color.g += transformPropertys[7] * weight; sprTransform.color.b += transformPropertys[8] * weight; sprTransform.color.a += transformPropertys[9] * weight; sprTransform.shear.x += transformPropertys[10] * weight; sprTransform.shear.y += transformPropertys[11] * weight; } } }
public SpriteAnimationKeyFrame(SpriteAnimationKeyFrame other) { Clone(other); }
static void DrawAnimationComponent(Vector2 orig, float frameRate, SpriteAnimationComponent component, float time, Matrix4x4 parentMat, float parentRotation, Vector2 parentScale, SpriteTransform parentTran, int parentLayer) { SpriteTransform transform = new SpriteTransform(); transform.parent = parentTran; transform.component = component; transform.layer = (int)component.layer + parentLayer; Sprite spr = null; SpriteAnimationClip refClip = null; SpriteAnimationKeyFrame kf = component.Evaluate(time, ref transform.position, ref transform.rotation, ref transform.scale, ref transform.shear, ref transform.color, ref spr, ref refClip); transform.sprite = spr; componentTransforms.Add(transform); transform.position.y = -transform.position.y; Vector2 tranPosition = parentMat.MultiplyPoint3x4(transform.position); Matrix4x4 tmpMat = Matrix4x4.TRS(transform.position, Quaternion.Euler(0, 0, -transform.rotation), transform.scale); if (refClip != null) { float l = refClip.length; float tick = 1f / refClip.frameRate; AnimationLinearCurve clipPlayingCurve = new AnimationLinearCurve(0, 0, l, l); clipPlayingCurve.wrapMode = refClip.wrapMode; float t = clipPlayingCurve.Evaluate(time - kf.frameIndex * tick); DrawAnimationComponent(orig, frameRate, refClip.root, t, parentMat * tmpMat, parentRotation + transform.rotation, new Vector2(transform.scale.x * parentScale.x, transform.scale.y * parentScale.y), transform, transform.layer); } foreach (int comIdx in component.children) { SpriteAnimationComponent com = component.clip.subComponents[comIdx]; DrawAnimationComponent(orig, frameRate, com, time, parentMat * tmpMat, parentRotation + transform.rotation, new Vector2(transform.scale.x * parentScale.x, transform.scale.y * parentScale.y), transform, parentLayer); } transform.position = tranPosition - orig; transform.scale = new Vector2(transform.scale.x * parentScale.x, transform.scale.y * parentScale.y); transform.rotation = parentRotation + transform.rotation; }