public override void Draw(RenderContext renderContext, GameTime gameTime) { if (renderContext.layerPass != RenderContext.LayerPass.MAIN_PASS) { return; } if (Game1.RECORDING) { MoveShip(renderContext.graphicsDevice); } SphereVector unitPosition = new SphereVector(position.Normalized()); SphereVector up = unitPosition.WalkNorth(Math.PI / 2); SphereVector right = new SphereVector(up.Cross(unitPosition).Normalized()); double rotation = Math.Atan2(forward.Dot(-right), forward.Dot(up)); // we want up to be 0 and a positive rotation to be cw Matrixd shipWVP = CreateShipWVP(renderContext, rotation); foreach (ModelMesh mesh in GlobalContent.StartingShuttle.Meshes) { foreach (BasicEffect eff in mesh.Effects) { eff.EnableDefaultLighting(); eff.World = shipWVP.toMatrix(); eff.VertexColorEnabled = false; eff.Alpha = 1; } mesh.Draw(); } }
private Matrixd CreateShipWVP(RenderContext renderContext, double rotation) { double fakeScale = Math.Max(Math.Pow(2, 21 - camera.cameraZoom), 1); // make the ship bigger to account for depth buffer limitations Vector3d shipPos = position; // earth radius 6371 km double shipScale = fakeScale / 6371000; double distanceFromCamera = 30; // in meters Matrixd world = Matrixd.CreateRotationZ(-camera.cameraRotX) * Matrixd.CreateRotationX(camera.cameraRotY); // eh.... think hard on this later double distance = 9 * Math.Pow(0.5, camera.cameraZoom); shipPos += position.WalkNorth(-Math.PI / 4) * (distance * 2 - distanceFromCamera * shipScale); // why distance * 2?? Matrixd view = CameraMatrixManager.GetWorldViewd(distance); Matrixd projection = CameraMatrixManager.GetWorldProjectiond(distance, renderContext.graphicsDevice.Viewport.AspectRatio); Matrixd worldWVP = world * view * projection; Matrixd shipRot = Matrixd.CreateRotationZ(rotation + Math.PI) * Matrixd.CreateRotationX(Math.PI / 2 - camera.cameraRotY) * Matrixd.CreateRotationZ(camera.cameraRotX); return(shipRot * Matrixd.CreateScale(shipScale) * Matrixd.CreateTranslation(shipPos) * worldWVP); }
public double RotateWithMouse(GraphicsDevice graphicsDevice) { SphereVector unitPosition = new SphereVector(position.Normalized()); SphereVector up2 = unitPosition.WalkNorth(Math.PI / 2); SphereVector right2 = new SphereVector(up2.Cross(unitPosition).Normalized()); double screenSpaceRotation = Math.Atan2(-forward.Dot(up2), forward.Dot(right2)); // we want up to be 0 and a positive rotation to be cw Point mousePos = Mouse.GetState().Position; Vector2d mouseV = new Vector2d((mousePos.X / (double)graphicsDevice.Viewport.Width - 0.5) * graphicsDevice.Viewport.AspectRatio, mousePos.Y / (double)graphicsDevice.Viewport.Height - 0.5); double mouseRotation = Math.Atan2(mouseV.Y, mouseV.X); double diff1 = (mouseRotation + 4 * Math.PI - screenSpaceRotation) % (2 * Math.PI); double diff2 = (screenSpaceRotation + 4 * Math.PI - mouseRotation) % (2 * Math.PI); double rotationSpeed; if (diff1 < diff2) { return(diff1 / 10); } else { return(-diff2 / 10); } }