public void FixedUpdate(UnityEngine.Transform rootTransform) { // - physics rigid body management // -set transforms/velocities for key framed bodies // get all the prediction time infos in this struct PredictionTimeParameters timeInfo = new PredictionTimeParameters(UnityEngine.Time.fixedDeltaTime); // start the predictor _predictor.StartBodyPredicitonForNextFrame(); int index = 0; MultiSourceCombinedSnapshot snapshot; _snapshotManager.Step(timeInfo.DT, out snapshot); _snapshotManager.UpdateDebugDisplay(rootTransform); // guarded by ifdef internally foreach (var rb in _rigidBodies.Values) { // if the body is owned then we only set the kinematic flag for the physics if (rb.Ownership) { if (rb.IsKeyframed) { rb.RigidBody.isKinematic = true; } else { rb.RigidBody.isKinematic = false; } continue; } // Find corresponding rigid body info. // since both are sorted list this should hit without index=0 at the beginning while (index < snapshot.RigidBodies.Count && rb.Id.CompareTo(snapshot.RigidBodies.Values[index].Id) > 0) { index++; } if (index < snapshot.RigidBodies.Count && rb.Id == snapshot.RigidBodies.Values[index].Id) { // todo: kick-in prediction if we are missing an update for this rigid body //if (!snapshot.RigidBodies.Values[index].HasUpdate) //{ // rb.RigidBody.isKinematic = false; // continue; //} RigidBodyTransform transform = snapshot.RigidBodies.Values[index].Transform; float timeOfSnapshot = snapshot.RigidBodies.Values[index].LocalTime; // get the key framed stream, and compute implicit velocities UnityEngine.Vector3 keyFramedPos = rootTransform.TransformPoint(transform.Position); UnityEngine.Quaternion keyFramedOrientation = rootTransform.rotation * transform.Rotation; UnityEngine.Vector3 JBLinearVelocity = rootTransform.rotation * snapshot.RigidBodies.Values[index].LinearVelocity; UnityEngine.Vector3 JBAngularVelocity = rootTransform.rotation * snapshot.RigidBodies.Values[index].AngularVelocity; // if there is a really new update then also store the implicit velocity if (rb.lastTimeKeyFramedUpdate < timeOfSnapshot) { // we moved the velocity estimation into the jitter buffer rb.lastValidLinerVelocityOrPos = JBLinearVelocity; rb.lastValidAngularVelocityorAng = JBAngularVelocity; #if MRE_PHYSICS_DEBUG // test the source of large velocities if (rb.lastValidLinerVelocityOrPos.sqrMagnitude > _maxEstimatedLinearVelocity * _maxEstimatedLinearVelocity) { // limited debug version Debug.Log(" ACTIVE SPEED LIMIT TRAP RB: " //+ rb.Id.ToString() + " got update lin vel:" + rb.lastValidLinerVelocityOrPos + " ang vel:" + rb.lastValidAngularVelocityorAng + " time:" + timeOfSnapshot + " newR:" + rb.lastTimeKeyFramedUpdate + " hasupdate:" + snapshot.RigidBodies.Values[index].HasUpdate + " DangE:" + eulerAngles + " DangR:" + radianAngles); } #endif // cap the velocities rb.lastValidLinerVelocityOrPos = UnityEngine.Vector3.ClampMagnitude( rb.lastValidLinerVelocityOrPos, _maxEstimatedLinearVelocity); rb.lastValidAngularVelocityorAng = UnityEngine.Vector3.ClampMagnitude( rb.lastValidAngularVelocityorAng, _maxEstimatedAngularVelocity); // if body is sleeping then all velocities are zero if (snapshot.RigidBodies.Values[index].motionType == Patching.Types.MotionType.Sleeping) { rb.lastValidLinerVelocityOrPos.Set(0.0F, 0.0F, 0.0F); rb.lastValidAngularVelocityorAng.Set(0.0F, 0.0F, 0.0F); } #if MRE_PHYSICS_DEBUG if (true) { // limited debug version Debug.Log(" Remote body: " + rb.Id.ToString() + " got update lin vel:" + rb.lastValidLinerVelocityOrPos + " ang vel:" + rb.lastValidAngularVelocityorAng + " time:" + timeOfSnapshot + " newR:" + rb.lastTimeKeyFramedUpdate); } else { Debug.Log(" Remote body: " + rb.Id.ToString() + " got update lin vel:" + rb.lastValidLinerVelocityOrPos + " ang vel:" + rb.lastValidAngularVelocityorAng //+ " DangE:" + eulerAngles + " DangR:" + radianAngles + " time:" + timeOfSnapshot + " newp:" + keyFramedPos + " newR:" + keyFramedOrientation + " oldP:" + rb.RigidBody.transform.position + " oldR:" + rb.RigidBody.transform.rotation + " OriginalRot:" + transform.Rotation + " keyF:" + rb.RigidBody.isKinematic + " KF:" + rb.IsKeyframed); } #endif // cap the velocities rb.lastValidLinerVelocityOrPos = UnityEngine.Vector3.ClampMagnitude( rb.lastValidLinerVelocityOrPos, _maxEstimatedLinearVelocity); rb.lastValidAngularVelocityorAng = UnityEngine.Vector3.ClampMagnitude( rb.lastValidAngularVelocityorAng, _maxEstimatedAngularVelocity); // if body is sleeping then all velocities are zero if (snapshot.RigidBodies.Values[index].motionType == Patching.Types.MotionType.Sleeping) { rb.lastValidLinerVelocityOrPos.Set(0.0F, 0.0F, 0.0F); rb.lastValidAngularVelocityorAng.Set(0.0F, 0.0F, 0.0F); } #if MRE_PHYSICS_DEBUG Debug.Log(" Remote body: " + rb.Id.ToString() + " got update lin vel:" + rb.lastValidLinerVelocityOrPos + " ang vel:" + rb.lastValidAngularVelocityorAng //+ " DangE:" + eulerAngles + " DangR:" + radianAngles + " time:" + timeOfSnapshot + " newp:" + keyFramedPos + " newR:" + keyFramedOrientation + " incUpdateDt:" + invUpdateDT + " oldP:" + rb.RigidBody.transform.position + " oldR:" + rb.RigidBody.transform.rotation + " OriginalRot:" + transform.Rotation + " keyF:" + rb.RigidBody.isKinematic + " KF:" + rb.IsKeyframed); #endif } rb.lastTimeKeyFramedUpdate = timeOfSnapshot; rb.IsKeyframed = (snapshot.RigidBodies.Values[index].motionType == Patching.Types.MotionType.Keyframed); // code to disable prediction and to use just key framing (and comment out the prediction) //rb.RigidBody.isKinematic = true; //rb.RigidBody.transform.position = keyFramedPos; //rb.RigidBody.transform.rotation = keyFramedOrientation; //rb.RigidBody.velocity.Set(0.0f, 0.0f, 0.0f); //rb.RigidBody.angularVelocity.Set(0.0f, 0.0f, 0.0f); // call the predictor with this remotely owned body _predictor.AddAndProcessRemoteBodyForPrediction(rb, transform, keyFramedPos, keyFramedOrientation, timeOfSnapshot, timeInfo); } } // call the predictor _predictor.PredictAllRemoteBodiesWithOwnedBodies(ref _rigidBodies, timeInfo); }
public void FixedUpdate(UnityEngine.Transform rootTransform) { // - physics rigid body management // -set transforms/velocities for key framed bodies // get all the prediction time infos in this struct PredictionTimeParameters timeInfo = new PredictionTimeParameters(UnityEngine.Time.fixedDeltaTime); // start the predictor _predictor.StartBodyPredicitonForNextFrame(); int index = 0; MultiSourceCombinedSnapshot snapshot = _snapshotManager.GetNextSnapshot(timeInfo.DT); foreach (var rb in _rigidBodies.Values) { // if the body is owned then we only set the kinematic flag for the physics if (rb.Ownership) { if (rb.IsKeyframed) { rb.RigidBody.isKinematic = true; } else { rb.RigidBody.isKinematic = false; } continue; } // Find corresponding rigid body info. // since both are sorted list this should hit without index=0 at the beginning while (index < snapshot.RigidBodies.Count && rb.Id.CompareTo(snapshot.RigidBodies.Values[index].Id) > 0) { index++; } if (index < snapshot.RigidBodies.Count && rb.Id == snapshot.RigidBodies.Values[index].Id) { // todo: kick-in prediction if we are missing an update for this rigid body //if (!snapshot.RigidBodies.Values[index].HasUpdate) //{ // rb.RigidBody.isKinematic = false; // continue; //} RigidBodyTransform transform = snapshot.RigidBodies.Values[index].Transform; float timeOfSnapshot = snapshot.RigidBodies.Values[index].LocalTime; // get the key framed stream, and compute implicit velocities UnityEngine.Vector3 keyFramedPos = rootTransform.TransformPoint(transform.Position); UnityEngine.Quaternion keyFramedOrientation = rootTransform.rotation * transform.Rotation; // if there is a really new update then also store the implicit velocity if (rb.lastTimeKeyFramedUpdate < timeOfSnapshot) { // <todo> for long running times this could be a problem float invUpdateDT = 1.0f / (timeOfSnapshot - rb.lastTimeKeyFramedUpdate); rb.lastValidLinerVelocity = (keyFramedPos - rb.RigidBody.transform.position) * invUpdateDT; // transform to radians and take the angular velocity UnityEngine.Vector3 eulerAngles = ( UnityEngine.Quaternion.Inverse(rb.RigidBody.transform.rotation) * keyFramedOrientation).eulerAngles; UnityEngine.Vector3 radianAngles = UtilMethods.TransformEulerAnglesToRadians(eulerAngles); rb.lastValidAngularVelocity = radianAngles * invUpdateDT; #if MRE_PHYSICS_DEBUG Debug.Log(" Remote body: " + rb.Id.ToString() + " got update lin vel:" + rb.lastValidLinerVelocity + " ang vel:" + rb.lastValidAngularVelocity //+ " DangE:" + eulerAngles + " DangR:" + radianAngles + " time:" + timeOfSnapshot + " newp:" + keyFramedPos + " newR:" + keyFramedOrientation + " incUpdateDt:" + invUpdateDT + " oldP:" + rb.RigidBody.transform.position + " oldR:" + rb.RigidBody.transform.rotation + " OriginalRot:" + transform.Rotation + " keyF:" + rb.RigidBody.isKinematic + " KF:" + rb.IsKeyframed); #endif } rb.lastTimeKeyFramedUpdate = timeOfSnapshot; rb.IsKeyframed = (snapshot.RigidBodies.Values[index].motionType == Patching.Types.MotionType.Keyframed); // code to disable prediction and to use just key framing //rb.RigidBody.isKinematic = true; //rb.RigidBody.transform.position = keyFramedPos; //rb.RigidBody.transform.rotation = keyFramedOrientation; //rb.RigidBody.velocity.Set(0.0f, 0.0f, 0.0f); //rb.RigidBody.angularVelocity.Set(0.0f, 0.0f, 0.0f); // call the predictor with this remotely owned body _predictor.AddAndProcessRemoteBodyForPrediction(rb, transform, keyFramedPos, keyFramedOrientation, timeOfSnapshot, timeInfo); } } // call the predictor _predictor.PredictAllRemoteBodiesWithOwnedBodies(ref _rigidBodies, timeInfo); }