Exemple #1
0
 public void UpdateTerrainElevation(TerrainAccessor terrainAccessor)
 {
     // Update camera terrain elevation
     if (terrainAccessor != null)
     {
         if (Altitude < 300000)
         {
             if (System.DateTime.Now - this.lastElevationUpdate > TimeSpan.FromMilliseconds(500))
             {
                 float elevation;
                 // Under camera target
                 elevation        = terrainAccessor.GetCachedElevationAt(Latitude.Degrees, Longitude.Degrees);
                 TerrainElevation = float.IsNaN(elevation) ? (short)0 : (short)elevation;
                 // Under the camera itself
                 Vector3 cameraPos   = Position;
                 Vector3 cameraCoord = MathEngine.CartesianToSpherical(cameraPos.X, cameraPos.Y, cameraPos.Z);
                 double  camLat      = MathEngine.RadiansToDegrees(cameraCoord.Y);
                 double  camLon      = MathEngine.RadiansToDegrees(cameraCoord.Z);
                 elevation = terrainAccessor.GetCachedElevationAt(camLat, camLon);
                 TerrainElevationUnderCamera = float.IsNaN(elevation) ? (short)0 : (short)elevation;
                 if (TerrainElevationUnderCamera < 0 && !World.Settings.AllowNegativeAltitude)
                 {
                     TerrainElevationUnderCamera = 0;
                 }
                 // reset timer
                 this.lastElevationUpdate = System.DateTime.Now;
             }
         }
         else
         {
             TerrainElevation            = 0;
             TerrainElevationUnderCamera = 0;
         }
     }
     else
     {
         TerrainElevation            = 0;
         TerrainElevationUnderCamera = 0;
     }
 }
        /// <summary>
        /// This is where we do our rendering
        /// Called from UI thread = UI code safe in this function
        /// </summary>
        public override void Render(DrawArgs drawArgs)
        {
            if (!isInitialized || (this.world.Name == "Earth" && World.Settings.EnableAtmosphericScattering))
            {
                return;
            }

            // Camera & Device shortcuts ;)
            CameraBase camera = drawArgs.WorldCamera;
            Device     device = drawArgs.device;

            //if(camera.Altitude > 200e3) return;

            Vector3 cameraPos            = camera.Position;
            double  distToCenterOfPlanet = (camera.Altitude + camera.WorldRadius);

            // Create or refresh SkyGradient dome
            if (mesh == null || lastAltitude != camera.Altitude)
            {
                // Compute distance to horizon and dome radius
                double tangentalDistance = Math.Sqrt(distToCenterOfPlanet * distToCenterOfPlanet - camera.WorldRadius * camera.WorldRadius);
                double domeRadius        = tangentalDistance;

                // horizon latitude
                double horizonLat = (-Math.PI / 2 + Math.Acos(tangentalDistance / distToCenterOfPlanet)) * 180 / Math.PI;

                // zenith latitude
                double zenithLat = 90;
                if (camera.Altitude >= thickness)
                {
                    double tangentalDistanceZenith = Math.Sqrt(distToCenterOfPlanet * distToCenterOfPlanet - (camera.WorldRadius + thickness) * (camera.WorldRadius + thickness));
                    zenithLat = (-Math.PI / 2 + Math.Acos(tangentalDistanceZenith / distToCenterOfPlanet)) * 180 / Math.PI;
                }
                if (camera.Altitude < thickness && camera.Altitude > thickness * 0.8)
                {
                    zenithLat = (thickness - camera.Altitude) / (thickness - thickness * 0.8) * 90;
                }
                // new mesh
                if (mesh != null)
                {
                    mesh.Dispose();
                }
                mesh         = ColoredSphere(device, (float)domeRadius, horizonLat, zenithLat, 128, 24);
                lastAltitude = camera.Altitude;
            }

            // set texture to null
            device.SetTexture(0, null);
            device.TextureState[0].ColorOperation = TextureOperation.BlendCurrentAlpha;
            device.VertexFormat = CustomVertex.PositionColored.Format;

            // save world and projection transform
            Matrix origWorld      = device.Transform.World;
            Matrix origProjection = device.Transform.Projection;

            // move SkyGradient dome
            Matrix  SkyGradientTrans;
            Vector3 cameraCoord = MathEngine.CartesianToSpherical(cameraPos.X, cameraPos.Y, cameraPos.Z);
            float   camLat      = cameraCoord.Y;
            float   camLon      = cameraCoord.Z;

            SkyGradientTrans = Matrix.Translation(0, 0, (float)distToCenterOfPlanet);
            SkyGradientTrans = Matrix.Multiply(SkyGradientTrans, Matrix.RotationY(-camLat + (float)Math.PI / 2));
            SkyGradientTrans = Matrix.Multiply(SkyGradientTrans, Matrix.RotationZ(camLon));

            device.Transform.World = SkyGradientTrans;

            // Recenter
            Recenter(drawArgs);

            // Save fog status
            bool origFog = device.RenderState.FogEnable;

            device.RenderState.FogEnable = false;

            // Set new one (to avoid being clipped) - probably better ways of doing this?
            float aspectRatio = (float)device.Viewport.Width / device.Viewport.Height;

            device.Transform.Projection = Matrix.PerspectiveFovRH((float)camera.Fov.Radians, aspectRatio, 1, float.MaxValue);

            // draw
            //device.RenderState.FillMode = FillMode.WireFrame;
            mesh.DrawSubset(0);

            // Restore device states
            device.RenderState.FillMode      = FillMode.Solid;
            device.Transform.World           = origWorld;
            device.Transform.Projection      = origProjection;
            device.RenderState.FogEnable     = origFog;
            device.RenderState.ZBufferEnable = true;

            // Fog effect
            if (useFog)
            {
                // Compute distance to horizon and camera altitude
                double tangentalDistance = Math.Sqrt(distToCenterOfPlanet * distToCenterOfPlanet - camera.WorldRadius * camera.WorldRadius);
                float  a = (float)camera.Altitude;
                device.RenderState.FogEnable    = true;
                device.RenderState.FogColor     = horizonColor;
                device.RenderState.FogTableMode = FogMode.Linear;
                device.RenderState.FogStart     = a * nearFactor;
                device.RenderState.FogEnd       = (float)tangentalDistance * farFactor;
            }
        }