// The smaller of the two possible angles between the two vectors is returned, therefore the result will never be greater than 180 degrees or smaller than -180 degrees. // If you imagine the from and to vectors as lines on a piece of paper, both originating from the same point, then the /axis/ vector would point up out of the paper. // The measured angle between the two vectors would be positive in a clockwise direction and negative in an anti-clockwise direction. public static Fix64 SignedAngle(FixVector3 from, FixVector3 to, FixVector3 axis) { FixVector3 fromNorm = from.Normalized, toNorm = to.Normalized; Fix64 unsignedAngle = FixMath.Acos(FixMath.Clamp(Dot(fromNorm, toNorm), -Fix64.ONE, Fix64.ONE)) * FixMath.Rad2Deg; Fix64 sign = FixMath.Sign(Dot(axis, Cross(fromNorm, toNorm))); return(unsignedAngle * sign); }
public static FixVector2 Lerp(FixVector2 value1, FixVector2 value2, Fix64 amount) { amount = FixMath.Clamp(amount, 0, 1); return(new FixVector2( FixMath.Lerp(value1.x, value2.x, amount), FixMath.Lerp(value1.y, value2.y, amount))); }
public static FixQuaternion Slerp(FixQuaternion from, FixQuaternion to, Fix64 t) { t = FixMath.Clamp(t, 0, 1); Fix64 dot = Dot(from, to); if (dot < 0.0f) { to = Multiply(to, -1); dot = -dot; } Fix64 halfTheta = Fix64.Acos(dot); return(Multiply(Multiply(from, Fix64.Sin((1 - t) * halfTheta)) + Multiply(to, Fix64.Sin(t * halfTheta)), 1 / Fix64.Sin(halfTheta))); }
private Fix64 ClampAngle(Fix64 angle, Fix64 min, Fix64 max) { while (angle < -360) { angle += 360; } while (angle > 360) { angle -= 360; } if (angle > max && angle - 360 >= min) { return(angle - 360); } if (angle < min && angle + 360 <= max) { return(angle + 360); } return(FixMath.Clamp(angle, -max, -min)); }
/// Clamp a vector to a bounding box. public FixVec2 ClampVect(FixVec2 v) { return(new FixVec2(FixMath.Clamp(v.X, L, R), FixMath.Clamp(v.Y, B, T))); }
public static FixQuaternion Lerp(FixQuaternion a, FixQuaternion b, Fix64 t) { t = FixMath.Clamp(t, Fix64.Zero, Fix64.One); return(LerpUnclamped(a, b, t)); }
public static void Clamp(ref FixVector2 value1, ref FixVector2 min, ref FixVector2 max, out FixVector2 result) { result = new FixVector2( FixMath.Clamp(value1.x, min.x, max.x), FixMath.Clamp(value1.y, min.y, max.y)); }
public static FixVector2 Clamp(FixVector2 value1, FixVector2 min, FixVector2 max) { return(new FixVector2( FixMath.Clamp(value1.x, min.x, max.x), FixMath.Clamp(value1.y, min.y, max.y))); }
public override void OnEnable() { base.OnEnable(); PlayerControlComponents.OnAdd() .Where(entity => !entity.HasComponent <NetworkPlayerComponent>()) .Subscribe(entity => { var playerControlComponent = entity.GetComponent <PlayerControlComponent>(); var characterController = entity.GetComponent <CharacterController>(); var viewComponent = entity.GetComponent <ViewComponent>(); Observable.EveryUpdate().Subscribe(_ => { if (characterController.isGrounded) { var angle = Vector3.Angle(viewComponent.Transforms[0].forward, mainCamera.transform.forward); if (angle < InvertRange.Min || angle > InvertRange.Max) { playerControlComponent.motion = new FixVector3(Input.GetAxis(InputParameters.Horizontal), 0, Input.GetAxis(InputParameters.Vertical)); } else { playerControlComponent.motion = new FixVector3(Input.GetAxis(InputParameters.Vertical), 0, Input.GetAxis(InputParameters.Horizontal)); } playerControlComponent.motion = (FixVector3)viewComponent.Transforms[0].TransformDirection((Vector3)playerControlComponent.motion); playerControlComponent.motion *= playerControlComponent.Run; if (Input.GetButton(InputParameters.Jump)) { playerControlComponent.motion.y = playerControlComponent.Jump; } } playerControlComponent.motion.y -= playerControlComponent.Gravity * Time.deltaTime; characterController.Move((Vector3)playerControlComponent.motion * Time.deltaTime); }).AddTo(this.Disposer).AddTo(playerControlComponent.Disposer); }).AddTo(this.Disposer); NetwrokTimeline.OnReverse((entity, result) => { var playerControlComponent = entity.GetComponent <PlayerControlComponent>(); var viewComponent = entity.GetComponent <ViewComponent>(); var playerControlResult = (PlayerControlResult)result[0]; viewComponent.Transforms[0].rotation = playerControlResult.Rotation; playerControlComponent.Follow.rotation = playerControlResult.Follow; viewComponent.Transforms[0].position = playerControlResult.Position; }).AddTo(this.Disposer); NetwrokTimeline.OnForward((entity, userInputData, deltaTime) => { var playerControlComponent = entity.GetComponent <PlayerControlComponent>(); var characterController = entity.GetComponent <CharacterController>(); var viewComponent = entity.GetComponent <ViewComponent>(); var animator = entity.GetComponent <Animator>(); var axisInput = userInputData[0].GetInput <AxisInput>(); var keyInput = userInputData[1].GetInput <KeyInput>(); var mouseInput = userInputData[2].GetInput <MouseInput>(); var playerControlResult = new PlayerControlResult(); var smoothTime = playerControlComponent.smoothTime; var yAngle = Fix64.Zero; playerControlResult.Rotation = viewComponent.Transforms[0].rotation; playerControlResult.Follow = playerControlComponent.Follow.rotation; playerControlResult.Position = viewComponent.Transforms[0].position; if (mouseInput != null && keyInput != null && axisInput != null) { var rotLeftRight = mouseInput.Delta.x * playerControlComponent.MouseSensivity.x * deltaTime; var rotUpDown = mouseInput.Delta.y * playerControlComponent.MouseSensivity.y * deltaTime; if (mouseInput.MouseButtons.Contains(1)) { playerControlComponent.aimTime += deltaTime; if (playerControlComponent.Aim.Value == AimMode.Free && playerControlComponent.aimTime > ShoulderAimTime) { playerControlComponent.Aim.Value = AimMode.Shoulder; } } else { if (playerControlComponent.Aim.Value == AimMode.Free) { if (playerControlComponent.aimTime > 0) { playerControlComponent.Aim.Value = AimMode.AimDownSight; } } else if (playerControlComponent.aimTime > 0) { playerControlComponent.Aim.Value = AimMode.Free; } playerControlComponent.aimTime = 0; } if (playerControlComponent.Aim.Value == AimMode.Free && keyInput.KeyCodes.Contains((int)KeyCode.LeftAlt)) { playerControlComponent.Follow.rotation = (Quaternion)((FixQuaternion)playerControlComponent.Follow.rotation * FixQuaternion.Euler(-rotUpDown, rotLeftRight, 0)); animator.SetFloat(Head_Vertical_f, 0); animator.SetFloat(Body_Vertical_f, 0); smoothTime = SmoothTime; } else { if (smoothTime > 0) { playerControlComponent.Follow.localRotation = (Quaternion)FixQuaternion.Lerp(FixQuaternion.identity, (FixQuaternion)playerControlComponent.Follow.localRotation, FixMath.Clamp01(smoothTime / SmoothTime)); animator.SetFloat(Head_Vertical_f, 0); animator.SetFloat(Body_Vertical_f, 0); smoothTime -= deltaTime; } else { yAngle = ClampAngle(playerControlComponent.Follow.localEulerAngles.x, playerControlComponent.YAngleLimit.Min, playerControlComponent.YAngleLimit.Max); yAngle = ClampAngle(yAngle - rotUpDown, playerControlComponent.YAngleLimit.Min, playerControlComponent.YAngleLimit.Max); var vertical = 2 * (0.5f - FixMath.Abs(yAngle - playerControlComponent.YAngleLimit.Min) / FixMath.Abs(playerControlComponent.YAngleLimit.Max - playerControlComponent.YAngleLimit.Min)); animator.SetFloat(Head_Vertical_f, 0.5f * (float)vertical); animator.SetFloat(Body_Vertical_f, (float)vertical); viewComponent.Transforms[0].rotation = (Quaternion)((FixQuaternion)viewComponent.Transforms[0].rotation * FixQuaternion.Euler(0, rotLeftRight, 0)); playerControlComponent.Follow.localEulerAngles = (Vector3) new FixVector3(yAngle, 0, 0); } } if (characterController.isGrounded) { playerControlComponent.motion = new FixVector3((float)axisInput.Horizontal, 0, (float)axisInput.Vertical); playerControlComponent.motion = (FixVector3)viewComponent.Transforms[0].TransformDirection((Vector3)playerControlComponent.motion); Fix64 t = 0.75f; Fix64 speed = playerControlComponent.Walk; Fix64 h = FixMath.Abs(axisInput.Horizontal); Fix64 sum = h + FixMath.Abs(axisInput.Vertical); Fix64 horizontal = sum == 0 ? 0 : axisInput.Horizontal * (h / sum); if (playerControlComponent.Aim.Value == AimMode.Shoulder) { t = 0.5f; } else if (playerControlComponent.Aim.Value == AimMode.AimDownSight) { t = 0.25f; } else if (keyInput != null && keyInput.KeyCodes.Contains((int)KeyCode.LeftShift)) { t = 1f; speed = playerControlComponent.Run; } playerControlComponent.Crouched = keyInput.KeyCodes.Contains((int)KeyCode.LeftControl); animator.SetBool(Crouch_b, playerControlComponent.Crouched); if (playerControlComponent.Crouched) { speed = 0; } playerControlComponent.motion *= t * speed; animator.SetFloat(Speed_f, (axisInput.Horizontal != Fix64.Zero || axisInput.Vertical != Fix64.Zero) ? (float)FixMath.Clamp(t, 0.3f, 1f) : 0f); animator.SetFloat(Head_Horizontal_f, 0.25f * (float)horizontal); animator.SetFloat(Body_Horizontal_f, 0.35f * (float)horizontal); } if (keyInput.KeyCodes.Contains((int)KeyCode.Space) && !playerControlComponent.Crouched) { playerControlComponent.motion.y = playerControlComponent.Jump; } } playerControlComponent.motion.y -= playerControlComponent.Gravity * deltaTime; playerControlComponent.smoothTime = smoothTime; characterController.Move((Vector3)(playerControlComponent.motion * deltaTime)); animator.SetBool(Jump_b, playerControlComponent.motion.y > 0); animator.SetBool(Grounded, characterController.isGrounded && playerControlComponent.motion.y <= 0); return(new IUserInputResult[] { playerControlResult }); }).AddTo(this.Disposer); }
// Returns the angle in degrees between /from/ and /to/. This is always the smallest public static Fix64 Angle(FixVector3 from, FixVector3 to) { return(FixMath.Acos(FixMath.Clamp(Dot(from.Normalized, to.Normalized), -Fix64.ONE, Fix64.ONE)) * FixMath.Rad2Deg); }