/// <summary> /// Adds the current state to the states queue. /// </summary> public void AddState(DynamicsWorld world, float timeStep, int numSteps) { if (!mainState.Tracking) { return; } StateDescriptor nextState = State; if (numSteps == 1) // This will be the case the vast majority of the time { States.Add(State); } else // If there's some random lag spike { StateDescriptor lastState = States.Front; float lerpAmount = 1f / numSteps; for (int i = 0; i < numSteps; i++) { float percent = (i + 1) * lerpAmount; States.Add(new StateDescriptor { Position = BulletSharp.Math.Vector3.Lerp(lastState.Position, nextState.Position, percent), Rotation = BulletSharp.Math.Matrix.Lerp(lastState.Rotation, nextState.Rotation, percent), LinearVelocity = BulletSharp.Math.Vector3.Lerp(lastState.LinearVelocity, nextState.LinearVelocity, percent), AngularVelocity = BulletSharp.Math.Vector3.Lerp(lastState.AngularVelocity, nextState.AngularVelocity, percent) }); } } }
/// <summary> /// Resets the trackers and reenables the RigidBodies. /// </summary> public override void End() { SelectedBody = null; //(SimUI.changeAnalytics.ToString()); if (SimUI.changeAnalytics) { Analytics.CustomEvent("Replay Mode", new Dictionary <string, object> { { "time", Time.time - tStart }, }); } foreach (Tracker t in trackers) { if (t.Trace) { UnityEngine.Object.Destroy(t.gameObject.GetComponent <LineRenderer>()); } StateDescriptor currentState = t.States[(int)Math.Floor(RewindFrame)]; RigidBody r = (RigidBody)t.GetComponent <BRigidBody>().GetCollisionObject(); r.LinearFactor = r.AngularFactor = BulletSharp.Math.Vector3.One; r.LinearVelocity = currentState.LinearVelocity; r.AngularVelocity = currentState.AngularVelocity; t.Clear(); } }
/// <summary> /// Updates the positions and rotations of each tracker's parent object according to the replay time. /// </summary> public override void LateUpdate() { if (dynamicCamera == null) { dynamicCamera = UnityEngine.Object.FindObjectOfType <DynamicCamera>(); camera = dynamicCamera.GetComponent <Camera>(); } if (InputControl.GetButtonDown(Controls.buttons[0].cameraToggle)) { dynamicCamera.ToggleCameraState(dynamicCamera.cameraState); } if (firstFrame) { firstFrame = false; } else if (Input.GetKeyDown(KeyCode.Space)) { if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) { rewindTime = Tracker.Lifetime; playbackMode = PlaybackMode.Play; } else { switch (playbackMode) { case PlaybackMode.Paused: if (rewindTime == 0f) { rewindTime = Tracker.Lifetime; } playbackMode = PlaybackMode.Play; break; case PlaybackMode.Play: case PlaybackMode.Rewind: playbackMode = PlaybackMode.Paused; break; } } } switch (playbackMode) { case PlaybackMode.Rewind: rewindTime += Time.deltaTime; break; case PlaybackMode.Play: rewindTime -= Time.deltaTime; break; } if (Input.GetKey(KeyCode.LeftArrow)) { rewindTime += Time.deltaTime * (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl) ? 0.05f : 0.25f); playbackMode = PlaybackMode.Paused; } if (Input.GetKey(KeyCode.RightArrow)) { rewindTime -= Time.deltaTime * (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl) ? 0.05f : 0.25f); playbackMode = PlaybackMode.Paused; } if (rewindTime < 0.0f) { rewindTime = 0.0f; playbackMode = PlaybackMode.Paused; } else if (rewindTime > Tracker.Lifetime) { rewindTime = Tracker.Lifetime; playbackMode = PlaybackMode.Paused; } foreach (Tracker t in trackers) { float replayTime = RewindFrame; int currentIndex = (int)Math.Floor(replayTime); StateDescriptor lowerState = t.States[currentIndex]; StateDescriptor upperState = currentIndex < t.States.Length - 1 ? t.States[currentIndex + 1] : lowerState; float percent = replayTime - currentIndex; BRigidBody rb = t.GetComponent <BRigidBody>(); if (!rb.GetCollisionObject().IsActive) { rb.GetCollisionObject().Activate(); } rb.SetPosition(BulletSharp.Math.Vector3.Lerp(lowerState.Position, upperState.Position, percent).ToUnity()); rb.SetRotation(BulletSharp.Math.Matrix.Lerp(lowerState.Rotation, upperState.Rotation, percent).GetOrientation().ToUnity()); } }
/// <summary> /// Updates the positions and rotations of each tracker's parent object according to the replay time. /// </summary> public override void Update() { if (dynamicCamera == null) { dynamicCamera = UnityEngine.Object.FindObjectOfType <DynamicCamera>(); camera = dynamicCamera.GetComponent <Camera>(); } if (InputControl.GetButtonDown(Controls.buttons[0].cameraToggle)) { dynamicCamera.ToggleCameraState(dynamicCamera.cameraState); } if (firstFrame) { firstFrame = false; } else if (Input.GetKeyDown(KeyCode.Space)) { if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) { rewindTime = Tracker.Lifetime; playbackMode = PlaybackMode.Play; } else { switch (playbackMode) { case PlaybackMode.Paused: if (rewindTime == 0f) { rewindTime = Tracker.Lifetime; } playbackMode = PlaybackMode.Play; break; case PlaybackMode.Play: case PlaybackMode.Rewind: playbackMode = PlaybackMode.Paused; break; } } } switch (playbackMode) { case PlaybackMode.Rewind: rewindTime += Time.smoothDeltaTime * playbackSpeed; break; case PlaybackMode.Play: rewindTime -= Time.smoothDeltaTime * playbackSpeed; break; } if (Input.GetKey(KeyCode.LeftArrow)) { rewindTime += Time.smoothDeltaTime * 0.25f; playbackMode = PlaybackMode.Paused; } if (Input.GetKey(KeyCode.RightArrow)) { rewindTime -= Time.smoothDeltaTime * 0.25f; playbackMode = PlaybackMode.Paused; } if (rewindTime < 0.0f) { rewindTime = 0.0f; playbackMode = PlaybackMode.Paused; } else if (rewindTime > Tracker.Lifetime) { rewindTime = Tracker.Lifetime; playbackMode = PlaybackMode.Paused; } foreach (Tracker t in trackers) { float replayTime = RewindFrame; int currentIndex = (int)Math.Floor(replayTime); StateDescriptor lowerState = t.States[currentIndex]; StateDescriptor upperState = currentIndex < t.States.Length - 1 ? t.States[currentIndex + 1] : lowerState; float percent = replayTime - currentIndex; RigidBody r = (RigidBody)t.GetComponent <BRigidBody>().GetCollisionObject(); if (!r.IsActive) { r.Activate(); } BulletSharp.Math.Matrix worldTransform = r.WorldTransform; worldTransform.Origin = BulletSharp.Math.Vector3.Lerp(lowerState.Position, upperState.Position, percent); worldTransform.Basis = BulletSharp.Math.Matrix.Lerp(lowerState.Rotation, upperState.Rotation, percent); r.WorldTransform = worldTransform; } if (Input.GetKeyDown(KeyCode.Tab)) { StateMachine.Instance.PopState(); } }