public Editor2D(Microsoft.Xna.Framework.Game game) : base(game) { // Create a simple delegate graphics screen to handle figure rendering var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService) { RenderCallback = Render, }; // TODO - make sure we don't just want to put this under the controls screen? // make sure to insert it on top? GraphicsService.Screens.Insert(0, delegateGraphicsScreen); _cameraObject = new Editor2DCameraObject(Services); GameObjectService.Objects.Add(_cameraObject); CreateGrid(); CreateGate(); // Add a game object which handles the picking: GameObjectService.Objects.Add(new FigurePickerObject(GraphicsService, Scene, _cameraObject, DebugRenderer)); var test = new GridSettingsWindow(); UIScreen.Children.Add(test); }
public FigurePickerObject(IGraphicsService graphicsService, Scene scene, Editor2DCameraObject cameraObject, DebugRenderer debugRenderer) { _cameraObject = cameraObject; _scene = scene; _debugRenderer = debugRenderer; // Create a collision domain which manages all collision objects used for // picking: the picking object and the collision objects for figure nodes. _collisionDomain = new CollisionDomain(new CollisionDetection()); // Create the picking object: // The picking object represents the mouse cursor or the reticle. Usually // a ray is used, but in this example we want to use a cylinder/cone. This // allows to check which objects within a certain radius of the reticle. A // picking cylinder/cone is helpful for touch devices where the picking is // done with an imprecise input method like the human finger. // We want to pick objects in 10 pixel radius around the reticle. To determine // the world space size of the required cylinder/cone, we can use the projection // and the viewport. const float pickingRadius = 0.25f; var projection = _cameraObject.CameraNode.Camera.Projection; var viewport = graphicsService.GraphicsDevice.Viewport; Shape pickingShape; if (projection is OrthographicProjection) { // Use cylinder for orthographic projections: // The cylinder is centered at the camera position and reaches from the // camera position to the camera far plane. A TransformedShape is used // to rotate and translate the cylinder. float radius = projection.Width / viewport.Width * pickingRadius; pickingShape = new TransformedShape( new GeometricObject( new CylinderShape(radius, projection.Far), new Pose(new Vector3F(0, 0, -projection.Far / 2), Matrix33F.CreateRotationX(ConstantsF.PiOver2)))); } else { // Use cone for perspective projections: // The cone tip is at the camera position and the cone base is at the // camera far plane. // Compute the radius at the far plane that projects to 10 pixels in screen space. float radius = viewport.Unproject( new Vector3(viewport.Width / 2.0f + pickingRadius, viewport.Height / 2.0f, 1), (Matrix)_cameraObject.CameraNode.Camera.Projection.ToMatrix44F(), Matrix.Identity, Matrix.Identity).X; // A transformed shape is used to rotate and translate the cone. pickingShape = new TransformedShape( new GeometricObject( new ConeShape(radius, projection.Far), new Pose(new Vector3F(0, 0, -projection.Far), Matrix33F.CreateRotationX(ConstantsF.PiOver2)))); } // Create collision object with the picking shape. _pickingObject = new CollisionObject(new GeometricObject(pickingShape, _cameraObject.CameraNode.PoseWorld)); }