//TODO: Improve rendering code to segment spherical coordinates //which are too far apart to follow curvature public Vector3[] BuildSegment(Angle startLatitude, Angle startLongitude, Angle endLatitude, Angle endLongitude, float heightAboveSurface) { //check how far the point being added is from the last point Angle angularDistance = World.ApproxAngularDistance( startLatitude, startLongitude, endLatitude, endLongitude); Vector3[] newPoints = null; if (angularDistance.Degrees >= 2.0) { int samples = (int)(angularDistance.Radians * 30); // 1 point for every 2 degrees. if (samples < 2) { samples = 2; } Angle lat, lon = Angle.Zero; newPoints = new Vector3[samples]; for (int i = 0; i < samples; i++) { float t = (float)i / (samples - 1); World.IntermediateGCPoint(t, startLatitude, startLongitude, endLatitude, endLongitude, angularDistance, out lat, out lon); newPoints[i] = MathEngine.SphericalToCartesian(lat, lon, this._parentWorld.EquatorialRadius + this.verticalExaggeration * heightAboveSurface); } } return(newPoints); }
/// <summary> /// Draws a tropic line at specified latitude with specified label /// </summary> /// <param name="latitude">Latitude in degrees</param> void RenderTropicLine(DrawArgs drawArgs, float latitude, string label) { int vertexIndex = 0; Vector3 referenceCenter = new Vector3( (float)drawArgs.WorldCamera.ReferenceCenter.X, (float)drawArgs.WorldCamera.ReferenceCenter.Y, (float)drawArgs.WorldCamera.ReferenceCenter.Z); for (float longitude = this.MinVisibleLongitude; longitude <= this.MaxVisibleLongitude; longitude = longitude + this.LongitudeInterval) { Vector3 pointXyz = MathEngine.SphericalToCartesian(latitude, longitude, this.radius); this.lineVertices[vertexIndex].X = pointXyz.X; this.lineVertices[vertexIndex].Y = pointXyz.Y; this.lineVertices[vertexIndex].Z = pointXyz.Z; this.lineVertices[vertexIndex].Color = World.Settings.tropicLinesColor; vertexIndex++; } drawArgs.device.DrawUserPrimitives(PrimitiveType.LineStrip, this.LongitudePointCount - 1, this.lineVertices); Vector3 t1 = MathEngine.SphericalToCartesian(Angle.FromDegrees(latitude), drawArgs.WorldCamera.Longitude - drawArgs.WorldCamera.TrueViewRange * 0.3f * 0.5f, this.radius); if (drawArgs.WorldCamera.ViewFrustum.ContainsPoint(t1)) { t1 = drawArgs.WorldCamera.Project(t1 - referenceCenter); drawArgs.defaultDrawingFont.DrawText(null, label, new System.Drawing.Rectangle((int)t1.X, (int)t1.Y, drawArgs.screenWidth, drawArgs.screenHeight), FontDrawFlags.NoClip, World.Settings.tropicLinesColor); } }
public virtual void ComputeAbsoluteMatrices() { this.m_absoluteWorldMatrix = Matrix.Identity; float aspectRatio = (float)this.viewPort.Width / this.viewPort.Height; float zNear = (float)Math.Max(this._altitude - this.TerrainElevationUnderCamera, minimumAltitude) * 0.1f; double distToCenterOfPlanet = (this._altitude + this.WorldRadius); double tangentalDistance = Math.Sqrt(distToCenterOfPlanet * distToCenterOfPlanet - this._worldRadius * this._worldRadius); if (tangentalDistance < 1000000 || double.IsNaN(tangentalDistance)) { tangentalDistance = 1000000; } this.m_absoluteProjectionMatrix = Matrix.PerspectiveFovRH((float)this._fov.Radians, aspectRatio, zNear, (float)tangentalDistance); this.m_absoluteViewMatrix = Matrix.LookAtRH( MathEngine.SphericalToCartesian(this._latitude.Degrees, this._longitude.Degrees, this.WorldRadius + this.curCameraElevation), Vector3.Zero, new Vector3(0, 0, 1)); this.m_absoluteViewMatrix *= Matrix.RotationYawPitchRoll( (float)-(this._swivel.Radians + this._headSwivel.Radians), (float)-(this._tilt.Radians + this._headTilt.Radians), (float)this._heading.Radians); //m_absoluteViewMatrix *= Matrix.Translation(0, 0, (float)(-this._distance + curCameraElevation)); this.m_absoluteViewMatrix *= Matrix.Translation(0, 0, (float)(-(this._distance + this._headZoom))); this.m_absoluteViewMatrix *= Matrix.RotationZ((float)this._bank.Radians); }
private void DrawAxis(DrawArgs drawArgs) { CustomVertex.PositionColored[] axis = new CustomVertex.PositionColored[2]; Vector3 topV = MathEngine.SphericalToCartesian(90, 0, 1.15f * this.EquatorialRadius); axis[0].X = topV.X; axis[0].Y = topV.Y; axis[0].Z = topV.Z; axis[0].Color = Color.Pink.ToArgb(); Vector3 botV = MathEngine.SphericalToCartesian(-90, 0, 1.15f * this.EquatorialRadius); axis[1].X = botV.X; axis[1].Y = botV.Y; axis[1].Z = botV.Z; axis[1].Color = Color.Pink.ToArgb(); drawArgs.Device.VertexFormat = CustomVertex.PositionColored.Format; drawArgs.Device.TextureState[0].ColorOperation = TextureOperation.Disable; drawArgs.Device.Transform.World = Matrix.Translation((float)-drawArgs.WorldCamera.ReferenceCenter.X, (float)-drawArgs.WorldCamera.ReferenceCenter.Y, (float)-drawArgs.WorldCamera.ReferenceCenter.Z); drawArgs.Device.DrawUserPrimitives(PrimitiveType.LineStrip, 1, axis); drawArgs.Device.Transform.World = drawArgs.WorldCamera.WorldMatrix; }
public override void Initialize(DrawArgs drawArgs) { FileInfo boundaryFileInfo = new FileInfo(this._boundaryFilePath); if (!boundaryFileInfo.Exists) { this.isInitialized = true; return; } using (FileStream boundaryFileStream = boundaryFileInfo.OpenRead()) using (BinaryReader boundaryFileReader = new BinaryReader(boundaryFileStream, System.Text.Encoding.ASCII)) { int numBoundaries = boundaryFileReader.ReadInt32(); int count = boundaryFileReader.ReadInt32(); this.vertices = new CustomVertex.PositionColored[count]; for (int i = 0; i < count; i++) { double lat = boundaryFileReader.ReadDouble(); double lon = boundaryFileReader.ReadDouble(); Vector3 v = MathEngine.SphericalToCartesian((float)lat, (float)lon, (float)(this._parentWorld.EquatorialRadius + this._distanceAboveSurface)); this.vertices[i].X = v.X; this.vertices[i].Y = v.Y; this.vertices[i].Z = v.Z; this.vertices[i].Color = this._color; } } this.isInitialized = true; }
/// <summary> /// Builds the image's mesh /// </summary> protected virtual void CreateMesh() { int upperBound = this.meshPointCount - 1; float scaleFactor = (float)1/upperBound; double latrange = Math.Abs(this.maxLat - this.minLat); double lonrange; if(this.minLon < this.maxLon) lonrange = this.maxLon - this.minLon; else lonrange = 360.0f + this.maxLon - this.minLon; int opacityColor = System.Drawing.Color.FromArgb(this.m_opacity,0,0,0).ToArgb(); this.vertices = new CustomVertex.PositionNormalTextured[this.meshPointCount * this.meshPointCount]; for(int i = 0; i < this.meshPointCount; i++) { for(int j = 0; j < this.meshPointCount; j++) { double height = 0; if(this._terrainAccessor != null) height = this.verticalExaggeration * this._terrainAccessor.GetElevationAt( (double) this.maxLat - scaleFactor * latrange * i, (double) this.minLon + scaleFactor * lonrange * j, (double)upperBound / latrange); Vector3 pos = MathEngine.SphericalToCartesian(this.maxLat - scaleFactor*latrange*i, this.minLon + scaleFactor*lonrange*j, this.layerRadius + height); this.vertices[i* this.meshPointCount + j].X = pos.X; this.vertices[i* this.meshPointCount + j].Y = pos.Y; this.vertices[i* this.meshPointCount + j].Z = pos.Z; this.vertices[i* this.meshPointCount + j].Tu = j*scaleFactor; this.vertices[i* this.meshPointCount + j].Tv = i*scaleFactor; // vertices[i*meshPointCount + j].Color = opacityColor; } } this.indices = new short[2 * upperBound * upperBound * 3]; for(int i = 0; i < upperBound; i++) { for(int j = 0; j < upperBound; j++) { this.indices[(2*3*i*upperBound) + 6*j] = (short)(i* this.meshPointCount + j); this.indices[(2*3*i*upperBound) + 6*j + 1] = (short)((i+1)* this.meshPointCount + j); this.indices[(2*3*i*upperBound) + 6*j + 2] = (short)(i* this.meshPointCount + j+1); this.indices[(2*3*i*upperBound) + 6*j + 3] = (short)(i* this.meshPointCount + j+1); this.indices[(2*3*i*upperBound) + 6*j + 4] = (short)((i+1)* this.meshPointCount + j); this.indices[(2*3*i*upperBound) + 6*j + 5] = (short)((i+1)* this.meshPointCount + j+1); } } this.calculate_normals(ref this.vertices, this.indices); }
protected virtual void RenderProgress(DrawArgs drawArgs) { drawArgs.device.SetTransform(TransformState.World, Matrix.Translation( (float)-drawArgs.WorldCamera.ReferenceCenter.X, (float)-drawArgs.WorldCamera.ReferenceCenter.Y, (float)-drawArgs.WorldCamera.ReferenceCenter.Z )); this.device.SetRenderState(RenderState.ZEnable , false); double centerLat = 0.5 * (this.maxLat + this.minLat); double centerLon = 0.5 * (this.maxLon + this.minLon); Vector3 v = MathEngine.SphericalToCartesian(centerLat, centerLon, this.layerRadius); if(drawArgs.WorldCamera.ViewFrustum.ContainsPoint(v) && MathEngine.SphericalDistanceDegrees(centerLat, centerLon, drawArgs.WorldCamera.Latitude.Degrees, drawArgs.WorldCamera.Longitude.Degrees) < 2 * drawArgs.WorldCamera.ViewRange.Degrees ) { v.Project(drawArgs.device.Viewport, drawArgs.device.GetTransform(TransformState.Projection), drawArgs.device.GetTransform(TransformState.View), drawArgs.device.GetTransform(TransformState.World)); MenuUtils.DrawBox((int)v.X, (int)v.Y, 200, 40, 0.0f, this.progressBarBackColor, drawArgs.device); Vector2[] boxOutline = new Vector2[5]; boxOutline[0].X = (int)v.X; boxOutline[0].Y = (int)v.Y; boxOutline[1].X = (int)v.X + 200; boxOutline[1].Y = (int)v.Y; boxOutline[2].X = (int)v.X + 200; boxOutline[2].Y = (int)v.Y + 40; boxOutline[3].X = (int)v.X; boxOutline[3].Y = (int)v.Y + 40; boxOutline[4].X = (int)v.X; boxOutline[4].Y = (int)v.Y; MenuUtils.DrawLine(boxOutline, this.progressBarOutlineColor, drawArgs.device); drawArgs.defaultDrawingFont.DrawText(null, "Downloading Remote Image...", new System.Drawing.Rectangle((int)v.X + 5, (int)v.Y + 5, 200, 50), FontDrawFlags.NoClip, this.textColor); this.DrawProgressBar(drawArgs, v.X + 100, v.Y + 30, 180, 10, World.Settings.downloadProgressColor); } this.device.SetRenderState(RenderState.ZEnable , true); drawArgs.device.SetTransform(TransformState.World, drawArgs.WorldCamera.WorldMatrix; }
/// <summary> /// Initializes a new instance of the <see cref= "T:WorldWind.BoundingSphere"/> class /// from a set of lat/lon values (degrees) /// </summary> /// <param name="south"></param> /// <param name="north"></param> /// <param name="west"></param> /// <param name="east"></param> /// <param name="radius1"></param> /// <param name="radius2"></param> public BoundingBox(float south, float north, float west, float east, float radius1, float radius2) { float scale = radius2 / radius1; this.corners = new Vector3[8]; this.corners[0] = MathEngine.SphericalToCartesian(south, west, radius1); this.corners[1] = Vector3.Scale(this.corners[0], scale); this.corners[2] = MathEngine.SphericalToCartesian(south, east, radius1); this.corners[3] = Vector3.Scale(this.corners[2], scale); this.corners[4] = MathEngine.SphericalToCartesian(north, west, radius1); this.corners[5] = Vector3.Scale(this.corners[4], scale); this.corners[6] = MathEngine.SphericalToCartesian(north, east, radius1); this.corners[7] = Vector3.Scale(this.corners[6], scale); }
// Compute Sun geocentric cartesian position given actual position on the globe, // heading, elevation and sun distance public static Point3d GetGeocentricPosition(Vector3 position, Angle heading, Angle elevation, double sunDistance) { // Untransformed sun pos from globe center Vector3 sun = MathEngine.SphericalToCartesian(elevation, Angle.FromRadians(Math.PI - heading.Radians), sunDistance); // Now transform it to current location Vector3 pos = MathEngine.CartesianToSpherical(position.X, position.Y, position.Z); Matrix sunTrans = Matrix.Identity; sunTrans *= Matrix.Translation(0, 0, pos.X); // radius pos sunTrans *= Matrix.RotationY((float)Math.PI / 2 - pos.Y); // lat pos sunTrans *= Matrix.RotationZ(pos.Z); // lon pos sun.TransformCoordinate(sunTrans); return(new Point3d(-sun.X, -sun.Y, -sun.Z)); }
private void Update() { double altitude; // Altitude is ASL altitude = (World.Settings.VerticalExaggeration * this.Alt) + DrawArgs.Camera.WorldRadius; this.Position = MathEngine.SphericalToCartesian(this.Lat, this.Lon, altitude); this.m_positionD = MathEngine.SphericalToCartesianD( Angle.FromDegrees(this.Lat), Angle.FromDegrees(this.Lon), altitude); }
/// <summary> /// Determine if the object is visible /// </summary> protected bool IsVisible(CameraBase camera) { if (this.IsVertExaggerable == true) { this.vertExaggeration = World.Settings.VerticalExaggeration; } else { this.vertExaggeration = 1; } //if (worldXyz == Vector3.Zero) this.worldXyz = MathEngine.SphericalToCartesian(this.Latitude, this.Longitude, this.World.EquatorialRadius + ((this.currentElevation + this.Altitude) * this.vertExaggeration)); return(camera.ViewFrustum.ContainsPoint(this.worldXyz)); }
public void Load(DrawArgs drawArgs) { this.linePoints = new CustomVertex.PositionColored[0]; if (this.terrainFileName == null) { this.isInitialized = true; return; } FileInfo inFile = new FileInfo(this.terrainFileName); if (!inFile.Exists) { this.isInitialized = true; return; } using (FileStream fs = new FileStream(inFile.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)) { byte[] buffer = new byte[inFile.Length]; int bytesRead = fs.Read(buffer, 0, (int)inFile.Length); using (MemoryStream ms = new MemoryStream(buffer)) using (BinaryReader br = new BinaryReader(ms, System.Text.Encoding.ASCII)) { int numCoords = br.ReadInt32(); this.sphericalCoordinates = new Vector3[numCoords]; for (int i = 0; i < numCoords; i++) { this.sphericalCoordinates[i].X = br.ReadSingle(); this.sphericalCoordinates[i].Y = br.ReadSingle(); } this.linePoints = new CustomVertex.PositionColored[numCoords]; for (int i = 0; i < numCoords; i++) { Vector3 v = MathEngine.SphericalToCartesian(this.sphericalCoordinates[i].X, this.sphericalCoordinates[i].Y, this._parentWorld.EquatorialRadius + World.Settings.VerticalExaggeration * this.heightAboveSurface); this.linePoints[i].X = v.X; this.linePoints[i].Y = v.Y; this.linePoints[i].Z = v.Z; this.linePoints[i].Color = this.lineColor; } } } this.isLoaded = true; }
public static Point3d GetGeocentricPosition(System.DateTime utcDateTime) { if (World.Settings.SunSynchedWithTime) { // Sun synched with time and date double JD = getJulianDay(utcDateTime); double T = (JD - 2451545.0) / 36525; // number of Julian centuries since Jan 1, 2000, 12 UT double k = Math.PI / 180.0; double M = 357.52910 + 35999.05030 * T - 0.0001559 * T * T - 0.00000048 * T * T * T; // mean anomaly, degree double L0 = 280.46645 + 36000.76983 * T + 0.0003032 * T * T; // mean longitude, degree double DL = (1.914600 - 0.004817 * T - 0.000014 * T * T) * Math.Sin(k * M) + (0.019993 - 0.000101 * T) * Math.Sin(k * 2 * M) + 0.000290 * Math.Sin(k * 3 * M); double L = L0 + DL; // true longitude, degree L = L % 360; // obliquity eps of ecliptic: double eps = 23.0 + 26.0 / 60.0 + 21.448 / 3600.0 - (46.8150 * T + 0.00059 * T * T - 0.001813 * T * T * T) / 3600; double X = Math.Cos(k * L); double Y = Math.Cos(k * eps) * Math.Sin(k * L); double Z = Math.Sin(k * eps) * Math.Sin(k * L); double R = Math.Sqrt(1.0 - Z * Z); double dec = (180 / Math.PI) * Math.Atan(Z / R); // in degrees double RA = (24 / Math.PI) * Math.Atan(Y / (X + R)); // in hours double theta0 = 280.46061837 + 360.98564736629 * (JD - 2451545.0) + 0.000387933 * T * T - T * T * T / 38710000.0; // Greenwich Sidereal Time theta0 = theta0 % 360; RA *= 15; // convert from hours to degrees double tau = theta0 - RA; Point3d pos = MathEngine.SphericalToCartesianD( Angle.FromDegrees(-dec), Angle.FromDegrees(-(tau - 180)), 1); return(pos); } else { // Fixed sun heading and elevation double worldRadius = 6378137; // Earth meter Vector3 position = MathEngine.SphericalToCartesian(World.Settings.CameraLatitude, World.Settings.CameraLongitude, worldRadius); return(GetGeocentricPosition(position, Angle.FromRadians(World.Settings.SunHeading), Angle.FromRadians(World.Settings.SunElevation), World.Settings.SunDistance)); } }
/// <summary> /// Intermediate points on a great circle /// In previous sections we have found intermediate points on a great circle given either /// the crossing latitude or longitude. Here we find points (lat,lon) a given fraction of the /// distance (d) between them. Suppose the starting point is (lat1,lon1) and the final point /// (lat2,lon2) and we want the point a fraction f along the great circle route. f=0 is /// point 1. f=1 is point 2. The two points cannot be antipodal ( i.e. lat1+lat2=0 and /// abs(lon1-lon2)=pi) because then the route is undefined. /// </summary> /// <param name="f">Fraction of the distance for intermediate point (0..1)</param> public Vector3 IntermediateGCPoint(float f, Angle lat1, Angle lon1, Angle lat2, Angle lon2, Angle d) { double sind = Math.Sin(d.Radians); double cosLat1 = Math.Cos(lat1.Radians); double cosLat2 = Math.Cos(lat2.Radians); double A = Math.Sin((1 - f) * d.Radians) / sind; double B = Math.Sin(f * d.Radians) / sind; double x = A * cosLat1 * Math.Cos(lon1.Radians) + B * cosLat2 * Math.Cos(lon2.Radians); double y = A * cosLat1 * Math.Sin(lon1.Radians) + B * cosLat2 * Math.Sin(lon2.Radians); double z = A * Math.Sin(lat1.Radians) + B * Math.Sin(lat2.Radians); Angle lat = Angle.FromRadians(Math.Atan2(z, Math.Sqrt(x * x + y * y))); Angle lon = Angle.FromRadians(Math.Atan2(y, x)); Vector3 v = MathEngine.SphericalToCartesian(lat, lon, _equatorialRadius); return(v); }
public override void Initialize(DrawArgs drawArgs) { FileInfo polygonFileInfo = new FileInfo(this._polygonFilePath); if (!polygonFileInfo.Exists) { this.isInitialized = true; return; } using (FileStream polygonFileStream = polygonFileInfo.OpenRead()) using (BinaryReader polygonFileReader = new BinaryReader(polygonFileStream, System.Text.Encoding.ASCII)) { int nodeCount = polygonFileReader.ReadInt32(); int edgeCount = polygonFileReader.ReadInt32(); this._vertices = new CustomVertex.PositionColored[nodeCount]; this._indices = new int[edgeCount * 3]; for (int i = 0; i < nodeCount; i++) { double lat = polygonFileReader.ReadDouble(); double lon = polygonFileReader.ReadDouble(); Vector3 curNode = MathEngine.SphericalToCartesian((float)lat, (float)lon, (float)(this._parentWorld.EquatorialRadius + this._distanceAboveSurface)); this._vertices[i].X = curNode.X; this._vertices[i].Y = curNode.Y; this._vertices[i].Z = curNode.Z; this._vertices[i].Color = this._color.ToArgb(); } for (int i = 0; i < edgeCount; i++) { int e0 = polygonFileReader.ReadInt32(); int e1 = polygonFileReader.ReadInt32(); int e2 = polygonFileReader.ReadInt32(); this._indices[i * 3] = e0; this._indices[i * 3 + 1] = e1; this._indices[i * 3 + 2] = e2; } } this.isInitialized = true; }
public bool WasClicked(DrawArgs drawArgs) { int halfIconWidth = (int)(0.3f * this.iconSize); int halfIconHeight = (int)(0.3f * this.iconSize); Vector3 projectedPoint = MathEngine.SphericalToCartesian(0.5f * (this.north + this.south), 0.5f * (this.west + this.east), this.layerRadius); if (!drawArgs.WorldCamera.ViewFrustum.ContainsPoint(projectedPoint)) { return(false); } Vector3 translationVector = new Vector3( (float)(projectedPoint.X - drawArgs.WorldCamera.ReferenceCenter.X), (float)(projectedPoint.Y - drawArgs.WorldCamera.ReferenceCenter.Y), (float)(projectedPoint.Z - drawArgs.WorldCamera.ReferenceCenter.Z)); // Find closest mouse-over icon projectedPoint = drawArgs.WorldCamera.Project(translationVector); int top = (int)projectedPoint.Y - halfIconHeight; int bottom = (int)projectedPoint.Y + halfIconHeight; int left = (int)projectedPoint.X - halfIconWidth; int right = (int)projectedPoint.X + halfIconWidth; try { if (DrawArgs.LastMousePosition.X < right && DrawArgs.LastMousePosition.X > left && DrawArgs.LastMousePosition.Y > top && DrawArgs.LastMousePosition.Y < bottom) { return(true); } else { return(false); } } catch { } return(false); }
/// <summary> /// Initializes a new instance of the <see cref= "T:WorldWind.BoundingSphere"/> class /// from a set of lat/lon values (degrees) /// </summary> public BoundingSphere(float south, float north, float west, float east, float radius1, float radius2) { // Compute the points in world coordinates const int CornerCount = 8; Vector3[] corners = new Vector3[CornerCount]; float scale = radius2 / radius1; corners[0] = MathEngine.SphericalToCartesian(south, west, radius1); corners[1] = Vector3.Scale(corners[0], scale); corners[2] = MathEngine.SphericalToCartesian(south, east, radius1); corners[3] = Vector3.Scale(corners[2], scale); corners[4] = MathEngine.SphericalToCartesian(north, west, radius1); corners[5] = Vector3.Scale(corners[4], scale); corners[6] = MathEngine.SphericalToCartesian(north, east, radius1); corners[7] = Vector3.Scale(corners[6], scale); //Find the center. In this case, we'll simply average the coordinates. foreach (Vector3 v in corners) { Center += v; } Center.Scale(1 / CornerCount); //Loop through the coordinates and find the maximum distance from the center. This is the radius. foreach (Vector3 v in corners) { float distSq = Vector3.Subtract(v, Center).LengthSq(); if (distSq > Radius) { Radius = distSq; } } Radius = (float)Math.Sqrt(Radius); }
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); }
protected virtual void CreateMesh(GeographicBoundingBox geographicBoundingBox, int meshPointCount, ref CustomVertex.PositionColoredTextured[] vertices, ref short[] indices) { int upperBound = meshPointCount - 1; float scaleFactor = (float)1 / upperBound; double latrange = Math.Abs(geographicBoundingBox.North - geographicBoundingBox.South); double lonrange; if (geographicBoundingBox.West < geographicBoundingBox.East) { lonrange = geographicBoundingBox.East - geographicBoundingBox.West; } else { lonrange = 360.0f + geographicBoundingBox.East - geographicBoundingBox.West; } double layerRadius = m_parentProjectedLayer.World.EquatorialRadius; int opacityColor = System.Drawing.Color.FromArgb( //m_parentProjectedLayer.Opacity, 0, 0, 0).ToArgb(); vertices = new CustomVertex.PositionColoredTextured[meshPointCount * meshPointCount]; for (int i = 0; i < meshPointCount; i++) { for (int j = 0; j < meshPointCount; j++) { double height = 0; if (m_parentProjectedLayer.World.TerrainAccessor != null) { height = m_verticalExaggeration * m_parentProjectedLayer.World.TerrainAccessor.GetElevationAt( (double)geographicBoundingBox.North - scaleFactor * latrange * i, (double)geographicBoundingBox.West + scaleFactor * lonrange * j, (double)upperBound / latrange); } Vector3 pos = MathEngine.SphericalToCartesian( geographicBoundingBox.North - scaleFactor * latrange * i, geographicBoundingBox.West + scaleFactor * lonrange * j, layerRadius + height); vertices[i * meshPointCount + j].X = pos.X; vertices[i * meshPointCount + j].Y = pos.Y; vertices[i * meshPointCount + j].Z = pos.Z; vertices[i * meshPointCount + j].Tu = j * scaleFactor; vertices[i * meshPointCount + j].Tv = i * scaleFactor; vertices[i * meshPointCount + j].Color = opacityColor; } } indices = new short[2 * upperBound * upperBound * 3]; for (int i = 0; i < upperBound; i++) { for (int j = 0; j < upperBound; j++) { indices[(2 * 3 * i * upperBound) + 6 * j] = (short)(i * meshPointCount + j); indices[(2 * 3 * i * upperBound) + 6 * j + 1] = (short)((i + 1) * meshPointCount + j); indices[(2 * 3 * i * upperBound) + 6 * j + 2] = (short)(i * meshPointCount + j + 1); indices[(2 * 3 * i * upperBound) + 6 * j + 3] = (short)(i * meshPointCount + j + 1); indices[(2 * 3 * i * upperBound) + 6 * j + 4] = (short)((i + 1) * meshPointCount + j); indices[(2 * 3 * i * upperBound) + 6 * j + 5] = (short)((i + 1) * meshPointCount + j + 1); } } }
public override void Update(DrawArgs drawArgs) { try { if (!drawArgs.WorldCamera.ViewFrustum.Intersects(this.boundingBox)) { this.Dispose(); return; } if (!this.isLoaded) { this.Load(); } if (this.linePoints != null) { if ((this.lastUpdatedPosition - drawArgs.WorldCamera.Position).LengthSquared() < 10 * 10) // Update if camera moved more than 10 meters { if (Math.Abs(this.verticalExaggeration - World.Settings.VerticalExaggeration) < 0.01) { // Already loaded and up-to-date return; } } } this.verticalExaggeration = World.Settings.VerticalExaggeration; ArrayList renderablePoints = new ArrayList(); Vector3 lastPointProjected = Vector3.Zero; Vector3 currentPointProjected; Vector3 currentPointXyz = Vector3.Zero; Vector3 rc = new Vector3( (float)drawArgs.WorldCamera.ReferenceCenter.X, (float)drawArgs.WorldCamera.ReferenceCenter.Y, (float)drawArgs.WorldCamera.ReferenceCenter.Z ); for (int i = 0; i < this.sphericalCoordinates.Count; i++) { double altitude = 0; if (this._parentWorld.TerrainAccessor != null && drawArgs.WorldCamera.Altitude < 3000000) { altitude = this._terrainAccessor.GetElevationAt(this.sphericalCoordinates[i].X, this.sphericalCoordinates[i].Y, (100.0 / drawArgs.WorldCamera.ViewRange.Degrees)); } currentPointXyz = MathEngine.SphericalToCartesian( this.sphericalCoordinates[i].X, this.sphericalCoordinates[i].Y, this._parentWorld.EquatorialRadius + this.heightAboveSurface + this.verticalExaggeration * altitude); currentPointProjected = drawArgs.WorldCamera.Project(currentPointXyz - rc); float dx = lastPointProjected.X - currentPointProjected.X; float dy = lastPointProjected.Y - currentPointProjected.Y; float distanceSquared = dx * dx + dy * dy; const float minimumPointSpacingSquaredPixels = 2 * 2; if (distanceSquared > minimumPointSpacingSquaredPixels) { renderablePoints.Add(currentPointXyz); lastPointProjected = currentPointProjected; } } // Add the last point if it's not already in there int pointCount = renderablePoints.Count; if (pointCount > 0 && (Vector3)renderablePoints[pointCount - 1] != currentPointXyz) { renderablePoints.Add(currentPointXyz); pointCount++; } CustomVertex.PositionColored[] newLinePoints = new CustomVertex.PositionColored[pointCount]; for (int i = 0; i < pointCount; i++) { currentPointXyz = (Vector3)renderablePoints[i]; newLinePoints[i].X = currentPointXyz.X; newLinePoints[i].Y = currentPointXyz.Y; newLinePoints[i].Z = currentPointXyz.Z; newLinePoints[i].Color = this.lineColor; } this.linePoints = newLinePoints; this.lastUpdatedPosition = drawArgs.WorldCamera.Position; System.Threading.Thread.Sleep(1); } catch { } }
/// <summary> /// Loads visible place names from one file. /// </summary> void UpdateNames(WorldWindPlacenameFile placenameFileDescriptor, ArrayList tempPlacenames, DrawArgs drawArgs) { // TODO: Replace with bounding box frustum intersection test double viewRange = drawArgs.WorldCamera.TrueViewRange.Degrees; double north = drawArgs.WorldCamera.Latitude.Degrees + viewRange; double south = drawArgs.WorldCamera.Latitude.Degrees - viewRange; double west = drawArgs.WorldCamera.Longitude.Degrees - viewRange; double east = drawArgs.WorldCamera.Longitude.Degrees + viewRange; if (placenameFileDescriptor.north < south) { return; } if (placenameFileDescriptor.south > north) { return; } if (placenameFileDescriptor.east < west) { return; } if (placenameFileDescriptor.west > east) { return; } string dataFilePath = Path.Combine(Path.GetDirectoryName(this.m_placenameListFilePath), placenameFileDescriptor.dataFilename); using (BufferedStream dataFileStream = new BufferedStream(File.Open(dataFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))) using (BinaryReader dataFileReader = new BinaryReader(dataFileStream, System.Text.Encoding.ASCII)) { WorldWindPlacenameFile dataFile = new WorldWindPlacenameFile(); dataFile.dataFilename = placenameFileDescriptor.dataFilename; dataFile.north = placenameFileDescriptor.north; dataFile.south = placenameFileDescriptor.south; dataFile.west = placenameFileDescriptor.west; dataFile.east = placenameFileDescriptor.east; int numberPlacenames = dataFileReader.ReadInt32(); tempPlacenames.Capacity = tempPlacenames.Count + numberPlacenames; WorldWindPlacename curPlace = new WorldWindPlacename(); for (int i = 0; i < numberPlacenames; i++) { if (this.m_placeNames != null && this.curPlaceNameIndex < this.m_placeNames.Length) { curPlace = this.m_placeNames[this.curPlaceNameIndex]; } string name = dataFileReader.ReadString(); float lat = dataFileReader.ReadSingle(); float lon = dataFileReader.ReadSingle(); int c = dataFileReader.ReadInt32(); // Not in use, removed for speed // Hashtable metaData = new Hashtable(c); for (int n = 0; n < c; n++) { string key = dataFileReader.ReadString(); string keyData = dataFileReader.ReadString(); // Not in use, removed for speed //metaData.Add(key, keyData); } // for easier hit testing float lonRanged = lon; if (lonRanged < west) { lonRanged += 360; // add a revolution } if (lat > north || lat < south || lonRanged > east || lonRanged < west) { continue; } WorldWindPlacename pn = new WorldWindPlacename(); pn.Lat = lat; pn.Lon = lon; pn.Name = name; // Not in use, removed for speed //pn.metaData = metaData; float elevation = 0; if (this.m_parentWorld.TerrainAccessor != null && drawArgs.WorldCamera.Altitude < 300000) { elevation = (float)this.m_parentWorld.TerrainAccessor.GetElevationAt(lat, lon); } float altitude = (float)(this.m_parentWorld.EquatorialRadius + World.Settings.VerticalExaggeration * this.m_altitude + World.Settings.VerticalExaggeration * elevation); pn.cartesianPoint = MathEngine.SphericalToCartesian(lat, lon, altitude); float distanceSq = Vector3.LengthSq(pn.cartesianPoint - drawArgs.WorldCamera.Position); if (distanceSq > this.m_maximumDistanceSq) { continue; } if (distanceSq < this.m_minimumDistanceSq) { continue; } if (!drawArgs.WorldCamera.ViewFrustum.ContainsPoint(pn.cartesianPoint)) { continue; } tempPlacenames.Add(pn); } } }
private void UpdateTexturedVertices() { if (m_altitudeMode == AltitudeMode.ClampedToGround) { if (m_lineString != null) { m_lineString.Remove = true; m_lineString = null; } m_lineString = new LineString(); m_lineString.Coordinates = Points; m_lineString.Color = LineColor; m_lineString.LineWidth = LineWidth; m_lineString.ParentRenderable = this; this.World.ProjectedVectorRenderer.Add(m_lineString); if (m_wallVertices != null) { m_wallVertices = null; } return; } if (m_extrude || m_altitudeMode == AltitudeMode.RelativeToGround) { m_wallVertices = new CustomVertex.PositionColoredTextured[m_numPoints * 2]; } float textureCoordIncrement = 1.0f / (float)(m_numPoints - 1); m_verticalExaggeration = World.Settings.VerticalExaggeration; int vertexColor = m_polygonColor.ToArgb(); m_topVertices = new CustomVertex.PositionColored[m_numPoints]; for (int i = 0; i < m_numPoints; i++) { double terrainHeight = 0; if (m_altitudeMode == AltitudeMode.RelativeToGround) { if (World.TerrainAccessor != null) { terrainHeight = World.TerrainAccessor.GetElevationAt( m_points[i].Y, m_points[i].X, (100.0 / DrawArgs.Camera.ViewRange.Degrees) ); } } Vector3 xyzVertex = MathEngine.SphericalToCartesian( m_points[i].Y, m_points[i].X, m_verticalExaggeration * (m_distanceAboveSurface + terrainHeight + m_points[i].Z) + World.EquatorialRadius ); m_topVertices[i].X = xyzVertex.X; m_topVertices[i].Y = xyzVertex.Y; m_topVertices[i].Z = xyzVertex.Z; m_topVertices[i].Color = m_lineColor.ToArgb(); if (m_extrude || m_altitudeMode == AltitudeMode.RelativeToGround) { m_wallVertices[2 * i].X = xyzVertex.X; m_wallVertices[2 * i].Y = xyzVertex.Y; m_wallVertices[2 * i].Z = xyzVertex.Z; m_wallVertices[2 * i].Color = vertexColor; m_wallVertices[2 * i].Tu = i * textureCoordIncrement; m_wallVertices[2 * i].Tv = 1.0f; xyzVertex = MathEngine.SphericalToCartesian( m_points[i].Y, m_points[i].X, m_verticalExaggeration * (m_distanceAboveSurface + terrainHeight) + World.EquatorialRadius ); m_wallVertices[2 * i + 1].X = xyzVertex.X; m_wallVertices[2 * i + 1].Y = xyzVertex.Y; m_wallVertices[2 * i + 1].Z = xyzVertex.Z; m_wallVertices[2 * i + 1].Color = vertexColor; m_wallVertices[2 * i + 1].Tu = i * textureCoordIncrement; m_wallVertices[2 * i + 1].Tv = 0.0f; } } }
private void CreateMesh( double north, double south, double west, double east, int samples, string displacementFile, ref CustomVertex.PositionTextured[] vertices, ref short[] indices) { int upperBound = samples - 1; float scaleFactor = (float)1 / upperBound; double latrange = Math.Abs(north - south); double lonrange; if (west < east) { lonrange = east - west; } else { lonrange = 360.0f + east - west; } System.Drawing.Bitmap heightMap = null; try { heightMap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(displacementFile); } catch {} vertices = new CustomVertex.PositionTextured[samples * samples]; for (int i = 0; i < samples; i++) { for (int j = 0; j < samples; j++) { double height = m_cloudBaseAltitude * World.Settings.VerticalExaggeration; if (heightMap != null) { double percentX = (double)j / (double)upperBound; double percentY = (double)i / (double)upperBound; if (percentX > 1) { percentX = 1; } if (percentY > 1) { percentY = 1; } int x = (int)(percentX * (heightMap.Width - 1)); int y = (int)(percentY * (heightMap.Height - 1)); height += m_displacementMultiplier * heightMap.GetPixel(x, y).R; } Vector3 pos = MathEngine.SphericalToCartesian( north - scaleFactor * latrange * i, west + scaleFactor * lonrange * j, this.World.EquatorialRadius + height); vertices[i * samples + j].X = pos.X; vertices[i * samples + j].Y = pos.Y; vertices[i * samples + j].Z = pos.Z; vertices[i * samples + j].Tu = j * scaleFactor; vertices[i * samples + j].Tv = i * scaleFactor; } } indices = new short[2 * upperBound * upperBound * 3]; for (int i = 0; i < upperBound; i++) { for (int j = 0; j < upperBound; j++) { indices[(2 * 3 * i * upperBound) + 6 * j] = (short)(i * samples + j); indices[(2 * 3 * i * upperBound) + 6 * j + 1] = (short)((i + 1) * samples + j); indices[(2 * 3 * i * upperBound) + 6 * j + 2] = (short)(i * samples + j + 1); indices[(2 * 3 * i * upperBound) + 6 * j + 3] = (short)(i * samples + j + 1); indices[(2 * 3 * i * upperBound) + 6 * j + 4] = (short)((i + 1) * samples + j); indices[(2 * 3 * i * upperBound) + 6 * j + 5] = (short)((i + 1) * samples + j + 1); } } if (heightMap != null) { heightMap.Dispose(); } }
/// <summary> /// Render the grid lines /// </summary> public override void Render(DrawArgs drawArgs) { if (!World.Settings.showLatLonLines) { return; } this.ComputeGridValues(drawArgs); float offsetDegrees = (float)drawArgs.WorldCamera.TrueViewRange.Degrees / 6; drawArgs.device.SetRenderState(RenderState.ZEnable, this.useZBuffer); drawArgs.device.SetTextureStageState(0, TextureStage.ColorOperation, TextureOperation.Disable); drawArgs.device.VertexFormat = CustomVertex.PositionColored.Format; drawArgs.device.SetTransform(TransformState.World, Matrix.Translation( (float)-drawArgs.WorldCamera.ReferenceCenter.X, (float)-drawArgs.WorldCamera.ReferenceCenter.Y, (float)-drawArgs.WorldCamera.ReferenceCenter.Z )); Vector3 referenceCenter = new Vector3( (float)drawArgs.WorldCamera.ReferenceCenter.X, (float)drawArgs.WorldCamera.ReferenceCenter.Y, (float)drawArgs.WorldCamera.ReferenceCenter.Z); // Turn off light if (World.Settings.EnableSunShading) { drawArgs.device.SetRenderState(RenderState.Lighting, false); } // Draw longitudes for (float longitude = this.MinVisibleLongitude; longitude < this.MaxVisibleLongitude; longitude += this.LongitudeInterval) { // Draw longitude lines int vertexIndex = 0; for (float latitude = this.MinVisibleLatitude; latitude <= this.MaxVisibleLatitude; latitude += this.LatitudeInterval) { Vector3 pointXyz = MathEngine.SphericalToCartesian(latitude, longitude, this.radius); this.lineVertices[vertexIndex].X = pointXyz.X; this.lineVertices[vertexIndex].Y = pointXyz.Y; this.lineVertices[vertexIndex].Z = pointXyz.Z; this.lineVertices[vertexIndex].Color = World.Settings.latLonLinesColor; vertexIndex++; } drawArgs.device.DrawUserPrimitives(PrimitiveType.LineStrip, this.LatitudePointCount - 1, this.lineVertices); // Draw longitude label float lat = (float)(drawArgs.WorldCamera.Latitude).Degrees; if (lat > 70) { lat = 70; } Vector3 v = MathEngine.SphericalToCartesian(lat, (float)longitude, this.radius); if (drawArgs.WorldCamera.ViewFrustum.ContainsPoint(v)) { // Make sure longitude is in -180 .. 180 range int longitudeRanged = (int)longitude; if (longitudeRanged <= -180) { longitudeRanged += 360; } else if (longitudeRanged > 180) { longitudeRanged -= 360; } string s = Math.Abs(longitudeRanged).ToString(); if (longitudeRanged < 0) { s += "W"; } else if (longitudeRanged > 0 && longitudeRanged < 180) { s += "E"; } v = drawArgs.WorldCamera.Project(v - referenceCenter); System.Drawing.Rectangle rect = new System.Drawing.Rectangle((int)v.X + 2, (int)v.Y, 10, 10); drawArgs.defaultDrawingFont.DrawText(null, s, rect.Left, rect.Top, World.Settings.latLonLinesColor); } } // Draw latitudes for (float latitude = this.MinVisibleLatitude; latitude <= this.MaxVisibleLatitude; latitude += this.LatitudeInterval) { // Draw latitude label float longitude = (float)(drawArgs.WorldCamera.Longitude).Degrees + offsetDegrees; Vector3 v = MathEngine.SphericalToCartesian(latitude, longitude, this.radius); if (drawArgs.WorldCamera.ViewFrustum.ContainsPoint(v)) { v = drawArgs.WorldCamera.Project(v - referenceCenter); float latLabel = latitude; if (latLabel > 90) { latLabel = 180 - latLabel; } else if (latLabel < -90) { latLabel = -180 - latLabel; } string s = ((int)Math.Abs(latLabel)).ToString(); if (latLabel > 0) { s += "N"; } else if (latLabel < 0) { s += "S"; } System.Drawing.Rectangle rect = new System.Drawing.Rectangle((int)v.X, (int)v.Y, 10, 10); drawArgs.defaultDrawingFont.DrawText(null, s, rect.Left, rect.Top, World.Settings.latLonLinesColor); } // Draw latitude line int vertexIndex = 0; for (longitude = this.MinVisibleLongitude; longitude <= this.MaxVisibleLongitude; longitude += this.LongitudeInterval) { Vector3 pointXyz = MathEngine.SphericalToCartesian(latitude, longitude, this.radius); this.lineVertices[vertexIndex].X = pointXyz.X; this.lineVertices[vertexIndex].Y = pointXyz.Y; this.lineVertices[vertexIndex].Z = pointXyz.Z; if (latitude == 0) { this.lineVertices[vertexIndex].Color = World.Settings.equatorLineColor; } else { this.lineVertices[vertexIndex].Color = World.Settings.latLonLinesColor; } vertexIndex++; } drawArgs.device.DrawUserPrimitives(PrimitiveType.LineStrip, this.LongitudePointCount - 1, this.lineVertices); } if (World.Settings.showTropicLines && this.IsEarth) { this.RenderTropicLines(drawArgs); } // Restore state drawArgs.device.SetTransform(TransformState.World, drawArgs.WorldCamera.WorldMatrix); if (!this.useZBuffer) { // Reset Z buffer setting drawArgs.device.SetRenderState(RenderState.ZEnable, true); } if (World.Settings.EnableSunShading) { drawArgs.device.SetRenderState(RenderState.Lighting, true); } }
/// <summary> /// Recalculates the grid bounds + interval values /// </summary> public void ComputeGridValues(DrawArgs drawArgs) { double vr = drawArgs.WorldCamera.TrueViewRange.Radians; // Compensate for closer grid towards poles vr *= 1 + Math.Abs(Math.Sin(drawArgs.WorldCamera.Latitude.Radians)); if (vr < 0.17) { this.LatitudeInterval = 1; } else if (vr < 0.6) { this.LatitudeInterval = 2; } else if (vr < 1.0) { this.LatitudeInterval = 5; } else { this.LatitudeInterval = 10; } this.LongitudeInterval = this.LatitudeInterval; if (drawArgs.WorldCamera.ViewFrustum.ContainsPoint(MathEngine.SphericalToCartesian(90, 0, this.radius)) || drawArgs.WorldCamera.ViewFrustum.ContainsPoint(MathEngine.SphericalToCartesian(-90, 0, this.radius))) { // Pole visible, 10 degree longitude spacing forced this.LongitudeInterval = 10; } this.MinVisibleLongitude = this.LongitudeInterval >= 10 ? -180 : (int)drawArgs.WorldCamera.Longitude.Degrees / this.LongitudeInterval * this.LongitudeInterval - 18 * this.LongitudeInterval; this.MaxVisibleLongitude = this.LongitudeInterval >= 10 ? 180 : (int)drawArgs.WorldCamera.Longitude.Degrees / this.LongitudeInterval * this.LongitudeInterval + 18 * this.LongitudeInterval; this.MinVisibleLatitude = (int)drawArgs.WorldCamera.Latitude.Degrees / this.LatitudeInterval * this.LatitudeInterval - 9 * this.LatitudeInterval; this.MaxVisibleLatitude = (int)drawArgs.WorldCamera.Latitude.Degrees / this.LatitudeInterval * this.LatitudeInterval + 9 * this.LatitudeInterval; if (this.MaxVisibleLatitude - this.MinVisibleLatitude >= 180 || this.LongitudeInterval == 10) { this.MinVisibleLatitude = -90; this.MaxVisibleLatitude = 90; } this.LongitudePointCount = (this.MaxVisibleLongitude - this.MinVisibleLongitude) / this.LongitudeInterval + 1; this.LatitudePointCount = (this.MaxVisibleLatitude - this.MinVisibleLatitude) / this.LatitudeInterval + 1; int vertexPointCount = Math.Max(this.LatitudePointCount, this.LongitudePointCount); if (this.lineVertices == null || vertexPointCount > this.lineVertices.Length) { this.lineVertices = new CustomVertex.PositionColored[Math.Max(this.LatitudePointCount, this.LongitudePointCount)]; } this.radius = this.WorldRadius; if (drawArgs.WorldCamera.Altitude < 0.10f * this.WorldRadius) { this.useZBuffer = false; } else { this.useZBuffer = true; double bRadius = this.WorldRadius * 1.01f; double nRadius = this.WorldRadius + 0.015f * drawArgs.WorldCamera.Altitude; this.radius = Math.Min(nRadius, bRadius); } }
public void AddPointToPath(float latitude, float longitude, bool terrainMapped, float heightAboveSurface) { /* if(terrainMapped) * { * heightAboveSurface += this.terrainManager.GetHeightAt(latitude, longitude) * this.verticalExaggeration; * }*/ //Always add first coordinate Vector3[] newPoints = null; if (this.sphericalCoordinates.Length > 0) { float startLatitude = this.sphericalCoordinates[this.sphericalCoordinates.Length - 1].X; float startLongitude = this.sphericalCoordinates[this.sphericalCoordinates.Length - 1].Y; newPoints = this.BuildSegment(Angle.FromDegrees(startLatitude), Angle.FromDegrees(startLongitude), Angle.FromDegrees(latitude), Angle.FromDegrees(longitude), heightAboveSurface); } Vector3[] newCoords = new Vector3[this.sphericalCoordinates.Length + 1]; this.sphericalCoordinates.CopyTo(newCoords, 0); newCoords[newCoords.Length - 1].X = latitude; newCoords[newCoords.Length - 1].Y = longitude; newCoords[newCoords.Length - 1].Z = heightAboveSurface; this.sphericalCoordinates = newCoords; //TODO: HACK work fix this if (newPoints == null) { CustomVertex.PositionColored[] newLine = new CustomVertex.PositionColored[this.linePoints.Length + 1]; this.linePoints.CopyTo(newLine, 0); Vector3 newPoint = MathEngine.SphericalToCartesian(latitude, longitude, this._parentWorld.EquatorialRadius + this.verticalExaggeration * heightAboveSurface); newLine[newLine.Length - 1] = new PositionColored(newPoint.X, newPoint.Y, newPoint.Z, this.lineColor); //Need to build path if points are spread too far apart lock (this.linePoints.SyncRoot) { this.linePoints = newLine; } } else { foreach (Vector3 newPoint in newPoints) { CustomVertex.PositionColored[] newLine = new CustomVertex.PositionColored[this.linePoints.Length + 1]; this.linePoints.CopyTo(newLine, 0); //Vector3 newPoint = MathEngine.SphericalToCartesian(latitude, longitude, this._parentWorld.EquatorialRadius + this.verticalExaggeration * heightAboveSurface ); newLine[newLine.Length - 1] = new PositionColored(newPoint.X, newPoint.Y, newPoint.Z, this.lineColor); //Need to build path if points are spread too far apart lock (this.linePoints.SyncRoot) { this.linePoints = newLine; } } } if (this.linePoints.Length == 1) { this.north = latitude; this.south = latitude; this.west = longitude; this.east = longitude; } else { if (latitude > this.north) { this.north = latitude; } if (latitude < this.south) { this.south = latitude; } if (longitude < this.west) { this.west = longitude; } if (longitude > this.east) { this.east = longitude; } } }
/// <summary> /// Initializes a new instance of the <see cref= "T:WorldWind.MeshLayer"/> class. /// </summary> /// <param name="name"></param> /// <param name="latitude"></param> /// <param name="longitude"></param> /// <param name="layerRadius"></param> /// <param name="scaleFactor"></param> /// <param name="meshFilePath"></param> /// <param name="orientation"></param> public MeshLayer(string name, float latitude, float longitude, float layerRadius, float scaleFactor, string meshFilePath, Quaternion orientation) : base(name, MathEngine.SphericalToCartesian(latitude, longitude, layerRadius), orientation) { this.meshFilePath = meshFilePath; this.lat = latitude; this.lon = longitude; this.layerRadius = layerRadius; this.scaleFactor = scaleFactor; }
/// <summary> /// Loads visible place names from one file. /// If cache files are appropriately named only files in view are hit /// </summary> void UpdateNames(WorldWindWFSPlacenameFile placenameFileDescriptor, ArrayList tempPlacenames, DrawArgs drawArgs) { // TODO: Replace with bounding box frustum intersection test double viewRange = drawArgs.WorldCamera.TrueViewRange.Degrees; double north = drawArgs.WorldCamera.Latitude.Degrees + viewRange; double south = drawArgs.WorldCamera.Latitude.Degrees - viewRange; double west = drawArgs.WorldCamera.Longitude.Degrees - viewRange; double east = drawArgs.WorldCamera.Longitude.Degrees + viewRange; //TODO: Implement GML parsing if (placenameFileDescriptor.north < south) { return; } if (placenameFileDescriptor.south > north) { return; } if (placenameFileDescriptor.east < west) { return; } if (placenameFileDescriptor.west > east) { return; } WorldWindPlacename[] tilednames = placenameFileDescriptor.PlaceNames; if (tilednames == null) { return; } tempPlacenames.Capacity = tempPlacenames.Count + tilednames.Length; WorldWindPlacename curPlace = new WorldWindPlacename(); for (int i = 0; i < tilednames.Length; i++) { if (this.m_placeNames != null && this.curPlaceNameIndex < this.m_placeNames.Length) { curPlace = this.m_placeNames[this.curPlaceNameIndex]; } WorldWindPlacename pn = tilednames[i]; float lat = pn.Lat; float lon = pn.Lon; // for easier hit testing float lonRanged = lon; if (lonRanged < west) { lonRanged += 360; // add a revolution } if (lat > north || lat < south || lonRanged > east || lonRanged < west) { continue; } float elevation = 0; if (this.m_parentWorld.TerrainAccessor != null && drawArgs.WorldCamera.Altitude < 300000) { elevation = (float)this.m_parentWorld.TerrainAccessor.GetElevationAt(lat, lon); } float altitude = (float)(this.m_parentWorld.EquatorialRadius + World.Settings.VerticalExaggeration * this.m_altitude + World.Settings.VerticalExaggeration * elevation); pn.cartesianPoint = MathEngine.SphericalToCartesian(lat, lon, altitude); float distanceSq = Vector3.LengthSq(pn.cartesianPoint - drawArgs.WorldCamera.Position); if (distanceSq > this.m_maximumDistanceSq) { continue; } if (distanceSq < this.m_minimumDistanceSq) { continue; } if (!drawArgs.WorldCamera.ViewFrustum.ContainsPoint(pn.cartesianPoint)) { continue; } tempPlacenames.Add(pn); } }
public override void Render(DrawArgs drawArgs) { if (!this.isInitialized) { return; } if (this.imageLayer != null && this.imageLayer.isInitialized && this.LoadImage) { if (!this.imageLayer.DisableZBuffer) { this.imageLayer.DisableZBuffer = true; } this.imageLayer.Render(drawArgs); drawArgs.defaultDrawingFont.DrawText(null, this.caption, new Rectangle(10, drawArgs.screenHeight - 50, drawArgs.screenWidth - 10, 50), FontDrawFlags.NoClip | FontDrawFlags.WordBreak, bottomLeftTextColor); return; } Vector3 centerPoint = MathEngine.SphericalToCartesian(0.5f * (this.north + this.south), 0.5f * (this.west + this.east), this.layerRadius); if (!drawArgs.WorldCamera.ViewFrustum.ContainsPoint(centerPoint)) { return; } Vector3 translationVector = new Vector3( (float)(centerPoint.X - drawArgs.WorldCamera.ReferenceCenter.X), (float)(centerPoint.Y - drawArgs.WorldCamera.ReferenceCenter.Y), (float)(centerPoint.Z - drawArgs.WorldCamera.ReferenceCenter.Z)); // Find closest mouse-over icon Vector3 projectedPoint = drawArgs.WorldCamera.Project(translationVector); // This value indicates the non-zoomed scale factor for icons const float baseScaling = 0.5f; // This value indicates the (maximum) added scale factor for when the mouse is over the icon float zoomScaling = 0.5f; // This value determines when the icon will start to zoom float selectionRadius = 0.5f * this.iconSize; float dx = DrawArgs.LastMousePosition.X - projectedPoint.X; float dy = DrawArgs.LastMousePosition.Y - projectedPoint.Y; float dr = (float)Math.Sqrt(dx * dx + dy * dy); bool renderDescription = false; if (dr > selectionRadius) { zoomScaling = 0; } else { zoomScaling *= (selectionRadius - dr) / selectionRadius; renderDescription = true; DrawArgs.MouseCursor = CursorType.Hand; } float scaleFactor = baseScaling + zoomScaling; int halfIconWidth = (int)(0.5f * this.iconSize * scaleFactor); int halfIconHeight = (int)(0.5f * this.iconSize * scaleFactor); if (this.downloadState != DownloadState.Pending) { halfIconWidth = (int)(0.5f * this.iconSize); halfIconHeight = (int)(0.5f * this.iconSize); } float scaleWidth = (float)2.0f * halfIconWidth / this.spriteSize.Width; float scaleHeight = (float)2.0f * halfIconHeight / this.spriteSize.Height; this.sprite.Begin(SpriteFlags.AlphaBlend); this.sprite.Transform = Matrix.Transformation2D(new Vector2(0.0f, 0.0f), 0.0f, new Vector2(scaleWidth, scaleHeight), new Vector2(0, 0), 0.0f, new Vector2(projectedPoint.X, projectedPoint.Y)); this.sprite.Draw(this.iconTexture, this.spriteSize, new Vector3(1.32f * this.iconSize, 1.32f * this.iconSize, 0), new Vector3(0, 0, 0), Color.White); this.sprite.End(); if (this.caption != null && renderDescription) { drawArgs.defaultDrawingFont.DrawText(null, this.caption, new Rectangle((int)projectedPoint.X + halfIconWidth + 5, (int)projectedPoint.Y - halfIconHeight, drawArgs.screenWidth, drawArgs.screenHeight), FontDrawFlags.WordBreak | FontDrawFlags.NoClip, Color.White.ToArgb()); } if (this.downloadState != DownloadState.Pending || this.IsTextureAvailable) { int progressColor = progressDefaultColor; if (this.IsTextureAvailable) { progressColor = progressColorLoading; } else if (this.downloadState == DownloadState.Converting) { progressColor = progressColorConversion; if (DateTime.Now.Millisecond < 500) { return; } } this.progressBarOutline[0].X = projectedPoint.X - halfIconWidth; this.progressBarOutline[0].Y = projectedPoint.Y + halfIconHeight + 1; this.progressBarOutline[0].Color = progressColor; this.progressBarOutline[1].X = projectedPoint.X + halfIconWidth; this.progressBarOutline[1].Y = projectedPoint.Y + halfIconHeight + 1; this.progressBarOutline[1].Color = progressColor; this.progressBarOutline[2].X = projectedPoint.X + halfIconWidth; this.progressBarOutline[2].Y = projectedPoint.Y + halfIconHeight + 3; this.progressBarOutline[2].Color = progressColor; this.progressBarOutline[3].X = projectedPoint.X - halfIconWidth; this.progressBarOutline[3].Y = projectedPoint.Y + halfIconHeight + 3; this.progressBarOutline[3].Color = progressColor; this.progressBarOutline[4].X = projectedPoint.X - halfIconWidth; this.progressBarOutline[4].Y = projectedPoint.Y + halfIconHeight + 1; this.progressBarOutline[4].Color = progressColor; drawArgs.device.VertexFormat = CustomVertex.TransformedColored.Format; drawArgs.device.SetTextureStageState(0, TextureStage.ColorOperation, TextureOperation.Disable); drawArgs.device.DrawUserPrimitives(PrimitiveType.LineStrip, 4, this.progressBarOutline); int barlength = (int)(this.downloadProgress * 2 * halfIconWidth); this.progressBar[0].X = projectedPoint.X - halfIconWidth; this.progressBar[0].Y = projectedPoint.Y + halfIconHeight + 1; this.progressBar[0].Color = progressColor; this.progressBar[1].X = projectedPoint.X - halfIconWidth; this.progressBar[1].Y = projectedPoint.Y + halfIconHeight + 3; this.progressBar[1].Color = progressColor; this.progressBar[2].X = projectedPoint.X - halfIconWidth + barlength; this.progressBar[2].Y = projectedPoint.Y + halfIconHeight + 1; this.progressBar[2].Color = progressColor; this.progressBar[3].X = projectedPoint.X - halfIconWidth + barlength; this.progressBar[3].Y = projectedPoint.Y + halfIconHeight + 3; this.progressBar[3].Color = progressColor; drawArgs.device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, this.progressBar); } }