protected void StopCameraMovement() { var cameraMovement = CameraMover.StaticHorizontalMovement - PreviousCameraMovement; cameraMovement.X = FloatHelpers.FloatsEqual(cameraMovement.X, 0) ? 0 : cameraMovement.X; cameraMovement.Y = FloatHelpers.FloatsEqual(cameraMovement.Y, 0) ? 0 : cameraMovement.Y; CameraMover.SetStaticHorizontalMovement(cameraMovement); PreviousCameraMovement = Vector2.Zero; }
/// <summary> /// Gets a point pointed at by touch or cursor (represented as normalized screen coords <paramref name="normalizedScreenPos"/>) /// in the vertical plane perpendicular to camera direction in the XZ plane placed at the <paramref name="point"/>. /// In other words, we place a plane on the <paramref name="point"/>, rotate it so it is perpendicular to the XZ plane /// and to the direction of the camera projected into the XZ plane, and then we get a point in this plane under the cursor /// from users perspective and the coordinates of this point in the game world. /// </summary> /// <param name="point">World point in the desired plane</param> /// <param name="normalizedScreenPos">Normalized screen position of the input</param> /// <returns>Point in the desired plane pointed at by the input</returns> public Vector3 GetPointUnderInput(Vector3 point, Vector2 normalizedScreenPos) { Plane plane = new Plane(Camera.Node.Direction.XZ(), point); var cameraRay = Camera.GetScreenRay(normalizedScreenPos.X, normalizedScreenPos.Y); var hitDist = cameraRay.HitDistance(plane); var result = cameraRay.Origin + cameraRay.Direction * hitDist; Debug.Assert(FloatHelpers.FloatsEqual(result.X, point.X) && FloatHelpers.FloatsEqual(result.Z, point.Z)); return(result); }
/// <summary> /// Stops the camera rotation down. /// </summary> /// <param name="args">The key up event data.</param> void StopCameraRotationDown(KeyUpEventArgs args) { if (!activeCameraMovement.RotateDown) { return; } activeCameraMovement.RotateDown = false; var pitch = camera.StaticPitch + CameraRotationSensitivity; if (FloatHelpers.FloatsEqual(pitch, 0)) { pitch = 0; } camera.SetStaticPitchChange(pitch); }
/// <summary> /// Stops the camera rotation to the left, /// </summary> /// <param name="args">The key up event data.</param> void StopCameraRotationLeft(KeyUpEventArgs args) { if (!activeCameraMovement.RotateLeft) { return; } activeCameraMovement.RotateLeft = false; var yaw = camera.StaticYaw + CameraRotationSensitivity; if (FloatHelpers.FloatsEqual(yaw, 0)) { yaw = 0; } camera.SetStaticYawChange(yaw); }
/// <summary> /// Handles scene update, moves the camera based on the set movement, rotation and zoom, calculates /// the movement decay for decaying movement. /// </summary> /// <param name="timeStep">The time elapsed since the last update.</param> protected override void OnUpdate(float timeStep) { if (IsDeleted || !EnabledEffective) { return; } //NOTE: Probably isn't needed, had a problem with 0 timeStep ticks if (timeStep <= 0) { return; } state.PreChangesUpdate(); if (staticMovement.LengthSquared > NearZero || decayingMovement.LengthSquared > NearZero) { state.MoveBy((staticMovement + decayingMovement) * timeStep); } if (staticRotation.LengthSquared > NearZero || decayingRotation.LengthSquared > NearZero) { state.Rotate((staticRotation + decayingRotation) * timeStep); } if (!FloatHelpers.FloatsEqual(staticZoom, 0, NearZero) || !FloatHelpers.FloatsEqual(decayingZoom, 0, NearZero)) { state.Zoom((staticZoom + decayingZoom) * timeStep); } if (SmoothMovement) { decayingMovement /= (1 + Drag * timeStep); decayingRotation /= (1 + Drag * timeStep); decayingZoom /= (1 + Drag * timeStep); } else { decayingMovement = Vector3.Zero; decayingRotation = Vector2.Zero; decayingZoom = 0; } state.PostChangesUpdate(); }
/// <summary> /// Stops the camera movement backwards. /// </summary> /// <param name="args">The key up event data.</param> void StopCameraMoveBackward(KeyUpEventArgs args) { //If the camera movement was stoped by other means, dont stop it again if (!activeCameraMovement.MoveBackward) { return; } activeCameraMovement.MoveBackward = false; var movement = camera.StaticMovement; movement.Z += CameraScrollSensitivity; if (FloatHelpers.FloatsEqual(movement.Z, 0)) { movement.Z = 0; } camera.SetStaticMovement(movement); }
/// <summary> /// Invoked when the mouse cursor leaves an area near the game window border. /// </summary> /// <param name="border">The border area the cursor left.</param> void OnScreenBorderLeft(ScreenBorder border) { if (!MouseBorderCameraMovement) { return; } Vector2 horizontalMovement = camera.StaticHorizontalMovement; switch (border) { case ScreenBorder.Top: if (!activeCameraMovement.BorderMovementUp) { return; } activeCameraMovement.BorderMovementUp = false; horizontalMovement.Y -= CameraScrollSensitivity; if (FloatHelpers.FloatsEqual(horizontalMovement.Y, 0)) { horizontalMovement.Y = 0; } break; case ScreenBorder.Bottom: if (!activeCameraMovement.BorderMovementDown) { return; } activeCameraMovement.BorderMovementDown = false; horizontalMovement.Y += CameraScrollSensitivity; if (FloatHelpers.FloatsEqual(horizontalMovement.Y, 0)) { horizontalMovement.Y = 0; } break; case ScreenBorder.Left: if (!activeCameraMovement.BorderMovementLeft) { return; } activeCameraMovement.BorderMovementLeft = false; horizontalMovement.X += CameraScrollSensitivity; if (FloatHelpers.FloatsEqual(horizontalMovement.X, 0)) { horizontalMovement.X = 0; } break; case ScreenBorder.Right: if (!activeCameraMovement.BorderMovementRight) { return; } activeCameraMovement.BorderMovementRight = false; horizontalMovement.X -= CameraScrollSensitivity; if (FloatHelpers.FloatsEqual(horizontalMovement.X, 0)) { horizontalMovement.X = 0; } break; default: throw new ArgumentOutOfRangeException(nameof(border), border, null); } camera.SetStaticHorizontalMovement(horizontalMovement); }