private StateMessage GetState(Inputs input) { StateMessage state_msg = new StateMessage(); state_msg.setPosition(cube_rigidbody.position); state_msg.setRotation(cube_rigidbody.rotation); state_msg.setVelocity(cube_rigidbody.velocity); state_msg.setVelocity_Ang(cube_rigidbody.angularVelocity); state_msg.setInput(input); state_msg.tick_number = tick_number; // Debug.Log("vel " + state_msg.velocity); return(state_msg); }
private void SimulateInterpolationHermite4(float interpolationFraction) { // if (InterpolationBuffer.Count >= 3 && !interpolationg) { SM1.setPosition(cube_rigidbody.position); SM1.setRotation(cube_rigidbody.rotation); SM1.setVelocity_Ang(cube_rigidbody.angularVelocity); SM2 = InterpolationBuffer.Dequeue(); SM3 = InterpolationBuffer.Dequeue(); SM4 = InterpolationBuffer.Dequeue(); journeyLength = interpolationFraction; Debug.Log("Interpolation starts sm1 " + SM1.getPosition() + "sm2 " + SM2.getPosition() + "sm3 " + SM3.getPosition() + "sm4 " + SM4.getPosition() + "buffer size " + InterpolationBuffer.Count); interpolationg = true; } if (interpolationg) { Vector3 IntPos = Hermite4(SM1.getPosition(), SM2.getPosition(), SM3.getPosition(), SM4.getPosition(), journeyLength); //Debug.Log("Interpolation in sm1 " + SM1.getPosition() + "sm2 " + SM2.getPosition() + "sm3 " + SM3.getPosition() + "sm4 " + SM4.getPosition()); Debug.Log("my postion " + cube_rigidbody.position + " hermite postion " + IntPos + " goal " + SM4.getPosition() + " fract of journey " + journeyLength); cube_rigidbody.position = IntPos; if (journeyLength >= 1f) { interpolationg = false; } else if (journeyLength >= 0.66f) { cube_rigidbody.rotation = Quaternion.Slerp(SM3.getRotation(), SM4.getRotation(), ((journeyLength - 0.66f) / 0.33f)); cube_rigidbody.velocity = SM3.getVelocity(); cube_rigidbody.angularVelocity = SM3.getVelocity_Angular(); } else if (journeyLength >= 0.33f) { cube_rigidbody.rotation = Quaternion.Slerp(SM2.getRotation(), SM3.getRotation(), ((journeyLength - 0.33f) / 0.33f)); cube_rigidbody.velocity = SM2.getVelocity(); cube_rigidbody.angularVelocity = SM2.getVelocity_Angular(); } else if (journeyLength >= 0.0f) { cube_rigidbody.rotation = Quaternion.Slerp(SM1.getRotation(), SM2.getRotation(), (journeyLength / 0.33f)); cube_rigidbody.velocity = SM1.getVelocity(); cube_rigidbody.angularVelocity = SM1.getVelocity_Angular(); } journeyLength += interpolationFraction; } }
void RewindState() { if (newStateMessages.Count > 0) { while (newStateMessages.Count != 0) { StateMessage state_msg = newStateMessages.Dequeue(); //uint buffer_slot = state_msg.tick_number % (uint)history.Count; Vector3 position_error = new Vector3(); position_error = state_msg.getPosition() - unConfirmedPredictions.Peek().getPosition(); float rotation_error = 1.0f - Quaternion.Dot(state_msg.getRotation(), unConfirmedPredictions.Peek().getRotation()); if (position_error.sqrMagnitude > 0.0000001f || rotation_error > 0.00001f) { // capture the current predicted pos for smoothing Vector3 prev_pos = cube_rigidbody.position + this.client_pos_error; Quaternion prev_rot = cube_rigidbody.rotation * this.client_rot_error; // rewind & replay Debug.Log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! rewind"); cube_rigidbody.position = state_msg.getPosition(); cube_rigidbody.rotation = state_msg.getRotation(); cube_rigidbody.velocity = state_msg.getVelocity(); cube_rigidbody.angularVelocity = state_msg.getVelocity_Angular(); int rewind_tick_number = (int)state_msg.tick_number; while (rewind_tick_number < tick_number) { StateMessage replay = unConfirmedPredictions.Dequeue(); AddForcesToPlayer(replay.getInput()); //for smoothig not applay dirrectly Physics.Simulate(Time.fixedDeltaTime); if (rewind_tick_number != state_msg.tick_number) { replay.setPosition(transform.position); replay.setRotation(transform.rotation); history.Add(replay); unConfirmedPredictions.Enqueue(replay); } ++rewind_tick_number; } // if more than 2ms apart, just snap if ((prev_pos - cube_rigidbody.position).sqrMagnitude >= 4.0f) { this.client_pos_error = Vector3.zero; this.client_rot_error = Quaternion.identity; } else { this.client_pos_error = prev_pos - cube_rigidbody.position; this.client_rot_error = Quaternion.Inverse(cube_rigidbody.rotation) * prev_rot; } } } } }