/// <summary> /// Calculates a LineSegment from the camera's position to the /// 3D position of the cursor, as if it were on the camera's farplane. /// </summary> public void CalculateCursorLineSegment(out LineSegment segment) { segment.start = Vector3.Zero; segment.end = Vector3.Zero; if (null == this.renderCamera) { return; } // Get position from Input Interface InputInterface input = this.game.SceneManager.GetInterface(InterfaceType.Input) as InputInterface; if (null == input) { throw new Exception("Input interface was not initialized before call to CalculateCursorRay()"); } CursorInfo info = input.GetCursorInfo(); if (!info.IsVisible) { // Cursor is not visible, so we just bail return; } // create 2 positions in screenspace using the cursor position. 0 is as // close as possible to the camera, 1 is as far away as possible. Vector3 nearSource = new Vector3(info.Position, 0f); Vector3 farSource = new Vector3(info.Position, 1f); MsgGetViewport msgGetPort = ObjectPool.Aquire <MsgGetViewport>(); this.game.SendInterfaceMessage(msgGetPort, InterfaceType.Graphics); MsgGetProjectionMatrix msgGetProj = ObjectPool.Aquire <MsgGetProjectionMatrix>(); msgGetProj.UniqueTarget = renderCamera.UniqueID; this.game.SendMessage(msgGetProj); MsgGetViewMatrix msgGetView = ObjectPool.Aquire <MsgGetViewMatrix>(); msgGetView.UniqueTarget = renderCamera.UniqueID; this.game.SendMessage(msgGetView); Viewport vPort = msgGetPort.Data; Matrix projMat = msgGetProj.Data; Matrix viewMat = msgGetView.Data; // use Viewport.Unproject to tell what those two screen space positions // would be in world space. we'll need the projection matrix and view // matrix, which we have saved as member variables. We also need a world // matrix, which can just be identity. segment.start = vPort.Unproject(nearSource, projMat, viewMat, Matrix.Identity); segment.end = vPort.Unproject(farSource, projMat, viewMat, Matrix.Identity); }
/// <summary> /// Handles a message sent to this component. /// </summary> /// <param name="message">Message to be handled</param> /// <returns>True, if handled, otherwise false</returns> /// <exception cref="ArgumentException">Thrown if a <see cref="MessageType"/> is not handled properly."/></exception> public override bool ExecuteMessage(IMessage message) { switch (message.Type) { case MessageType.CameraZoomIn: { MsgCameraZoomIn zoomMsg = message as MsgCameraZoomIn; message.TypeCheck(zoomMsg); ZoomPerspectiveIn(); } return(true); case MessageType.CameraZoomOut: { MsgCameraZoomOut zoomMsg = message as MsgCameraZoomOut; message.TypeCheck(zoomMsg); ZoomPerspectiveOut(); } return(true); case MessageType.GetCameraValues: { MsgCameraGetValues msgCamValues = message as MsgCameraGetValues; message.TypeCheck(msgCamValues); msgCamValues.AspectRatio = this.aspectRatio; msgCamValues.FOV = this.fov; msgCamValues.NearPlane = this.nearPlane; msgCamValues.FarPlane = this.farPlane; msgCamValues.ViewMatrix = this.viewMatrix; } return(true); case MessageType.CameraGetViewMatrix: { MsgGetViewMatrix getViewMsg = message as MsgGetViewMatrix; message.TypeCheck(getViewMsg); getViewMsg.ViewMatrix = this.viewMatrix; } return(true); case MessageType.CameraGetProjectionMatrix: { MsgGetProjectionMatrix getProjMsg = message as MsgGetProjectionMatrix; message.TypeCheck(getProjMsg); getProjMsg.ProjectionMatrix = this.projectionMatrix; } return(true); case MessageType.GraphicsSettingsChanged: { if (this.lockAspectRatioToViewport) { this.aspectRatio = this.parentEntity.Game.GraphicsDevice.Viewport.AspectRatio; if (this.aspectRatio < float.Epsilon) { throw new ArgumentOutOfRangeException("aspectRatio cannot be zero or a negative value"); } this.UpdateProjectionMatrix(); } } return(true); default: return(false); } }