public Point3d cross(Point3d p) { return new Point3d( Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X ); }
/// <summary> /// Test if a point is inside the frustum. /// </summary> /// <returns>true when the point is inside.</returns> /// <param name="v">XYZ in world coordinates of the point to test.</param> public bool ContainsPoint(Point3d v) { foreach(Plane2d p in this.planes) if(Point3d.dot(new Point3d(p.A, p.B, p.C), v) + p.D < 0) return false; return true; }
// Compute Sun geocentric cartesian position given actual position on the globe, // heading, elevation and sun distance internal static Point3d GetGeocentricPosition(Point3d position, Angle heading, Angle elevation, double sunDistance) { // Untransformed sun pos from globe center Point3d sun = MathEngine.SphericalToCartesian(elevation, Angle.FromRadians(Math.PI - heading.Radians), sunDistance); // Now transform it to current location Point3d pos = MathEngine.CartesianToSpherical(position.X, position.Y, position.Z); Matrix4d sunTrans = Matrix4d.Identity; sunTrans *= Matrix4d.Translation(0, 0, pos.X); // radius pos sunTrans *= Matrix4d.RotationY((float)Math.PI / 2 - pos.Y); // lat pos sunTrans *= Matrix4d.RotationZ(pos.Z); // lon pos // JBTODO: Does this do the same as in DirectX sun.TransformCoordinate(sunTrans); return new Point3d(-sun.X, -sun.Y, -sun.Z); }
/// <summary> /// Initializes a new instance of the <see cref= "T:WorldWind.World"/> class. /// </summary> /// <param name="name"></param> /// <param name="position"></param> /// <param name="orientation"></param> /// <param name="equatorialRadius"></param> /// <param name="cacheDirectory"></param> /// <param name="terrainAccessor"></param> public World(string name, Point3d position, Quaternion4d orientation, double equatorialRadius, string cacheDirectory, TerrainAccessor terrainAccessor) : base(name, position, orientation) { this.equatorialRadius = equatorialRadius; this._terrainAccessor = terrainAccessor; this._renderableObjects = new RenderableObjectList(this.Name); this.MetaData.Add("CacheDirectory", cacheDirectory); // this.m_WorldSurfaceRenderer = new WorldSurfaceRenderer(32, 0, this); this.m_projectedVectorRenderer = new ProjectedVectorRenderer("World Default ProjectedVectorRenderer", this); m_outerSphere = new AtmosphericScatteringSphere(); AtmosphericScatteringSphere.m_fInnerRadius = (float)equatorialRadius; AtmosphericScatteringSphere.m_fOuterRadius = (float)equatorialRadius * 1.025f; m_outerSphere.Init((float)equatorialRadius * 1.025f); }
/// <summary> /// Adds a point to the end of the line. /// </summary> /// <param name="x">Lon</param> /// <param name="y">Lat</param> /// <param name="z">Alt (meters)</param> public void AddPoint(double x, double y, double z) { Point3d point = new Point3d(x, y, z); //TODO:Divide into subsegments if too far if (m_numPoints > 0) { Angle startlon = Angle.FromDegrees(m_points[m_numPoints - 1].X); Angle startlat = Angle.FromDegrees(m_points[m_numPoints - 1].Y); double startalt = m_points[m_numPoints - 1].Z; Angle endlon = Angle.FromDegrees(x); Angle endlat = Angle.FromDegrees(y); double endalt = z; Angle dist = World.ApproxAngularDistance(startlat, startlon, endlat, endlon); if (dist.Degrees > 0.25) { double stepSize = 0.25; int samples = (int)(dist.Degrees / stepSize); for (int i = 0; i < samples; i++) { Angle lat, lon = Angle.Zero; float frac = (float)i / samples; World.IntermediateGCPoint(frac, startlat, startlon, endlat, endlon, dist, out lat, out lon); double alt = startalt + frac * (endalt - startalt); Point3d pointint = new Point3d(lon.Degrees, lat.Degrees, alt); AddPoint(pointint); } AddPoint(point); } else { AddPoint(point); } } else { AddPoint(point); } }
public LineFeature(string name, World parentWorld, Point3d[] points, System.Drawing.Color lineColor) : base(name, parentWorld) { m_points = points; m_lineColor = lineColor; m_polygonColor = lineColor; m_numPoints = m_points.LongLength; RenderPriority = WorldWind.Renderable.RenderPriority.LinePaths; }
internal void TransformCoordinate(Matrix4d m) { this = new Point3d(this.X * m[0, 0] + this.Y * m[1, 0] + this.Z * m[2, 0] + m[3, 0], this.X * m[0, 1] + this.Y * m[1, 1] + this.Z * m[2, 1] + m[3, 1], this.X * m[0, 2] + this.Y * m[1, 2] + this.Z * m[2, 2] + m[3, 2]); }
// normalization internal static Point3d normalize(Point3d v) { double n = v.Length; return new Point3d(v.X / n, v.Y / n, v.Z / n); }
// cross product public static Point3d cross(Point3d P1, Point3d P2) { return P1 * P2; }
public override void Load() { base.Load(); // Add our plugin to the World Wind Tools menu menuItem = new System.Windows.Forms.ToolStripMenuItem(); menuItem.Text = "3Dconnexion Input Device"; menuItem.Click += new System.EventHandler(menuItem_Click); s_stopWatch = new Stopwatch(); s_WW = m_Application.WorldWindow; s_TheCamera = s_WW.DrawArgs.WorldCamera; m_TheInputDevice = new TDconnexion.TDxDeviceWrapper(); if (m_TheInputDevice != null) { if (m_TheInputDevice.InitializationSuccessful) { // JBTODO: m_app.MenuStrip.Items.Add(menuItem); s_TheSensor = m_TheInputDevice.Sensor; s_TheKeyBoard = m_TheInputDevice.Keyboard; s_Position = new Point3d(); SetCameraMode(); m_KeyEventHandler = new TDconnexion.TDxKeyboardEvent(KeyboardEventHandler); s_TheKeyBoard.KeyboardEventDOWN += m_KeyEventHandler; m_TheInputDevice.Connect(); } else { m_TheInputDevice = null; } } }
internal static Vector4 ToVector4(Point3d v) { return new Vector4((float)v.X, (float)v.Y, (float) v.Z, 0.0f); }
internal static Vector3 ToVector3(Point3d v) { return new Vector3((float)v.X, (float)v.Y, (float)v.Z); }
public override void Initialize(DrawArgs drawArgs) { if (m_polygonFeature == null) { double offset = 0.02; Point3d[] points = new Point3d[4]; points[0] = new Point3d( m_longitude - offset, m_latitude - offset, 200000); points[1] = new Point3d( m_longitude - offset, m_latitude + offset, 200000); points[2] = new Point3d( m_longitude + offset, m_latitude + offset, 200000); points[3] = new Point3d( m_longitude + offset, m_latitude - offset, 200000); LinearRing outerRing = new LinearRing(); outerRing.Points = points; m_polygonFeature = new PolygonFeature( name, World, outerRing, null, System.Drawing.Color.Chocolate); m_polygonFeature.AltitudeMode = AltitudeMode.Absolute; m_polygonFeature.Extrude = true; m_polygonFeature.Outline = true; m_polygonFeature.OutlineColor = System.Drawing.Color.Chocolate; } FileInfo savedFlagFile = new FileInfo(SavedImagePath); FileInfo placeHolderFile = new FileInfo(SavedImagePath + ".blk"); if (savedFlagFile.Exists) { try { m_texture = ImageHelper.LoadTexture( savedFlagFile.FullName, System.Drawing.Color.Black.ToArgb()); } catch { savedFlagFile.Delete(); savedFlagFile.Refresh(); } } if (!savedFlagFile.Exists && !placeHolderFile.Exists) { if (!savedFlagFile.Directory.Exists) savedFlagFile.Directory.Create(); try { WorldWind.Net.WebDownload download = new WorldWind.Net.WebDownload(m_imageUri); download.DownloadFile(savedFlagFile.FullName); download.Dispose(); savedFlagFile.Refresh(); } catch { FileStream fs = placeHolderFile.Create(); fs.Close(); fs = null; placeHolderFile.Refresh(); } if (savedFlagFile.Exists) { m_texture = ImageHelper.LoadTexture( savedFlagFile.FullName, System.Drawing.Color.Black.ToArgb()); } } UpdateVertices(); isInitialized = true; }
private static Point3d[] GetPoints(KMLLineString oInput) { Point3d[] result = new Point3d[oInput.Count]; for (int count = 0; count < oInput.Count; count++) { result[count] = new Point3d(oInput[count].Longitude, oInput[count].Latitude, oInput[count].Altitude); } return result; }
internal virtual void ComputeViewMatrix() { // Compute camera elevation int minStep = 10; targetCameraElevation = TerrainElevation * World.Settings.VerticalExaggeration; float stepToTarget = targetCameraElevation - curCameraElevation; if (Math.Abs(stepToTarget) > minStep) { float step = 0.05f * stepToTarget; if (Math.Abs(step) < minStep) step = step > 0 ? minStep : -minStep; curCameraElevation = curCameraElevation + step; } else curCameraElevation = targetCameraElevation; // Absolute matrices ComputeAbsoluteMatrices(); // needs to be double precsion double radius = WorldRadius + curCameraElevation; double radCosLat = radius * Math.Cos(_latitude.Radians); LookFrom = new Point3d(radCosLat * Math.Cos(_longitude.Radians), radCosLat * Math.Sin(_longitude.Radians), radius * Math.Sin(_latitude.Radians)); // this constitutes a local tri-frame hovering above the sphere Point3d zAxis = LookFrom; // on sphere the normal vector and position vector are the same zAxis.normalize(); Point3d xAxis = Point3d.cross(cameraUpVector, zAxis); xAxis.normalize(); Point3d yAxis = Point3d.cross(zAxis, xAxis); ReferenceCenter = MathEngine.SphericalToCartesian( Angle.FromRadians(Convert.ToSingle(_latitude.Radians)), Angle.FromRadians(Convert.ToSingle(_longitude.Radians)), WorldRadius); // Important step !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // In order to use single precsion rendering, we need to define a local frame (i.e. center of center tile, etc.) // Vector3d LocalCenter should be defined & initialized in the CameraBase class // Each time the camera moves, a new local center could be defined // The local center also has to be subtracted from all the terrain vertices!!!! relCameraPos = LookFrom - ReferenceCenter; // Important step: construct the single precision m_ViewMatrix by hand // We can build the m_ViewMatrix by hand m_ViewMatrix[0, 0] = xAxis.X; m_ViewMatrix[1, 0] = xAxis.Y; m_ViewMatrix[2, 0] = xAxis.Z; m_ViewMatrix[0, 1] = yAxis.X; m_ViewMatrix[1, 1] = yAxis.Y; m_ViewMatrix[2, 1] = yAxis.Z; m_ViewMatrix[0, 2] = zAxis.X; m_ViewMatrix[1, 2] = zAxis.Y; m_ViewMatrix[2, 2] = zAxis.Z; m_ViewMatrix[3, 0] = -(xAxis.X * relCameraPos.X + xAxis.Y * relCameraPos.Y + xAxis.Z * relCameraPos.Z); m_ViewMatrix[3, 1] = -(yAxis.X * relCameraPos.X + yAxis.Y * relCameraPos.Y + yAxis.Z * relCameraPos.Z); m_ViewMatrix[3, 2] = -(zAxis.X * relCameraPos.X + zAxis.Y * relCameraPos.Y + zAxis.Z * relCameraPos.Z); m_ViewMatrix[0, 3] = 0.0; m_ViewMatrix[1, 3] = 0.0; m_ViewMatrix[2, 3] = 0.0; m_ViewMatrix[3, 3] = 1.0; double cameraDisplacement = _distance; //if(cameraDisplacement < targetCameraElevation + minimumAltitude) // cameraDisplacement = targetCameraElevation + minimumAltitude; m_ViewMatrix *= Matrix4d.RotationYawPitchRoll( 0, -_tilt.Radians, _heading.Radians); //m_ViewMatrix *= Matrix4d.Translation(0, 0, (-cameraDisplacement + curCameraElevation)); m_ViewMatrix *= Matrix4d.Translation(0, 0, (-cameraDisplacement)); m_ViewMatrix *= Matrix4d.RotationZ(_bank.Radians); // Extract camera position Matrix4d cam = Matrix4d.Invert(m_absoluteViewMatrix); _position = new Point3d(cam[3, 0], cam[3, 1], cam[3, 2]); }
private void finishTesselation(Point3d[] tesselatorList) { int polygonColor = System.Drawing.Color.FromArgb(m_polygonColor.A, m_polygonColor.R, m_polygonColor.G, m_polygonColor.B).ToArgb(); CustomVertex.PositionNormalColored[] vertices = new CustomVertex.PositionNormalColored[tesselatorList.Length]; for(int i = 0; i < vertices.Length; i++) { Point3d sphericalPoint = tesselatorList[i]; double terrainHeight = 0; if(m_altitudeMode == AltitudeMode.RelativeToGround) { if(World.TerrainAccessor != null) { terrainHeight = World.TerrainAccessor.GetElevationAt( sphericalPoint.Y, sphericalPoint.X, (100.0 / DrawArgs.Camera.ViewRange.Degrees) ); } } Vector3 xyzVector = MathEngine.SphericalToCartesian( sphericalPoint.Y, sphericalPoint.X, World.EquatorialRadius + m_verticalExaggeration * (m_geographicBoundingBox.MaximumAltitude + m_distanceAboveSurface + terrainHeight)); vertices[i].Color = polygonColor; vertices[i].X = xyzVector.X; vertices[i].Y = xyzVector.Y; vertices[i].Z = xyzVector.Z; } primList.Add(vertices); }
private void UpdateVertices() { m_verticalExaggeration = World.Settings.VerticalExaggeration; if(m_altitudeMode == AltitudeMode.ClampedToGround) { if(m_polygon != null) { m_polygon.Remove = true; m_polygon = null; } m_polygon = new Polygon(); m_polygon.outerBoundary = m_outerRing; m_polygon.innerBoundaries = m_innerRings; m_polygon.PolgonColor = m_polygonColor; m_polygon.Fill = m_fill; m_polygon.ParentRenderable = this; this.World.ProjectedVectorRenderer.Add(m_polygon); if(m_vertices != null) m_vertices = null; if(m_lineFeature != null) { m_lineFeature[0].Dispose(); m_lineFeature = null; } return; } getTessellation(); if(m_extrude || m_outline) { m_lineFeature = new LineFeature[1 + (m_innerRings != null && m_innerRings.Length > 0 ? m_innerRings.Length : 0)]; Point3d[] linePoints = new Point3d[m_outerRing.Points.Length + 1]; for(int i = 0; i < m_outerRing.Points.Length; i++) { linePoints[i] = m_outerRing.Points[i]; } linePoints[linePoints.Length - 1] = m_outerRing.Points[0]; m_lineFeature[0] = new LineFeature(Name, World, linePoints, m_polygonColor); m_lineFeature[0].DistanceAboveSurface = m_distanceAboveSurface; m_lineFeature[0].MinimumDisplayAltitude = m_minimumDisplayAltitude; m_lineFeature[0].MaximumDisplayAltitude = m_maximumDisplayAltitude; m_lineFeature[0].AltitudeMode = AltitudeMode; m_lineFeature[0].Opacity = Opacity; m_lineFeature[0].Outline = m_outline; m_lineFeature[0].LineColor = m_outlineColor; m_lineFeature[0].Extrude = m_extrude; if(m_innerRings != null && m_innerRings.Length > 0) { for(int i = 0; i < m_innerRings.Length; i++) { Point3d[] innerPoints = new Point3d[m_innerRings[i].Points.Length + 1]; for(int j = 0; j < m_innerRings[i].Points.Length; j++) { innerPoints[j] = m_innerRings[i].Points[j]; } innerPoints[innerPoints.Length - 1] = m_innerRings[i].Points[0]; m_lineFeature[1 + i] = new LineFeature(Name, World, innerPoints, m_polygonColor); m_lineFeature[1 + i].DistanceAboveSurface = m_distanceAboveSurface; m_lineFeature[1 + i].MinimumDisplayAltitude = m_minimumDisplayAltitude; m_lineFeature[1 + i].MaximumDisplayAltitude = m_maximumDisplayAltitude; m_lineFeature[1 + i].AltitudeMode = AltitudeMode; m_lineFeature[1 + i].Opacity = Opacity; m_lineFeature[1 + i].Outline = m_outline; m_lineFeature[1 + i].LineColor = m_outlineColor; m_lineFeature[1 + i].Extrude = m_extrude; } } } else { if(m_lineFeature != null && m_lineFeature.Length > 0) { for(int i = 0; i < m_lineFeature.Length; i++) { if(m_lineFeature[i] != null) { m_lineFeature[i].Dispose(); m_lineFeature[i] = null; } } m_lineFeature = null; } } }
/// <summary> /// used as delegate for the "Camera Mode" -axis mapping, moving the Camera/Yourself /// </summary> private static void CameraMode() { long delta = 1; if (s_stopWatch.IsRunning) { delta = s_stopWatch.ElapsedMilliseconds; //ToDo: remove just a performance improvement for 3DxWare Version < 6.1.8 if (delta < s_TheSensor.Period) return; s_stopWatch.Stop(); if (delta > (10 * s_TheSensor.Period)) return; //Console.WriteLine(delta.ToString()); //Debug.Print(delta.ToString()); } //get data from the Input Device TDconnexion.C3DxVector TranslVector = s_TheSensor.Translation as TDconnexion.C3DxVector; TDconnexion.C3DxRotation AngleAxis = s_TheSensor.Rotation as TDconnexion.C3DxRotation; double dNormTime = (double)delta / s_TheSensor.Period; TranslVector *= dNormTime; AngleAxis *= dNormTime; //0- event sent when cap released if ((AngleAxis.Angle == 0) && (TranslVector.X == 0) && (TranslVector.Y == 0) && (TranslVector.Z == 0) ) { s_dLastHeight = s_TheCamera.Altitude; s_dDeltaHeight = 0; s_stopWatch.Stop(); return; } s_TheCamera = s_WW.DrawArgs.WorldCamera; //set CameraSmooth to false to disable movement after releasing the cap bool bBackUpSmooth = World.Settings.CameraSmooth; World.Settings.CameraSmooth = false; //variables to move the earth via Quaternion4d double dRadius = s_TheCamera.WorldRadius; double dAltitude = s_TheCamera.Altitude; //height above sealevel of the camera Angle rTilt = s_TheCamera.Tilt; //angle between line [center of earth ... crosshairs] and line [crosshairs ... camera] double dDeltaLatitude = 0; //change of Latitude double dDeltaLongitude = 0; //change of Longitude double dSinus = Math.Sin(rTilt.Radians); double dLength = dAltitude + dRadius; //distance earth center - camera double dSinusLaw = dSinus / dLength; //const of law of sines double dAlpha = rTilt.Radians - Math.Asin(dRadius * dSinusLaw); //angle between crosshairs and intersection of line [camera ... center of earth] and earth- face ////////////////////////////////////////////////////////////////////////////// /// Tilt, camera position == center of rotation -> adjust latitude/distance/// ////////////////////////////////////////////////////////////////////////////// double dDeltaTiltRad = AngleAxis.X * AngleAxis.Angle * WorldSettings.CameraRotationSpeed / NormTilt; //150000.0; if (Math.Abs(dDeltaTiltRad) > double.Epsilon) { rTilt += Angle.FromRadians(dDeltaTiltRad); if (rTilt.Degrees > 85.0) rTilt.Degrees = 85.0; if (Math.Abs(rTilt.Radians) > double.Epsilon) { dSinus = Math.Sin(rTilt.Radians); dSinusLaw = dSinus / dLength; dDeltaLatitude = -dAlpha; dAlpha = rTilt.Radians - Math.Asin(dRadius * dSinusLaw); // == dAlpha after Tilt dDeltaLatitude += dAlpha; } } /////////////////////////////////////////////////////////////////////////////////////// /// Camera height: change Distance and Position (Tilt != 0) in order to move radial /// /////////////////////////////////////////////////////////////////////////////////////// bool bPosOK = false; if (s_dDeltaHeight < -double.Epsilon) { if (dAltitude < (s_dLastHeight + (s_dDeltaHeight * 0.5))) bPosOK = true; } else if (s_dDeltaHeight > double.Epsilon) { if (dAltitude > (s_dLastHeight + (s_dDeltaHeight * 0.5))) bPosOK = true; } else bPosOK = true; s_dLastHeight = dAltitude; s_dDeltaHeight = TranslVector.Z * dAltitude / NormDistance; //50000.0; if (Math.Abs(dSinus) > double.Epsilon) { dAltitude += s_dDeltaHeight; if (bPosOK) { dLength = dAltitude + dRadius; if (rTilt.Degrees < 85.0) { double dTilt = Math.Asin(dLength * dSinusLaw); //==new tilt if (Angle.FromRadians(dTilt).Degrees <= 85.0) { dDeltaLatitude += dTilt - rTilt.Radians; rTilt.Radians = dTilt; } else rTilt.Degrees = 85.0; } else {//only change latitude, tilt is fixed Tilt = 85.0 dDeltaLatitude += Math.Asin(dRadius * dSinusLaw); dSinusLaw = dSinus / dLength; dDeltaLatitude -= Math.Asin(dRadius * dSinusLaw); } } } else dAltitude += s_dDeltaHeight; s_TheCamera.Tilt = rTilt; s_TheCamera.TargetDistance = DDxCpteDist(dAltitude, s_TheCamera.Tilt, dRadius); /////////////////////////////////////////////////////////////////////////////////////// /// Latitude/Longitude /// /////////////////////////////////////////////////////////////////////////////////////// double factor = s_TheCamera.Altitude / (s_WW.CurrentWorld.EquatorialRadius * NormLatLon);//50000.0); dDeltaLatitude += TranslVector.Y * factor; dDeltaLongitude += TranslVector.X * factor; /////////////////////////////////////////////////////////////////////////////////////// /// Heading /// /////////////////////////////////////////////////////////////////////////////////////// double dHeading = -AngleAxis.Z * AngleAxis.Angle * WorldSettings.CameraRotationSpeed / NormHeading; // 250000.0; /////////////////////////////////////////////////////////////////////////////////////// /// set the new View/Camera - position /// /////////////////////////////////////////////////////////////////////////////////////// Quaternion4d TiltQuat = Quaternion4d.RotationYawPitchRoll(0 , -dAlpha , 0); Quaternion4d TiltQuatInv = Quaternion4d.RotationYawPitchRoll(0 , dAlpha , 0); Quaternion4d SpMoQuat = Quaternion4d.RotationYawPitchRoll(dDeltaLongitude , dDeltaLatitude , dHeading); Quaternion4d OrientNew = TiltQuatInv * SpMoQuat * TiltQuat; OrientNew *= s_TheCamera.CurrentOrientation; s_TheCamera.CurrentOrientation = OrientNew; s_Position = Quaternion4d.QuaternionToEuler(OrientNew); s_TheCamera.Heading = Angle.FromRadians(s_Position.Z); s_WW.SetViewPosition(Angle.FromRadians(s_Position.Y).Degrees , Angle.FromRadians(s_Position.X).Degrees , dAltitude); World.Settings.CameraSmooth = bBackUpSmooth; s_stopWatch.Reset(); s_stopWatch.Start(); }
// inner product 2 internal static double dot(Point3d P1, Point3d P2) { return (P1.X * P2.X + P1.Y * P2.Y + P1.Z * P2.Z); }
/// <summary> /// used as delegate for the "Object Mode" -axis mapping, moving the earth /// </summary> private static void ObjectMode() { long delta = 1; if (s_stopWatch.IsRunning) { delta = s_stopWatch.ElapsedMilliseconds; //ToDo: remove following two lines; //just a performance improvement for 3DxWare Version < 6.1.8. if (delta < s_TheSensor.Period) return; s_stopWatch.Stop(); if (delta > (10 * s_TheSensor.Period)) return; } //get data from the Input Device TDconnexion.C3DxVector TranslVector = s_TheSensor.Translation as TDconnexion.C3DxVector; TDconnexion.C3DxRotation AngleAxis = s_TheSensor.Rotation as TDconnexion.C3DxRotation; double dNormTime = (double)delta / s_TheSensor.Period; TranslVector *= dNormTime; AngleAxis *= dNormTime; //0- event sent when cap released if ((AngleAxis.Angle == 0) && (TranslVector.X == 0) && (TranslVector.Y == 0) && (TranslVector.Z == 0) ) { s_stopWatch.Stop(); return; } s_TheCamera = s_WW.DrawArgs.WorldCamera; //set CameraSmooth to false to disable movement after releasing the cap bool bBackUpSmooth = World.Settings.CameraSmooth; World.Settings.CameraSmooth = false; //// Tilt//////////////////////////// s_TheCamera.Tilt -= Angle.FromRadians(AngleAxis.X * AngleAxis.Angle * WorldSettings.CameraRotationSpeed / NormTilt); //// Heading///////////////////////// double dHeading = -AngleAxis.Y * AngleAxis.Angle * WorldSettings.CameraRotationSpeed / NormHeading; //// Distance/////////////////////// s_TheCamera.TargetDistance *= (1 + TranslVector.Y / NormDistance); double factor = (s_TheCamera.Altitude) / (-NormLatLon * s_WW.CurrentWorld.EquatorialRadius); Quaternion4d Orientation = Quaternion4d.RotationYawPitchRoll(s_TheCamera.Longitude.Radians + (TranslVector.X * factor) , s_TheCamera.Latitude.Radians + (TranslVector.Z * factor) , dHeading); s_TheCamera.CurrentOrientation = Orientation; s_Position = Quaternion4d.QuaternionToEuler(Orientation); s_WW.SetViewPosition(Angle.FromRadians(s_Position.Y).Degrees , Angle.FromRadians(s_Position.X).Degrees , s_TheCamera.Altitude); World.Settings.CameraSmooth = bBackUpSmooth; s_stopWatch.Reset(); s_stopWatch.Start(); }
internal void MultiplyMatrix(Matrix4d m, ref double w) { double wprev = w; w = this.X * m[0, 3] + this.Y * m[1, 3] + this.Z * m[2, 3] + wprev * m[3, 3]; this = new Point3d(this.X * m[0, 0] + this.Y * m[1, 0] + this.Z * m[2, 0] + wprev * m[3, 0], this.X * m[0, 1] + this.Y * m[1, 1] + this.Z * m[2, 1] + wprev * m[3, 1], this.X * m[0, 2] + this.Y * m[1, 2] + this.Z * m[2, 2] + wprev * m[3, 2]); }
private static void addLineFeature(XPathNodeIterator iter, World parentWorld, RenderableObjectList parentRenderable) { if(iter.Count > 0) { while(iter.MoveNext()) { string name = getInnerTextFromFirstChild(iter.Current.Select("Name")); string distanceAboveSurfaceString = getInnerTextFromFirstChild(iter.Current.Select("DistanceAboveSurface")); string minimumDisplayAltitudeString = getInnerTextFromFirstChild(iter.Current.Select("MinimumDisplayAltitude")); string maximumDisplayAltitudeString = getInnerTextFromFirstChild(iter.Current.Select("MaximumDisplayAltitude")); string opacityString = getInnerTextFromFirstChild(iter.Current.Select("Opacity")); //string extrudeHeightString = getInnerTextFromFirstChild(iter.Current.Select("ExtrudeHeight")); string extrudeUpwardsString = getInnerTextFromFirstChild(iter.Current.Select("Extrude")); string imageUri = getInnerTextFromFirstChild(iter.Current.Select("ImageUri")); string outlineString = getInnerTextFromFirstChild(iter.Current.Select("Outline")); string lineWidthString = getInnerTextFromFirstChild(iter.Current.Select("LineWidth")); string altitudemodeString = getInnerTextFromFirstChild(iter.Current.Select("AltitudeMode")); XPathNodeIterator posListIter = iter.Current.Select("LineString/posList"); posListIter.MoveNext(); string lineString = getInnerTextFromFirstChild(posListIter); string[] lineParts = lineString.Split(' '); Point3d[] points = new Point3d[lineParts.Length]; for(int i = 0; i < lineParts.Length; i++) { string[] pointParts = lineParts[i].Split(','); points[i] = new Point3d(); points[i].X = ParseDouble(pointParts[0]); points[i].Y = ParseDouble(pointParts[1]); if(pointParts.Length > 2) points[i].Z = ParseDouble(pointParts[2]); } System.Drawing.Color c = System.Drawing.Color.Black; if(iter.Current.Select("RGBColor").Count > 0) { c = getColor(iter.Current.Select("RGBColor")); } if(iter.Current.Select("FeatureColor").Count > 0) { c = getColor(iter.Current.Select("FeatureColor")); } LineFeature lf = null; if(imageUri != null && imageUri.Length > 0) { lf = new LineFeature(name, parentWorld, points, imageUri); } else { lf = new LineFeature( name, parentWorld, points, c); } string description = getInnerTextFromFirstChild(iter.Current.Select("Description")); if(description != null && description.Length > 0) lf.Description = description; if(iter.Current.Select("OutlineColor").Count > 0) { lf.LineColor = getColor(iter.Current.Select("OutlineColor")); } if(lineWidthString != null) lf.LineWidth = (float)ParseDouble(lineWidthString); if(outlineString != null && outlineString.Length > 0) lf.Outline = ParseBool(outlineString); if(opacityString != null && opacityString.Length > 0) lf.Opacity = byte.Parse(opacityString); if(distanceAboveSurfaceString != null && distanceAboveSurfaceString.Length > 0) lf.DistanceAboveSurface = ParseDouble(distanceAboveSurfaceString); if(minimumDisplayAltitudeString != null && minimumDisplayAltitudeString.Length > 0) lf.MinimumDisplayAltitude = ParseDouble(minimumDisplayAltitudeString); if(maximumDisplayAltitudeString != null && maximumDisplayAltitudeString.Length > 0) lf.MaximumDisplayAltitude = ParseDouble(maximumDisplayAltitudeString); if (altitudemodeString != null && altitudemodeString.Length > 0) { if (altitudemodeString.ToLower(System.Globalization.CultureInfo.InvariantCulture).Equals("absolute")) lf.AltitudeMode = AltitudeMode.Absolute; if (altitudemodeString.ToLower(System.Globalization.CultureInfo.InvariantCulture).Equals("relativetoground")) lf.AltitudeMode = AltitudeMode.RelativeToGround; if (altitudemodeString.ToLower(System.Globalization.CultureInfo.InvariantCulture).Equals("clampedtoground")) lf.AltitudeMode = AltitudeMode.ClampedToGround; } if(extrudeUpwardsString!=null) { bool extrude = Convert.ToBoolean(extrudeUpwardsString); lf.Extrude = extrude; } addExtendedInformation(iter.Current.Select("ExtendedInformation"), lf); string infoUri = iter.Current.GetAttribute("InfoUri", ""); if(infoUri != null && infoUri.Length > 0) { if(lf.MetaData.Contains("InfoUri")) { lf.MetaData["InfoUri"] = infoUri; } else { lf.MetaData.Add("InfoUri", infoUri); } } lf.MetaData.Add("XmlSource", (string)parentRenderable.MetaData["XmlSource"]); lf.ParentList = parentRenderable; if(World.Settings.useDefaultLayerStates) { lf.IsOn = ParseBool(iter.Current.GetAttribute("ShowAtStartup", "")); } else { lf.IsOn = IsLayerOn(lf); } parentRenderable.ChildObjects.Add( lf ); parentRenderable.RenderPriority = RenderPriority.LinePaths; } } }
/// <summary> /// Find the intersection of a ray with the terrain. /// </summary> /// <param name="p1">Cartesian coordinate of starting point</param> /// <param name="p2">Cartesian coordinate of end point</param> /// <param name="samplingPrecision">Sample length in meter</param> /// <param name="resultPrecision">Final sampling length in meter</param> /// <param name="latitude">Out : intersection latitude</param> /// <param name="longitude">Out : intersection longitude</param> /// <param name="world">Current world</param> /// <returns>NaN if no intersection found</returns> internal static void RayIntersectionWithTerrain( Point3d p1, Point3d p2, double samplingPrecision, double resultPrecision, out Angle latitude, out Angle longitude, World world) { // Check for sphere intersection first // Note : checks for world radius + highest possible elevation float vertEx = World.Settings.VerticalExaggeration; double maxRadius = world.EquatorialRadius + 9000 * vertEx; // Max altitude for earth - should be dependant on world double a = (p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y) + (p2.Z - p1.Z) * (p2.Z - p1.Z); double b = 2.0 * ((p2.X - p1.X) * (p1.X) + (p2.Y - p1.Y) * (p1.Y) + (p2.Z - p1.Z) * (p1.Z)); double c = p1.X * p1.X + p1.Y * p1.Y + p1.Z * p1.Z - maxRadius * maxRadius; double discriminant = b * b - 4 * a * c; if (discriminant <= 0) { // No intersection with sphere latitude = Angle.NaN; longitude = Angle.NaN; return; } // Factor to intersection // Note : if t1 > 0 intersection is forward, < 0 is behind us double t1 = ((-1.0) * b - Math.Sqrt(discriminant)) / (2 * a); Point3d p1LatLon = MathEngine.CartesianToSpherical(p1.X, p1.Y, p1.Z); if (t1 > 0 && p1LatLon.X > maxRadius) { // Looking from above max altitude : move p1 forward to intersection with max alt sphere p1 = new Point3d(p1.X + t1 * (p2.X - p1.X), p1.Y + t1 * (p2.Y - p1.Y), p1.Z + t1 * (p2.Z - p1.Z)); } // Ray sample Vector3 sample = new Vector3((float)(p2.X - p1.X), (float)(p2.Y - p1.Y), (float)(p2.Z - p1.Z)); double maxLength = sample.Length(); // Max length for ray tracing double sampleLength = samplingPrecision;// Sampling steps length sample.Normalize(); sample.Scale((float)sampleLength); // Casting Point3d ray = p1; double rayLength = 0; while (rayLength < maxLength) { Point3d rayLatLon = MathEngine.CartesianToSpherical(ray.X, ray.Y, ray.Z); // Altitude at ray position double rayAlt = rayLatLon.X - world.EquatorialRadius; // Altitude at terrain position - from cached data (no download) double terrainAlt = world.TerrainAccessor.GetCachedElevationAt(MathEngine.RadiansToDegrees(rayLatLon.Y), MathEngine.RadiansToDegrees(rayLatLon.Z)); // best loaded data if (double.IsNaN(terrainAlt)) terrainAlt = 0; terrainAlt *= vertEx; if (terrainAlt > rayAlt) { // Intersection found if (sampleLength > resultPrecision) { // Go back one step ray.X -= sample.X; ray.Y -= sample.Y; ray.Z -= sample.Z; rayLength -= sampleLength; // and refine sampling sampleLength /= 10; sample.Normalize(); sample.Scale((float)sampleLength); } else { // return location latitude = Angle.FromRadians(rayLatLon.Y); longitude = Angle.FromRadians(rayLatLon.Z); return; } } // Move forward ray.X += sample.X; ray.Y += sample.Y; ray.Z += sample.Z; rayLength += sampleLength; } // No intersection with terrain found latitude = Angle.NaN; longitude = Angle.NaN; }
private static void addPolygonFeature(XPathNodeIterator iter, World parentWorld, RenderableObjectList parentRenderable) { if(iter.Count > 0) { while(iter.MoveNext()) { string name = getInnerTextFromFirstChild(iter.Current.Select("Name")); string distanceAboveSurfaceString = getInnerTextFromFirstChild(iter.Current.Select("DistanceAboveSurface")); string minimumDisplayAltitudeString = getInnerTextFromFirstChild(iter.Current.Select("MinimumDisplayAltitude")); string maximumDisplayAltitudeString = getInnerTextFromFirstChild(iter.Current.Select("MaximumDisplayAltitude")); string opacityString = getInnerTextFromFirstChild(iter.Current.Select("Opacity")); string extrudeHeightString = getInnerTextFromFirstChild(iter.Current.Select("ExtrudeHeight")); string extrudeUpwardsString = getInnerTextFromFirstChild(iter.Current.Select("ExtrudeUpwards")); string imageUri = getInnerTextFromFirstChild(iter.Current.Select("ImageUri")); string outlineString = getInnerTextFromFirstChild(iter.Current.Select("Outline")); XPathNodeIterator posListIter = iter.Current.Select("exterior/LinearRing/posList"); posListIter.MoveNext(); string lineString = getInnerTextFromFirstChild(posListIter); string[] lineParts = lineString.Split(' '); Point3d[] points = new Point3d[lineParts.Length]; for(int i = 0; i < lineParts.Length; i++) { string[] pointParts = lineParts[i].Split(','); points[i] = new Point3d(); points[i].X = ParseDouble(pointParts[0]); points[i].Y = ParseDouble(pointParts[1]); if(pointParts.Length > 2) points[i].Z = ParseDouble(pointParts[2]); } System.Drawing.Color c = System.Drawing.Color.Black; System.Drawing.Color outlineColor = System.Drawing.Color.Black; if(iter.Current.Select("FeatureColor").Count > 0) { c = getColor(iter.Current.Select("FeatureColor")); } if(iter.Current.Select("OutlineColor").Count > 0) { outlineColor = getColor(iter.Current.Select("OutlineColor")); } PolygonFeature pf = null; LinearRing outerRing = new LinearRing(); outerRing.Points = points; pf = new PolygonFeature(name, parentWorld, outerRing, null, c); pf.OutlineColor = outlineColor; if(outlineString != null && outlineString.Length > 0) pf.Outline = ParseBool(outlineString); if(opacityString != null && opacityString.Length > 0) pf.Opacity = byte.Parse(opacityString); if(distanceAboveSurfaceString != null && distanceAboveSurfaceString.Length > 0) pf.DistanceAboveSurface = ParseDouble(distanceAboveSurfaceString); if(minimumDisplayAltitudeString != null && minimumDisplayAltitudeString.Length > 0) pf.MinimumDisplayAltitude = ParseDouble(minimumDisplayAltitudeString); if(maximumDisplayAltitudeString != null && maximumDisplayAltitudeString.Length > 0) pf.MaximumDisplayAltitude = ParseDouble(maximumDisplayAltitudeString); string description = getInnerTextFromFirstChild(iter.Current.Select("Description")); if(description != null && description.Length > 0) pf.Description = description; addExtendedInformation(iter.Current.Select("ExtendedInformation"), pf); string infoUri = iter.Current.GetAttribute("InfoUri", ""); if(infoUri != null && infoUri.Length > 0) { if(pf.MetaData.Contains("InfoUri")) { pf.MetaData["InfoUri"] = infoUri; } else { pf.MetaData.Add("InfoUri", infoUri); } } pf.MetaData.Add("XmlSource", (string)parentRenderable.MetaData["XmlSource"]); pf.ParentList = parentRenderable; if(World.Settings.useDefaultLayerStates) { pf.IsOn = ParseBool(iter.Current.GetAttribute("ShowAtStartup", "")); } else { pf.IsOn = IsLayerOn(pf); } parentRenderable.ChildObjects.Add( pf ); parentRenderable.RenderPriority = RenderPriority.LinePaths; } } }
public LineFeature(string name, World parentWorld, Point3d[] points, string imageUri) : base(name, parentWorld) { m_points = points; m_imageUri = imageUri; m_numPoints = m_points.LongLength; RenderPriority = WorldWind.Renderable.RenderPriority.LinePaths; }
// Adjust/Fold struts vertices using terrain border vertices positions private void fold_struts(bool renderStruts, float meshBaseRadius) { short vertexDensity = (short)Math.Sqrt(vertices.Length); for (int i = 0; i < vertexDensity; i++) { if (i == 0 || i == vertexDensity - 1) { for (int j = 0; j < vertexDensity; j++) { int offset = (i == 0) ? vertexDensity : -vertexDensity; if (j == 0) offset++; if (j == vertexDensity - 1) offset--; Point3d p = new Point3d(vertices[i * vertexDensity + j + offset].Position.X, vertices[i * vertexDensity + j + offset].Position.Y, vertices[i * vertexDensity + j + offset].Position.Z); if (renderStruts) p = ProjectOnMeshBase(p, meshBaseRadius); vertices[i * vertexDensity + j].Position = new Vector3((float)p.X, (float)p.Y, (float)p.Z); } } else { Point3d p = new Point3d(vertices[i * vertexDensity + 1].Position.X, vertices[i * vertexDensity + 1].Position.Y, vertices[i * vertexDensity + 1].Position.Z); if (renderStruts) p = ProjectOnMeshBase(p, meshBaseRadius); vertices[i * vertexDensity].Position = new Vector3((float)p.X, (float)p.Y, (float)p.Z); p = new Point3d(vertices[i * vertexDensity + vertexDensity - 2].Position.X, vertices[i * vertexDensity + vertexDensity - 2].Position.Y, vertices[i * vertexDensity + vertexDensity - 2].Position.Z); if (renderStruts) p = ProjectOnMeshBase(p, meshBaseRadius); vertices[i * vertexDensity + vertexDensity - 1].Position = new Vector3((float)p.X, (float)p.Y, (float)p.Z); } } }
/// <summary> /// Adds a point to the line at the end of the line. /// </summary> /// <param name="point">The Point3d object to add.</param> public void AddPoint(Point3d point) { // if the array is too small grow it. if (m_numPoints >= m_points.LongLength) { long growSize = m_points.LongLength / 2; if (growSize < 10) growSize = 10; Point3d[] points = new Point3d[m_points.LongLength + growSize]; for (int i = 0; i < m_numPoints; i++) { points[i] = m_points[i]; } m_points = points; } m_points[m_numPoints] = point; m_numPoints++; NeedsUpdate = true; }
// Project an elevated mesh point to the mesh base private Point3d ProjectOnMeshBase(Point3d p, float meshBaseRadius) { p.normalize(); p = p * meshBaseRadius; return p; }
private System.Drawing.Point[] getScreenPoints(Point3d[] sourcePoints, int offset, int length, GeographicBoundingBox dstBB, Size dstImageSize) { double degreesPerPixelX = (dstBB.East - dstBB.West) / (double)dstImageSize.Width; double degreesPerPixelY = (dstBB.North - dstBB.South) / (double)dstImageSize.Height; ArrayList screenPointList = new ArrayList(); for(int i = offset; i < offset + length; i++) { double screenX = (sourcePoints[i].X - dstBB.West) / degreesPerPixelX; double screenY = (dstBB.North - sourcePoints[i].Y) / degreesPerPixelY; if(screenPointList.Count > 0) { Point v = (Point)screenPointList[screenPointList.Count - 1]; if(v.X == (int)screenX && v.Y == (int)screenY) { continue; } } screenPointList.Add(new Point((int)screenX, (int)screenY)); } if(screenPointList.Count <= 1) return new Point[] { new Point(0,0), new Point(0,0) }; return (Point[])screenPointList.ToArray(typeof(Point)); }
private void f(System.IntPtr vertexData) { try { double[] v = new double[3]; System.Runtime.InteropServices.Marshal.Copy(vertexData, v, 0, 3); Point3d p = new Point3d(v[0], v[1], 0); tessList.Add(p); } catch(Exception ex) { Log.Write(ex); } }