public override bool IsTileInFrustum(PlaneD[] frustum)
 {
     return true;
 }
        private static bool IsSphereInFrustum(Vector3d sphereCenter, double sphereRadius, PlaneD[] frustum)
        {
            Vector4d center4 = new Vector4d(sphereCenter.X, sphereCenter.Y, sphereCenter.Z, 1.0);

            for (int i = 0; i < 6; i++)
            {
                if (frustum[i].Dot(center4) < -sphereRadius)
                {
                    return false;
                }
            }

            return true;
        }
        public static void ComputeFrustum(Matrix3d projection, PlaneD[] frustum)
        {
            // Left plane
            frustum[0].A = projection.M14 + projection.M11;
            frustum[0].B = projection.M24 + projection.M21;
            frustum[0].C = projection.M34 + projection.M31;
            frustum[0].D = projection.M44 + projection.M41;

            // Right plane
            frustum[1].A = projection.M14 - projection.M11;
            frustum[1].B = projection.M24 - projection.M21;
            frustum[1].C = projection.M34 - projection.M31;
            frustum[1].D = projection.M44 - projection.M41;

            // Top plane
            frustum[2].A = projection.M14 - projection.M12;
            frustum[2].B = projection.M24 - projection.M22;
            frustum[2].C = projection.M34 - projection.M32;
            frustum[2].D = projection.M44 - projection.M42;

            // Bottom plane
            frustum[3].A = projection.M14 + projection.M12;
            frustum[3].B = projection.M24 + projection.M22;
            frustum[3].C = projection.M34 + projection.M32;
            frustum[3].D = projection.M44 + projection.M42;

            // Near plane
            frustum[4].A = projection.M13;
            frustum[4].B = projection.M23;
            frustum[4].C = projection.M33;
            frustum[4].D = projection.M43;

            // Far plane
            frustum[5].A = projection.M14 - projection.M13;
            frustum[5].B = projection.M24 - projection.M23;
            frustum[5].C = projection.M34 - projection.M33;
            frustum[5].D = projection.M44 - projection.M43;

            // Normalize planes
            for (int i = 0; i < 6; i++)
            {
                frustum[i].Normalize();
            }
        }
        internal static void Draw(RenderContext11 renderContext, float opacity, bool astronomical, string referenceFrame, bool nested, bool flatSky)
        {
            if (!AllMaps.ContainsKey(referenceFrame))
            {
                return;
            }

            LayerMap thisMap = AllMaps[referenceFrame];

            if (!thisMap.Enabled || (thisMap.ChildMaps.Count == 0 && thisMap.Layers.Count == 0 && !(thisMap.Frame.ShowAsPoint || thisMap.Frame.ShowOrbitPath)))
            {
                return;
            }

            //PrepTourLayers();

            Matrix3d matOld = renderContext.World;
            Matrix3d matOldNonRotating = renderContext.WorldBaseNonRotating;
            double oldNominalRadius = renderContext.NominalRadius;
            if (thisMap.Frame.Reference == ReferenceFrames.Custom | thisMap.Frame.Reference == ReferenceFrames.Sandbox)
            {
                thisMap.ComputeFrame(renderContext);
                if (thisMap.Frame.useRotatingParentFrame())
                {
                    renderContext.World = thisMap.Frame.WorldMatrix * renderContext.World;
                }
                else
                {
                    renderContext.World = thisMap.Frame.WorldMatrix * renderContext.WorldBaseNonRotating;

                }
                if (thisMap.Frame.ReferenceFrameType == ReferenceFrameTypes.Synodic)
                {
                    renderContext.WorldBaseNonRotating = renderContext.World;
                }

                renderContext.NominalRadius = thisMap.Frame.MeanRadius;
            }

            if (thisMap.Frame.ShowAsPoint)
            {
                Planets.DrawPointPlanet(renderContext, new Vector3d(0, 0, 0), (float).2, thisMap.Frame.RepresentativeColor, true, opacity);
            }

            PlaneD[] viewFrustum = new PlaneD[6];
            RenderContext11.ComputeFrustum(renderContext.Projection, viewFrustum);

            for (int pass = 0; pass < 2; pass++)
            {
                foreach (Layer layer in AllMaps[referenceFrame].Layers)
                {
                    if ((pass == 0 && layer is ImageSetLayer) || (pass == 1 && !(layer is ImageSetLayer)))
                    {
                        bool skipLayer = false;
                        if (pass == 0)
                        {
                            // Skip default image set layer so that it's not drawn twice
                            skipLayer = !astronomical && ((ImageSetLayer)layer).OverrideDefaultLayer;
                        }

                        if (layer.Enabled && !skipLayer) // && astronomical == layer.Astronomical)
                        {
                            double layerStart = SpaceTimeController.UtcToJulian(layer.StartTime);
                            double layerEnd = SpaceTimeController.UtcToJulian(layer.EndTime);
                            double fadeIn = SpaceTimeController.UtcToJulian(layer.StartTime) - ((layer.FadeType == FadeType.In || layer.FadeType == FadeType.Both) ? layer.FadeSpan.TotalDays : 0);
                            double fadeOut = SpaceTimeController.UtcToJulian(layer.EndTime) + ((layer.FadeType == FadeType.Out || layer.FadeType == FadeType.Both) ? layer.FadeSpan.TotalDays : 0);

                            if (SpaceTimeController.JNow > fadeIn && SpaceTimeController.JNow < fadeOut)
                            {
                                float fadeOpacity = 1;
                                if (SpaceTimeController.JNow < layerStart)
                                {
                                    fadeOpacity = (float)((SpaceTimeController.JNow - fadeIn) / layer.FadeSpan.TotalDays);
                                }

                                if (SpaceTimeController.JNow > layerEnd)
                                {
                                    fadeOpacity = (float)((fadeOut - SpaceTimeController.JNow) / layer.FadeSpan.TotalDays);
                                }
                                layer.Astronomical = astronomical;

                                layer.Draw(renderContext, opacity * fadeOpacity, flatSky);
                            }
                        }
                    }
                }
            }
            if (nested)
            {
                foreach (LayerMap map in AllMaps[referenceFrame].ChildMaps.Values)
                {
                    if (map.Enabled && map.Frame.ShowOrbitPath && Properties.Settings.Default.SolarSystemMinorOrbits.State)
                    {
                        if (map.Frame.ReferenceFrameType == ReferenceFrameTypes.Orbital)
                        {
                            if (map.Frame.Orbit == null)
                            {
                                map.Frame.Orbit = new Orbit(map.Frame.Elements, 360, map.Frame.RepresentativeColor, 1,/* referenceFrame == "Sun" ? (float)(UiTools.KilometersPerAu*1000.0):*/ (float)renderContext.NominalRadius);
                            }

                            double dd = renderContext.NominalRadius;

                            double distss = UiTools.SolarSystemToMeters(Earth3d.MainWindow.SolarSystemCameraDistance);

                            Matrix3d matSaved = renderContext.World;
                            renderContext.World = thisMap.Frame.WorldMatrix * renderContext.WorldBaseNonRotating;

                            // orbitCenter is a position in camera space
                            Vector3d orbitCenter = Vector3d.TransformCoordinate(new Vector3d(0, 0, 0), Matrix3d.Multiply(renderContext.World, renderContext.View));
                            double worldScale = Math.Sqrt(renderContext.World.M11 * renderContext.World.M11 + renderContext.World.M12 * renderContext.World.M12 + renderContext.World.M13 * renderContext.World.M13) * UiTools.KilometersPerAu;

                            double orbitRadius = map.Frame.Orbit.BoundingRadius / UiTools.KilometersPerAu * worldScale;
                            bool cull = !IsSphereInFrustum(orbitCenter, orbitRadius, viewFrustum);

                            float fade = (float)Math.Min(1, Math.Max(Math.Log(UiTools.SolarSystemToMeters(Earth3d.MainWindow.SolarSystemCameraDistance), 10) - 7.3, 0));
                            if (Earth3d.MainWindow.TrackingFrame == map.Frame.Name)
                            {
                                double ratio = map.Frame.MeanRadius / distss;

                                double val = Math.Log(ratio, 10) + 2.7;
                                fade = (float)Math.Min(1, Math.Max(-val, 0));

                            }

                            fade *= Properties.Settings.Default.SolarSystemMinorOrbits.Opacity;
                            if ( fade > 0)
                            {

                                map.Frame.Orbit.Draw3D(renderContext, fade, new Vector3d(0, 0, 0));
                                renderContext.World = matSaved;
                            }
                        }
                        else if (map.Frame.ReferenceFrameType == ReferenceFrameTypes.Trajectory)
                        {
                            if (map.Frame.trajectoryLines == null)
                            {
                                map.Frame.trajectoryLines = new LineList();
                                map.Frame.trajectoryLines.ShowFarSide = true;
                                map.Frame.trajectoryLines.UseNonRotatingFrame = true;

                                int count = map.Frame.Trajectory.Count - 1;
                                for (int i = 0; i < count; i++)
                                {
                                    Vector3d pos1 = map.Frame.Trajectory[i].Position;
                                    Vector3d pos2 = map.Frame.Trajectory[i + 1].Position;
                                    pos1.Multiply(1 / renderContext.NominalRadius);
                                    pos2.Multiply(1 / renderContext.NominalRadius);
                                    map.Frame.trajectoryLines.AddLine(pos1, pos2, map.Frame.RepresentativeColor, new Dates());
                                }
                            }
                            Matrix3d matSaved = renderContext.World;
                            renderContext.World = thisMap.Frame.WorldMatrix * renderContext.WorldBaseNonRotating;
                            double distss = UiTools.SolarSystemToMeters(Earth3d.MainWindow.SolarSystemCameraDistance);

                            float fade = (float)Math.Min(1, Math.Max(Math.Log(distss, 10) - 7.3, 0));
                            if (Earth3d.MainWindow.TrackingFrame == map.Frame.Name)
                            {
                                double ratio = map.Frame.MeanRadius / distss;

                                double val = Math.Log(ratio, 10) + 2.7;
                                fade = (float)Math.Min(1, Math.Max(-val, 0));
                            }

                            map.Frame.trajectoryLines.DrawLines(renderContext, Properties.Settings.Default.SolarSystemMinorOrbits.Opacity * fade);
                            renderContext.World = matSaved;
                        }
                    }

                    if ((map.Frame.Reference == ReferenceFrames.Custom || map.Frame.Reference == ReferenceFrames.Identity))
                    {
                        Draw(renderContext, opacity, astronomical, map.Name, nested, flatSky);
                    }
                }
            }
            renderContext.NominalRadius = oldNominalRadius;
            renderContext.World = matOld;
            renderContext.WorldBaseNonRotating = matOldNonRotating;
        }
Example #5
0
        public virtual bool IsTileInFrustum(PlaneD[]frustum)
        {
            InViewFrustum = false;
            Vector3d center = sphereCenter;

            if (this.Level < 2 && (dataset.Projection == ProjectionType.Mercator || dataset.Projection == ProjectionType.Toast))
            {
                return true;
            }

            Vector4d centerV4 = new Vector4d(center.X , center.Y , center.Z , 1f);
            Vector3d length = new Vector3d(sphereRadius, 0, 0);

            double rad = length.Length();
            for (int i = 0; i < 6; i++)
            {
                if (frustum[i].Dot(centerV4) + rad < 0)
                {
                    return false;
                }
            }
            InViewFrustum = true;

            return true;
        }