public void CanLoopKeyframes() { var keyframe1 = "test-1"; var keyframe2 = "test-2"; var keyframe3 = "test-3"; var time1 = TimeSpan.FromSeconds(2); var mid12 = TimeSpan.FromSeconds(10); // 7 seconds, loop, then 3 more seconds var time2 = TimeSpan.FromSeconds(4); var time3 = TimeSpan.FromSeconds(6); var loopDelay = TimeSpan.FromSeconds(1); var anim = new KeyframeAnimation <string>() .AddKeyframe(time1, keyframe1) .AddKeyframe(time2, keyframe2) .AddKeyframe(time3, keyframe3) .Loop(loopDelay); // Before 1st keyframe var mid01 = time1 - ((time2 - time1) / 2); Assert.True(mid01 < time1); Assert.Equal(keyframe3, anim.GetFrame(mid01)); // After last keyframe, but before loop var mid34 = time3 + (loopDelay / 2); Assert.True(mid34 > time3); Assert.Equal(keyframe3, anim.GetFrame(mid34)); // After one loop, then between frames 1 and 2 Assert.Equal(keyframe1, anim.GetFrame(mid12)); }
public void CanOverwriteKeyframe() { var anim = new KeyframeAnimation <Rect2d>(); anim.AddKeyframe(TimeSpan.FromMilliseconds(30), new Rect2d(1, 2, 3, 4)); anim.AddKeyframe(TimeSpan.FromMilliseconds(30), new Rect2d(5, 6, 7, 8)); Assert.Single(anim.Keyframes); }
public void CanAddKeyframe() { var anim = new KeyframeAnimation <Rect2d>(); anim.AddKeyframe(TimeSpan.Zero, new Rect2d(1, 2, 3, 4)); Assert.Single(anim.Keyframes); anim.AddKeyframe(TimeSpan.FromMilliseconds(30), new Rect2d(5, 6, 7, 8)); Assert.Equal(2, anim.Keyframes.Count); }
public void CanGetExactSingleKeyframe() { var keyframe = "test"; var time = TimeSpan.FromMinutes(5); var anim = new KeyframeAnimation <string>(); anim.AddKeyframe(time, keyframe); Assert.Equal(keyframe, anim.GetFrame(time)); }
public void CanGetApproximateSingleKeyframe() { var keyframe = "test"; var time = TimeSpan.FromMinutes(5); var diff = TimeSpan.FromSeconds(15); var anim = new KeyframeAnimation <string>(); anim.AddKeyframe(time, keyframe); Assert.Equal(keyframe, anim.GetFrame(time.Subtract(diff))); Assert.Equal(keyframe, anim.GetFrame(time.Add(diff))); }
public void CanGetExactMultipleKeyframes() { var keyframe1 = "test-1"; var keyframe2 = "test-2"; var keyframe3 = "test-3"; var time1 = TimeSpan.FromMinutes(5); var time2 = TimeSpan.FromMinutes(6); var time3 = TimeSpan.FromMinutes(7); var anim = new KeyframeAnimation <string>() .AddKeyframe(time1, keyframe1) .AddKeyframe(time2, keyframe2) .AddKeyframe(time3, keyframe3); Assert.Equal(keyframe1, anim.GetFrame(time1)); Assert.Equal(keyframe2, anim.GetFrame(time2)); Assert.Equal(keyframe3, anim.GetFrame(time3)); }
public void TestKeyframeAnimationSerialization() { KeyframeAnimation anim = new KeyframeAnimation() { CurrentAnimationPosition = 5, CurrentCommand = KeyframeAnimation.Commands.Stop, CurrentMode = KeyframeAnimation.Modes.PingPong, InitialPosition = new Vector3(128, 128, 128), InitialRotation = new Quaternion(0.25f, 0.5f, 0.75f, 1.0f), PingPongForwardMotion = true, PositionList = new Vector3[3] { new Vector3(10, 0, 0), new Vector3(-10, 0, 0), new Vector3(0, 0, 10) }, RotationList = new Quaternion[3] { new Quaternion(0.4f, 0.6f, 0.8f, 1), new Quaternion(0.2f, 0.5f, 0.8f, 1), new Quaternion(0.1f, 0.5f, 0.9f, 1) }, TimeElapsed = 678, TimeLastTick = Environment.TickCount, TimeList = new TimeSpan[3] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) } }; byte[] byteFormat = serEngine.MiscObjectSerializer.SerializeKeyframeAnimationToBytes(anim); KeyframeAnimation deserializedAnim = serEngine.MiscObjectSerializer.DeserializeKeyframeAnimationFromBytes(byteFormat); CompareObjects comp = new CompareObjects(); comp.CompareStaticFields = false; comp.CompareStaticProperties = false; comp.ElementsToIgnore = PrimCompareIgnoreList; Assert.IsTrue(comp.Compare(anim, deserializedAnim), comp.DifferencesString); }
public void CanGetApproximateMultipleKeyframes() { var keyframe1 = "test-1"; var keyframe2 = "test-2"; var keyframe3 = "test-3"; var time1 = TimeSpan.FromMinutes(5); var time2 = TimeSpan.FromMinutes(6); var time3 = TimeSpan.FromMinutes(7); var anim = new KeyframeAnimation <string>() .AddKeyframe(time1, keyframe1) .AddKeyframe(time2, keyframe2) .AddKeyframe(time3, keyframe3); // Before 1st keyframe var mid01 = time1 - ((time2 - time1) / 2); Assert.True(mid01 < time1); Assert.Equal(keyframe1, anim.GetFrame(mid01)); // Between keyframes 1 and 2 var mid12 = time2 - ((time2 - time1) / 2); Assert.InRange(mid12, time1, time2); Assert.Equal(keyframe1, anim.GetFrame(mid12)); // Between keyframes 2 and 3 var mid23 = time2 + ((time3 - time2) / 2); Assert.InRange(mid23, time2, time3); Assert.Equal(keyframe2, anim.GetFrame(mid23)); // After last keyframe var mid34 = time3 + ((time3 - time2) / 2); Assert.True(mid34 > time3); Assert.Equal(keyframe3, anim.GetFrame(mid34)); }
public void llSetKeyframedMotion(LSL_List keyframes, LSL_List options) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } if (!m_host.IsRoot) { Error("llSetKeyframedMotion", "Must be used in the root object!"); return; } KeyframeAnimation.Data dataType = KeyframeAnimation.Data.Both; KeyframeAnimation.Modes currentMode = KeyframeAnimation.Modes.Forward; for (int i = 0; i < options.Length; i += 2) { LSL_Integer option = options.GetLSLIntegerItem(i); LSL_Integer value = options.GetLSLIntegerItem(i + 1); if (option == ScriptBaseClass.KFM_COMMAND) { m_host.ParentEntity.AddKeyframedMotion(null, (KeyframeAnimation.Commands)value.value); break; //Its supposed to be the only option in the list } if (option == ScriptBaseClass.KFM_MODE) { currentMode = (KeyframeAnimation.Modes)value.value; } else if (option == ScriptBaseClass.KFM_DATA) { dataType = (KeyframeAnimation.Data)value.value; } } List <Vector3> positions = new List <Vector3>(); List <Quaternion> rotations = new List <Quaternion>(); List <float> times = new List <float>(); for (int i = 0; i < keyframes.Length; i += (dataType == KeyframeAnimation.Data.Both ? 3 : 2)) { if (dataType == KeyframeAnimation.Data.Both || dataType == KeyframeAnimation.Data.Translation) { LSL_Vector pos = keyframes.GetVector3Item(i); positions.Add(pos.ToVector3()); } if (dataType == KeyframeAnimation.Data.Both || dataType == KeyframeAnimation.Data.Rotation) { LSL_Rotation rot = keyframes.GetQuaternionItem(i + (dataType == KeyframeAnimation.Data.Both ? 1 : 0)); Quaternion quat = rot.ToQuaternion(); quat.Normalize(); rotations.Add(quat); } LSL_Float time = keyframes.GetLSLFloatItem(i + (dataType == KeyframeAnimation.Data.Both ? 2 : 1)); times.Add((float)time); } KeyframeAnimation animation = new KeyframeAnimation { CurrentMode = currentMode, PositionList = positions.ToArray(), RotationList = rotations.ToArray(), TimeList = times.ToArray(), CurrentAnimationPosition = 0, InitialPosition = m_host.AbsolutePosition, InitialRotation = m_host.GetRotationOffset() }; m_host.ParentEntity.AddKeyframedMotion(animation, KeyframeAnimation.Commands.Play); }
public void AddKeyframedMotion(KeyframeAnimation animation, KeyframeAnimation.Commands command) { if (command == KeyframeAnimation.Commands.Play) { KeyframeAnimation = animation; m_scene.EventManager.OnFrame += moveKeyframeMotion; } else { m_scene.EventManager.OnFrame -= moveKeyframeMotion; if (command == KeyframeAnimation.Commands.Stop) KeyframeAnimation = null; } }
public void llSetKeyframedMotion(LSL_List keyframes, LSL_List options) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return; if (!m_host.IsRoot) { ShoutError("Must be used in the root object!"); return; } KeyframeAnimation.Data dataType = KeyframeAnimation.Data.Both; KeyframeAnimation.Modes currentMode = KeyframeAnimation.Modes.Forward; for (int i = 0; i < options.Length; i += 2) { LSL_Integer option = options.GetLSLIntegerItem(i); LSL_Integer value = options.GetLSLIntegerItem(i + 1); if (option == ScriptBaseClass.KFM_COMMAND) { m_host.ParentEntity.AddKeyframedMotion(null, (KeyframeAnimation.Commands) value.value); break; //Its supposed to be the only option in the list } if (option == ScriptBaseClass.KFM_MODE) { currentMode = (KeyframeAnimation.Modes) value.value; } else if (option == ScriptBaseClass.KFM_DATA) { dataType = (KeyframeAnimation.Data) value.value; } } List<Vector3> positions = new List<Vector3>(); List<Quaternion> rotations = new List<Quaternion>(); List<int> times = new List<int>(); for (int i = 0; i < keyframes.Length; i += (dataType == KeyframeAnimation.Data.Both ? 3 : 2)) { if (dataType == KeyframeAnimation.Data.Both || dataType == KeyframeAnimation.Data.Translation) { LSL_Vector pos = keyframes.GetVector3Item(i); positions.Add(pos.ToVector3()); } if (dataType == KeyframeAnimation.Data.Both || dataType == KeyframeAnimation.Data.Rotation) { LSL_Rotation rot = keyframes.GetQuaternionItem(i + (dataType == KeyframeAnimation.Data.Both ? 1 : 0)); Quaternion quat = rot.ToQuaternion(); quat.Normalize(); rotations.Add(quat); } int time = keyframes.GetLSLIntegerItem(i + (dataType == KeyframeAnimation.Data.Both ? 2 : 1)); times.Add(time); } KeyframeAnimation animation = new KeyframeAnimation { CurrentMode = currentMode, PositionList = positions.ToArray(), RotationList = rotations.ToArray(), TimeList = times.ToArray(), CurrentAnimationPosition = 0, InitialPosition = m_host.AbsolutePosition, InitialRotation = m_host.GetRotationOffset() }; m_host.ParentEntity.AddKeyframedMotion(animation, KeyframeAnimation.Commands.Play); }
public void AddKeyframedMotion(KeyframeAnimation animation, KeyframeAnimation.Commands command) { if (command == KeyframeAnimation.Commands.Play) { m_rootPart.KeyframeAnimation = animation; //Only have one at a time m_scene.EventManager.OnFrame -= moveKeyframeMotion; m_scene.EventManager.OnFrame += moveKeyframeMotion; } else { m_scene.EventManager.OnFrame -= moveKeyframeMotion; if (command == KeyframeAnimation.Commands.Stop) m_rootPart.KeyframeAnimation = null; } }
public void CannotGetWithNoKeyframes() { var anim = new KeyframeAnimation <Rect2d>(); Assert.Throws <InvalidOperationException>(() => anim.GetFrame(TimeSpan.FromMilliseconds(30))); }