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; }
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; }