Beispiel #1
0
        internal Rayd CastFromCamera(GraphicsDevice graphicsDevice, Vector2 mouseVector)
        {
            Matrixd worldd      = Matrixd.CreateRotationZ(-cameraRotX) * Matrixd.CreateRotationX(cameraRotY);
            double  distance    = 9 * Math.Pow(0.5, cameraZoom);
            Matrixd viewd       = CameraMatrixManager.GetWorldViewd(distance);
            Matrixd projectiond = CameraMatrixManager.GetWorldProjectiond(distance, graphicsDevice.Viewport.AspectRatio);

            return(Rayd.CastFromCamera(graphicsDevice, mouseVector.X, mouseVector.Y, projectiond, viewd, worldd));
        }
Beispiel #2
0
        // yup, it returns lat/long only in the range you'd expect
        internal Vector3d GetLatLongOfCoord(GraphicsDevice graphicsDevice, double x, double y)
        {
            Matrixd worldd      = Matrixd.CreateRotationZ(-cameraRotX) * Matrixd.CreateRotationX(cameraRotY);
            double  distance    = 9 * Math.Pow(0.5, cameraZoom);
            Matrixd viewd       = CameraMatrixManager.GetWorldViewd(distance);
            Matrixd projectiond = CameraMatrixManager.GetWorldProjectiond(distance, graphicsDevice.Viewport.AspectRatio);

            Rayd     ray          = Rayd.CastFromCamera(graphicsDevice, x, y, projectiond, viewd, worldd);
            Vector3d intersection = ray.IntersectionSphere(new Vector3d(0, 0, 0), 1); // angle 0

            if (intersection == null)
            {
                return(null);
            }
            return(ToLatLong(intersection));
        }
Beispiel #3
0
        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);
        }
        private void Draw3D(GraphicsDevice graphicsDevice, SectorBounds bounds, ISector rootSector, RenderContext.LayerPass layerPass)
        {
            double         relativeCameraZoom = camera.cameraZoom - Math.Log(ZCoords.GetSectorManager().GetTopmostOSMSectors().Count, 4) + (Game1.RECORDING ? 1 : 0);
            int            zoomLevel          = Math.Min(Math.Max((int)(relativeCameraZoom - 3), 0), ZCoords.GetSectorManager().GetHighestOSMZoom());
            List <ISector> containedSectors   = rootSector.GetSectorsInRange(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY, zoomLevel);
            List <ISector> sorted             = containedSectors.Where(x => x.GetRoot().Equals(rootSector)).ToList();

            sorted.Sort((x, y) => x.Zoom.CompareTo(y.Zoom));
            foreach (var sector in sorted)
            {
                IGraphicsBuffer buffer = loadedMaps[sector];
                if (buffer is ImageTileBuffer)
                {
                    continue;
                }
                SectorBounds b           = new SectorBounds(bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.minY * (1 << sector.Zoom) - sector.Y, bounds.maxY * (1 << sector.Zoom) - sector.Y);
                SectorBounds limitedB    = new SectorBounds(Math.Max(0, Math.Min(1, b.minX)), Math.Max(0, Math.Min(1, b.maxX)), Math.Max(0, Math.Min(1, b.minY)), Math.Max(0, Math.Min(1, b.maxY)));
                BasicEffect  basicEffect = new BasicEffect(graphicsDevice);
                camera.ApplyMatrices(basicEffect);
                // going to make it easy and assume the shape is perfectly parallel (it's not)
                // the sector plane is constructed by flattening the visible portion of the sphere, basically
                Vector3d v1    = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.minX, limitedB.minY));
                Vector3d v2    = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.maxX, limitedB.minY));
                Vector3d v3    = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.minX, limitedB.maxY));
                Vector3d xAxis = (v2 - v1) / (limitedB.maxX - limitedB.minX);
                Vector3d yAxis = (v3 - v1) / (limitedB.maxY - limitedB.minY);
                Vector3d start = v1 - xAxis * limitedB.minX - yAxis * limitedB.minY;
                Vector3d zAxis = start * (xAxis.Length() + yAxis.Length()) / start.Length() / 2;                                          // make this roughly the same length
                // matrixes copied over
                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);
                Matrixd       view            = CameraMatrixManager.GetWorldViewd(distance);
                Matrixd       projection      = CameraMatrixManager.GetWorldProjectiond(distance, graphicsDevice.Viewport.AspectRatio);
                Matrixd       transformMatrix = new Matrixd(xAxis.X, xAxis.Y, xAxis.Z, 0, yAxis.X, yAxis.Y, yAxis.Z, 0, zAxis.X, zAxis.Y, zAxis.Z, 0, start.X, start.Y, start.Z, 1); // turns our local coordinates into 3d spherical coordinates, based on the sector
                Matrixd       WVP             = Normalize(transformMatrix * world * view * projection);                                                                              // combine them all to allow for higher precision
                RenderContext context         = new RenderContext(graphicsDevice, WVP, b.minX, b.maxX, b.minY, b.maxY, camera.cameraZoom, layerPass);
                buffer.Draw(context);
            }
        }