/// <summary> /// Adds a keyframe at start and at end. Remove all keyframes in between. /// Used when starting to drag a curve to modify tangents. /// </summary> public void AddTangentKey(AnimationKey key, int start, int end) { if (keys.Count == 0) { return; } int startFrame = Mathf.Max(GlobalState.Animation.StartFrame, start); int endFrame = Mathf.Min(GlobalState.Animation.EndFrame, end); int firstKeyIndex = Mathf.Max(cachedKeysIndices[startFrame - (GlobalState.Animation.StartFrame)], 0); int lastKeyIndex = Mathf.Max(cachedKeysIndices[endFrame - (GlobalState.Animation.StartFrame)], 0); bool hasPrevValue = Evaluate(startFrame, out float prevValue); bool hasNextValue = Evaluate(endFrame, out float nextValue); if (keys[firstKeyIndex].frame != startFrame && hasPrevValue) { AddKey(new AnimationKey(startFrame, prevValue, Interpolation.Bezier), false); } if (keys[lastKeyIndex].frame != endFrame && hasNextValue) { AddKey(new AnimationKey(endFrame, nextValue, Interpolation.Bezier), false); } List <AnimationKey> toRemove = keys.FindAll(x => x.frame > startFrame && x.frame < endFrame); toRemove.ForEach(x => RemoveKey(x.frame)); }
public void AddKey(AnimationKey key) { if (GetKeyIndex(key.frame, out int index)) { keys[index] = key; ComputeCacheValuesAt(index); } else { index++; keys.Insert(index, key); int end = cachedKeysIndices.Length - 1; if (index + 1 < keys.Count) { end = keys[index + 1].frame - GlobalState.Animation.StartFrame - 1; end = Mathf.Clamp(end, 0, cachedKeysIndices.Length - 1); } int start = key.frame - GlobalState.Animation.StartFrame; start = Mathf.Clamp(start, 0, end); for (int i = start; i <= end; i++) { cachedKeysIndices[i] = index; } for (int i = end + 1; i < cachedKeysIndices.Length; i++) { cachedKeysIndices[i]++; } ComputeCacheValuesAt(index); } }
// To be used by in-app add key (not from networked keys) public void AddFilteredKeyframe(GameObject gobject, AnimatableProperty property, AnimationKey key) { AnimationSet animationSet = GetObjectAnimation(gobject); if (null == animationSet) { animationSet = new AnimationSet(gobject); animations.Add(gobject, animationSet); } Curve curve = animationSet.GetCurve(property); // Filter rotation if (property == AnimatableProperty.RotationX || property == AnimatableProperty.RotationY || property == AnimatableProperty.RotationZ) { AnimationKey previousKey = curve.GetPreviousKey(key.frame); if (null != previousKey) { float delta = Mathf.DeltaAngle(previousKey.value, key.value); key.value = previousKey.value + delta; } } curve.AddKey(key); onChangeCurve.Invoke(gobject, property); }
public void AddFilteredKeyframeTangent(GameObject gobjet, AnimatableProperty property, AnimationKey key, int start, int end, bool updateCurves = true) { AnimationSet animationSet = GetObjectAnimation(gobjet); Curve curve = animationSet.GetCurve(property); // Filter rotation if (property == AnimatableProperty.RotationX || property == AnimatableProperty.RotationY || property == AnimatableProperty.RotationZ) { AnimationKey previousKey = curve.GetPreviousKey(key.frame); if (null != previousKey) { float delta = Mathf.DeltaAngle(previousKey.value, key.value); key.value = previousKey.value + delta; } else { float delta = Mathf.DeltaAngle(0, key.value); key.value = delta; } } curve.AddTangentKey(key, start, end); if (updateCurves) { onChangeCurve.Invoke(gobjet, property); } }
public AnimationKey(AnimationKey key) { frame = key.frame; value = key.value; interpolation = key.interpolation; inTangent = key.inTangent; outTangent = key.outTangent; }
public void MoveKey(int oldFrame, int newFrame) { if (GetKeyIndex(oldFrame, out int index)) { AnimationKey key = keys[index]; RemoveKey(key.frame); key.frame = newFrame; AddKey(key); } }
public bool TryFindKey(int frame, out AnimationKey key) { if (GetKeyIndex(frame, out int index)) { key = keys[index]; return(true); } key = null; return(false); }
private void AppendFilteredKey(Curve curve, int frame, float value) { if (curve.keys.Count > 0) { AnimationKey previousKey = curve.keys[curve.keys.Count - 1]; float delta = Mathf.DeltaAngle(previousKey.value, value); value = previousKey.value + delta; } curve.AppendKey(new AnimationKey(frame, value)); }
private void GetTangents(int ac, AnimationKey previous1Key, AnimationKey next1Key) { theta[ac + 0] = previous1Key.inTangent.x; theta[ac + 1] = previous1Key.inTangent.y; theta[ac + 2] = previous1Key.outTangent.x; theta[ac + 3] = previous1Key.outTangent.y; theta[ac + 4] = next1Key.inTangent.x; theta[ac + 5] = next1Key.inTangent.y; theta[ac + 6] = next1Key.outTangent.x; theta[ac + 7] = next1Key.outTangent.y; }
public void AddKey(AnimationKey key, bool lockTangents = false) { if (GetKeyIndex(key.frame, out int index)) { keys[index] = key; if (!lockTangents) { PreviousTangent(index); NextTangent(index); if (key.inTangent == Vector2.zero && key.outTangent == Vector2.zero) { CurrentTangent(index); } } ComputeCacheValuesAt(index); } else { index++; keys.Insert(index, key); int end = cachedKeysIndices.Length - 1; if (index + 1 < keys.Count) { end = keys[index + 1].frame - GlobalState.Animation.StartFrame - 1; end = Mathf.Clamp(end, 0, cachedKeysIndices.Length - 1); } int start = key.frame - GlobalState.Animation.StartFrame; start = Mathf.Clamp(start, 0, end); for (int i = start; i <= end; i++) { cachedKeysIndices[i] = index; } for (int i = end + 1; i < cachedKeysIndices.Length; i++) { cachedKeysIndices[i]++; } if (!lockTangents) { PreviousTangent(index); NextTangent(index); if (key.inTangent == Vector2.zero && key.outTangent == Vector2.zero) { CurrentTangent(index); } } ComputeCacheValuesAt(index); } }
private bool GetKeyIndex(int frame, out int index) { index = cachedKeysIndices[frame - GlobalState.Animation.StartFrame]; if (index == -1) { return(false); } AnimationKey key = keys[index]; return(key.frame == frame); }
private void AddFilteredKeyframeZone(GameObject target, AnimationKey posX, AnimationKey posY, AnimationKey posZ, AnimationKey rotX, AnimationKey rotY, AnimationKey rotZ, AnimationKey scalex, AnimationKey scaley, AnimationKey scalez) { GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.RotationX, rotX, startFrame, endFrame, false); GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.RotationY, rotY, startFrame, endFrame, false); GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.RotationZ, rotZ, startFrame, endFrame, false); GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.ScaleX, scalex, startFrame, endFrame, false); GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.ScaleY, scaley, startFrame, endFrame, false); GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.ScaleZ, scalez, startFrame, endFrame, false); GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.PositionX, posX, startFrame, endFrame, false); GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.PositionY, posY, startFrame, endFrame, false); GlobalState.Animation.AddFilteredKeyframeZone(target, AnimatableProperty.PositionZ, posZ, startFrame, endFrame); }
public void AddKeyframe(GameObject gobject, AnimatableProperty property, AnimationKey key) { AnimationSet animationSet = GetObjectAnimation(gobject); if (null == animationSet) { animationSet = new AnimationSet(gobject); animations.Add(gobject, animationSet); } Curve curve = animationSet.GetCurve(property); curve.AddKey(key); onChangeCurve.Invoke(gobject, property); }
public void RemoveKey(int frame) { if (GetKeyIndex(frame, out int index)) { AnimationKey key = keys[index]; int start = key.frame - GlobalState.Animation.StartFrame; int end = cachedKeysIndices.Length - 1; for (int i = start; i <= end; i++) { cachedKeysIndices[i]--; } keys.RemoveAt(index); ComputeCacheValuesAt(index); } }
/// <summary> /// Same as AddZoneKey, but fill oldKeys and newKeys instead of modifying the curve. /// Used when the curve is released, to apply changes through commands /// </summary> public void GetZoneKeyChanges(AnimationKey key, int startFrame, int endFrame, List <AnimationKey> oldKeys, List <AnimationKey> newKeys) { int firstKeyIndex = cachedKeysIndices[startFrame - (GlobalState.Animation.StartFrame - 1)]; int lastKeyIndex = cachedKeysIndices[endFrame - (GlobalState.Animation.StartFrame - 1)]; if (!Evaluate(key.frame, out float value)) { return; } if (keys[firstKeyIndex].frame != startFrame && Evaluate(startFrame, out float prevValue)) { newKeys.Add(new AnimationKey(startFrame, prevValue, key.interpolation)); } if (keys[lastKeyIndex].frame != endFrame && Evaluate(endFrame, out float nextValue)) { newKeys.Add(new AnimationKey(endFrame, nextValue, key.interpolation)); } float deltaValue = key.value - value; float zoneSize = endFrame - startFrame; for (int i = firstKeyIndex; i <= lastKeyIndex; i++) { int deltaFrame = Mathf.Abs(key.frame - keys[i].frame); float deltaTime = 1 - (deltaFrame / (float)zoneSize); if (property == AnimatableProperty.RotationX || property == AnimatableProperty.RotationY || property == AnimatableProperty.RotationZ) { oldKeys.Add(new AnimationKey(keys[i].frame, keys[i].value, keys[i].interpolation)); float newValue = Mathf.LerpAngle(keys[i].value, keys[i].value + deltaValue, deltaTime); newKeys.Add(new AnimationKey(keys[i].frame, newValue, key.interpolation)); } else { oldKeys.Add(new AnimationKey(keys[i].frame, keys[i].value, keys[i].interpolation)); float newValue = Mathf.Lerp(keys[i].value, keys[i].value + deltaValue, deltaTime); newKeys.Add(new AnimationKey(keys[i].frame, newValue, key.interpolation)); } } if (TryFindKey(key.frame, out AnimationKey oldKey)) { oldKeys.Add(new AnimationKey(oldKey.frame, oldKey.value, oldKey.interpolation)); } newKeys.Add(new AnimationKey(key.frame, key.value, key.interpolation)); }
private void DragObject(Matrix4x4 transformation, float scaleIndice) { Matrix4x4 transformed = objectData.InitialParentMatrixWorldToLocal * transformation * objectData.InitialParentMatrix * objectData.InitialTRS; Maths.DecomposeMatrix(transformed, out objectData.lastPosition, out objectData.lastQRotation, out objectData.lastScale); objectData.lastRotation = objectData.lastQRotation.eulerAngles; objectData.lastScale *= scaleIndice; Interpolation interpolation = GlobalState.Settings.interpolation; AnimationKey posX = new AnimationKey(Frame, objectData.lastPosition.x, interpolation); AnimationKey posY = new AnimationKey(Frame, objectData.lastPosition.y, interpolation); AnimationKey posZ = new AnimationKey(Frame, objectData.lastPosition.z, interpolation); AnimationKey rotX = new AnimationKey(Frame, objectData.lastRotation.x, interpolation); AnimationKey rotY = new AnimationKey(Frame, objectData.lastRotation.y, interpolation); AnimationKey rotZ = new AnimationKey(Frame, objectData.lastRotation.z, interpolation); AnimationKey scalex = new AnimationKey(Frame, objectData.lastScale.z, interpolation); AnimationKey scaley = new AnimationKey(Frame, objectData.lastScale.z, interpolation); AnimationKey scalez = new AnimationKey(Frame, objectData.lastScale.z, interpolation); switch (manipulationMode) { case AnimationTool.CurveEditMode.AddKeyframe: AddFilteredKeyframe(Target, posX, posY, posZ, rotX, rotY, rotZ, scalex, scaley, scalez); break; case AnimationTool.CurveEditMode.Zone: AddFilteredKeyframeZone(Target, posX, posY, posZ, rotX, rotY, rotZ, scalex, scaley, scalez); break; case AnimationTool.CurveEditMode.Segment: objectData.Solver = new TangentSimpleSolver(objectData.lastPosition, objectData.lastQRotation, GlobalState.Animation.GetObjectAnimation(Target), Frame, startFrame, endFrame, continuity); objectData.Solver.TrySolver(); GlobalState.Animation.onChangeCurve.Invoke(Target, AnimatableProperty.PositionX); break; case AnimationTool.CurveEditMode.Tangents: objectData.Solver = new TangentSimpleSolver(objectData.lastPosition, objectData.lastQRotation, GlobalState.Animation.GetObjectAnimation(Target), Frame, startFrame, endFrame, continuity); objectData.Solver.TrySolver(); GlobalState.Animation.onChangeCurve.Invoke(Target, AnimatableProperty.PositionX); break; } }
/// <summary> /// Fill upper bounds array with delta from current values /// </summary> private void FillUpperBounds(int curveIndex, AnimationKey previous1Key, AnimationKey next1Key, AnimationKey previous2Key, AnimationKey next2Key, float Min, float Max) { //k- in.x upperBound[curveIndex * 8 + 0] = previous1Key.frame - previous2Key.frame - previous1Key.inTangent.x; //k- in.y upperBound[curveIndex * 8 + 1] = -Mathf.Min(0, Min - Mathf.Min(curvesMinMax[curveIndex, 0].x, curvesMinMax[curveIndex, 0].y)); //k- out.x upperBound[curveIndex * 8 + 2] = currentFrame - previous1Key.frame - previous1Key.outTangent.x; //k- out.y upperBound[curveIndex * 8 + 3] = Mathf.Max(0, (4 / 3f) * (Max - (previous1Key.value + (3 / 4f) * previous1Key.outTangent.y))); //k+ in.x upperBound[curveIndex * 8 + 4] = next1Key.frame - currentFrame - next1Key.inTangent.x; //k+ in.y upperBound[curveIndex * 8 + 5] = Mathf.Max(0, -(4 / 3f) * (Min - (next1Key.value - (3 / 4f) * next1Key.inTangent.y))); //k+ out.x upperBound[curveIndex * 8 + 6] = next2Key.frame - next1Key.frame - next1Key.outTangent.x; //k+ out.y upperBound[curveIndex * 8 + 7] = Mathf.Max(0, Max - Mathf.Max(curvesMinMax[curveIndex, 1].x, curvesMinMax[curveIndex, 1].y)); }
private double[] GetAllTangents(int p, int K, List <int> requieredKeys) { double[] theta = new double[p]; for (int i = 0; i < 6; i++) { AnimatableProperty property = (AnimatableProperty)i; Curve curve = ObjectAnimation.GetCurve(property); for (int k = 0; k < K; k++) { AnimationKey key = curve.keys[requieredKeys[k]]; theta[4 * (i * K + k) + 0] = key.inTangent.x; theta[4 * (i * K + k) + 1] = key.inTangent.y; theta[4 * (i * K + k) + 2] = key.outTangent.x; theta[4 * (i * K + k) + 3] = key.outTangent.y; } } return(theta); }
public CommandAddKeyframe(GameObject obj, AnimatableProperty property, int frame, float value, Interpolation interpolation) { gObject = obj; this.property = property; newAnimationKey = new AnimationKey(frame, value, interpolation); AnimationSet animationSet = GlobalState.Animation.GetObjectAnimation(obj); if (null == animationSet) { return; } Curve curve = animationSet.GetCurve(property); if (null == curve) { return; } curve.TryFindKey(frame, out oldAnimationKey); }
/// <summary> /// Add a key at startFrame and endFrame. Move every keys in between towards the new key value. Then add the new keyframe. /// Used when draging a curve. /// </summary> public void AddZoneKey(AnimationKey key, int startFrame, int endFrame) { int firstKeyIndex = cachedKeysIndices[startFrame - (GlobalState.Animation.StartFrame - 1)]; int lastKeyIndex = cachedKeysIndices[endFrame - (GlobalState.Animation.StartFrame - 1)]; if (!Evaluate(key.frame, out float value)) { return; } if (keys[firstKeyIndex].frame != startFrame && Evaluate(startFrame, out float prevValue)) { AddKey(new AnimationKey(startFrame, prevValue, key.interpolation)); } if (keys[lastKeyIndex].frame != endFrame && Evaluate(endFrame, out float nextValue)) { AddKey(new AnimationKey(endFrame, nextValue, key.interpolation)); } float deltaValue = key.value - value; float zoneSize = endFrame - startFrame; for (int i = firstKeyIndex; i <= lastKeyIndex; i++) { int deltaFrame = Mathf.Abs(key.frame - keys[i].frame); float deltaTime = 1 - (deltaFrame / (float)zoneSize); if (property == AnimatableProperty.RotationX || property == AnimatableProperty.RotationY || property == AnimatableProperty.RotationZ) { keys[i].value = Mathf.LerpAngle(keys[i].value, keys[i].value + deltaValue, deltaTime); } else { keys[i].value = Mathf.Lerp(keys[i].value, keys[i].value + deltaValue, deltaTime); } ComputeCacheValuesAt(i); } AddKey(key); }
public CommandAddKeyframeZone(GameObject obj, AnimatableProperty property, int frame, float value, int startFrame, int endFrame, Interpolation interpolation) { gObject = obj; this.property = property; oldKeys = new List <AnimationKey>(); newKeys = new List <AnimationKey>(); AnimationSet animationSet = GlobalState.Animation.GetObjectAnimation(gObject); if (null == animationSet) { return; } Curve curve = animationSet.GetCurve(property); if (null == curve) { return; } AnimationKey newKey = new AnimationKey(frame, value, interpolation); curve.GetZoneKeyChanges(newKey, startFrame, endFrame, oldKeys, newKeys); }
private Vector2 GetMinMax(AnimationKey previous1Key, AnimationKey next1Key) { float A = previous1Key.value; float B = A + previous1Key.outTangent.y; float D = next1Key.value; float C = D - next1Key.inTangent.y; float a = -A + (3 * B) - (3 * C) + D; float b = (3 * A) - (6 * B) + (3 * C); float c = (-3 * A) + (3 * B); float tMin = 0; float tMax = 1; if (a != 0 && ((b * b) - 3 * a * c) > 0) { tMin = (-b - Mathf.Sqrt((b * b) - 3 * a * c)) / (3 * a); tMax = (-b + Mathf.Sqrt((b * b) - 3 * a * c)) / (3 * a); } float MinValue = Bezier.CubicBezier(A, B, C, D, Mathf.Clamp01(tMin)); float MaxValue = Bezier.CubicBezier(A, B, C, D, Mathf.Clamp01(tMax)); return(new Vector2(MinValue, MaxValue)); }
private bool EvaluateCache(int frame, out float value) { if (keys.Count == 0) { value = float.NaN; return(false); } int prevIndex = cachedKeysIndices[frame - GlobalState.Animation.StartFrame]; if (prevIndex == -1) { value = keys[0].value; return(true); } if (prevIndex == keys.Count - 1) { value = keys[keys.Count - 1].value; return(true); } AnimationKey prevKey = keys[prevIndex]; switch (prevKey.interpolation) { case Interpolation.Constant: value = prevKey.value; return(true); case Interpolation.Other: case Interpolation.Linear: { AnimationKey nextKey = keys[prevIndex + 1]; float dt = (float)(frame - prevKey.frame) / (float)(nextKey.frame - prevKey.frame); float oneMinusDt = 1f - dt; value = prevKey.value * oneMinusDt + nextKey.value * dt; return(true); } case Interpolation.Bezier: { AnimationKey nextKey = keys[prevIndex + 1]; Vector2 A = new Vector2(prevKey.frame, prevKey.value); Vector2 B, C; Vector2 D = new Vector2(nextKey.frame, nextKey.value); if (prevIndex == 0) { B = A + (D - A) / 3f; } else { AnimationKey prevPrevKey = keys[prevIndex - 1]; Vector2 V = (D - new Vector2(prevPrevKey.frame, prevPrevKey.value)).normalized; Vector2 AD = D - A; B = A + V * AD.magnitude / 3f; } if (prevIndex + 2 >= keys.Count) { C = D - (D - A) / 3f; } else { AnimationKey nextNextKey = keys[prevIndex + 2]; Vector2 V = (new Vector2(nextNextKey.frame, nextNextKey.value) - A).normalized; Vector2 AD = D - A; C = D - V * AD.magnitude / 3f; } value = EvaluateBezier(A, B, C, D, frame); return(true); } } value = float.NaN; return(false); }
public static void RemoveKeyframe(GameObject gobject, AnimatableProperty property, AnimationKey key) { GlobalState.Animation.RemoveKeyframe(gobject, property, key.frame); Instance.scene.RemoveKeyframe(gobject, property, key); }
public bool Setup() { Curve rotXCurve = objectAnimation.GetCurve(AnimatableProperty.RotationX); rotXCurve.GetKeyIndex(firstFrame, out int firstIndex); rotXCurve.GetKeyIndex(lastFrame, out int lastIndex); if (currentFrame < firstFrame) { return(false); } if (currentFrame > lastFrame) { return(false); } requiredKeyframe = new List <int>() { firstFrame, lastFrame }; keyCount = requiredKeyframe.Count; int curveCount = curves.Count; //number of curve * (in tangent x , in tangent y, out tangent x, out tangent y) * (k- , k+) paramCount = curveCount * 4 * 2; ds_thetaJob(paramCount, keyCount); theta = new double[paramCount]; Stiffnes_D = new double[paramCount, paramCount]; Continuity_T = new double[paramCount, paramCount]; curvesMinMax = new Vector2[curveCount, 2]; lowerBound = new double[paramCount]; upperBound = new double[paramCount]; scale = new double[paramCount]; delta_theta_0 = new double[paramCount]; //Hierarchy rotation curves for (int animIndex = 0; animIndex < animationCount; animIndex++) { for (int curve = 0; curve < 3; curve++) { int curveIndex = animIndex * 3 + curve; AnimationKey previous1Key = curves[curveIndex].keys[firstIndex]; AnimationKey previous2Key = firstIndex > 0 ? curves[curveIndex].keys[firstIndex - 1] : new AnimationKey(previous1Key.frame, previous1Key.value, inTangent: Vector2.zero, outTangent: Vector2.zero); AnimationKey next1Key = curves[curveIndex].keys[lastIndex]; AnimationKey next2key = lastIndex < curves[curveIndex].keys.Count - 1 ? curves[curveIndex].keys[lastIndex + 1] : new AnimationKey(next1Key.frame, next1Key.value, inTangent: Vector2.zero, outTangent: Vector2.zero); GetTangents(curveIndex * 8, previous1Key, next1Key); curvesMinMax[curveIndex, 0] = GetMinMax(previous2Key, previous1Key); curvesMinMax[curveIndex, 1] = GetMinMax(next1Key, next2key); float Min = controllers[animIndex].LowerAngleBound[curve]; float Max = controllers[animIndex].UpperAngleBound[curve]; FillLowerBounds(curveIndex, previous1Key, next1Key, Min, Max); FillUpperBounds(curveIndex, previous1Key, next1Key, previous2Key, next2key, Min, Max); GetContinuity(curveIndex * 8, Min, Max); //k- in x, k- in y, k- out x, k- out y, k+ in x, k+ in y, k+ out x, k+ out y for (int tan = 0; tan < 8; tan++) { int tanIndice = curveIndex * 8 + tan; Stiffnes_D[tanIndice, tanIndice] = animIndex == animationCount - 1 ? 0 : controllers[animIndex].stiffness; scale[tanIndice] = 1d; delta_theta_0[tanIndice] = 0; } } } //Root position curves int aIndex = animationCount; for (int curve = 0; curve < 3; curve++) { int curveIndex = aIndex * 3 + curve; AnimationKey previous1Key = curves[curveIndex].keys[firstIndex]; AnimationKey previous2Key = firstIndex > 0 ? curves[curveIndex].keys[firstIndex - 1] : new AnimationKey(previous1Key.frame, previous1Key.value, inTangent: Vector2.zero, outTangent: Vector2.zero); AnimationKey next1Key = curves[curveIndex].keys[lastIndex]; AnimationKey next2Key = lastIndex < curves[curveIndex].keys.Count - 1 ? curves[curveIndex].keys[lastIndex + 1] : new AnimationKey(next1Key.frame, next1Key.value, inTangent: Vector2.zero, outTangent: Vector2.zero); GetTangents(curveIndex * 8, previous1Key, next1Key); curvesMinMax[curveIndex, 0] = GetMinMax(previous2Key, previous1Key); curvesMinMax[curveIndex, 1] = GetMinMax(next1Key, next2Key); GetContinuity(curveIndex * 8); for (int tan = 0; tan < 8; tan++) { int tanIndice = curveIndex * 8 + tan; Stiffnes_D[tanIndice, tanIndice] = controllers[0].stiffness; lowerBound[tanIndice] = -10; upperBound[tanIndice] = 10; scale[tanIndice] = 1d; delta_theta_0[tanIndice] = 0; } } currentState = GetCurrentState(currentFrame); targetState = new State() { position = targetPosition, rotation = targetRotation, time = currentFrame }; Delta_s_prime = new double[7, 1]; for (int i = 0; i < 3; i++) { Delta_s_prime[i, 0] = targetState.position[i] - currentState.position[i]; } if ((currentState.rotation * Quaternion.Inverse(targetState.rotation)).w < 0) { targetState.rotation = new Quaternion(-targetState.rotation.x, -targetState.rotation.y, -targetState.rotation.z, -targetState.rotation.w); } for (int i = 0; i < 4; i++) { Delta_s_prime[i + 3, 0] = targetState.rotation[i] - currentState.rotation[i]; } Theta = Maths.ColumnArrayToArray(theta); return(true); }
public static void RemoveKeyframe(GameObject gobject, AnimatableProperty property, AnimationKey key, bool updateCurves = true, bool lockTangents = false) { GlobalState.Animation.RemoveKeyframe(gobject, property, key.frame, updateCurves, lockTangents); Instance.scene.RemoveKeyframe(gobject, property, key); }
public static void AddObjectKeyframe(GameObject gobject, AnimatableProperty property, AnimationKey key) { GlobalState.Animation.AddFilteredKeyframe(gobject, property, key); Instance.scene.AddKeyframe(gobject, property, key); }
public void RemoveKeyframe(GameObject gobject, AnimatableProperty property, AnimationKey key) { }
// Don't compute cache. Should be called when adding a lot of keys in a row. // And then don't forget to call ComputeCache(). public void AppendKey(AnimationKey key) { keys.Add(key); }