internal static void Init(Projection proj, TerrainAccessor terrainAccessor, double layerRadius) { _proj = proj; _terrainAccessor = terrainAccessor; _layerRadius = layerRadius; }
/// <summary> /// Layer initialization code /// </summary> public override void Initialize(DrawArgs drawArgs) { try { if (this.isInitialized == true) { return; } pushpinsprite = new Sprite(drawArgs.device); string spritePath = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\Plugins\\VirtualEarth\\VirtualEarthPushPin.png"; if (File.Exists(spritePath) == false) { Utility.Log.Write(new Exception("spritePath not found " + spritePath)); } earthRadius = parentApplication.CurrentWorld.EquatorialRadius; earthCircum = earthRadius * 2.0 * Math.PI; //40075016.685578488 earthHalfCirc = earthCircum / 2; //20037508. string[] projectionParameters = new string[] { "proj=merc", "ellps=sphere", "a=" + earthRadius.ToString(CultureInfo.InvariantCulture), "es=0.0", "no.defs" }; proj = new Projection(projectionParameters); //static VeTile.Init(this.proj, parentApplication.CurrentWorld.TerrainAccessor, parentApplication.CurrentWorld.EquatorialRadius); prevVe = World.Settings.VerticalExaggeration; this.isInitialized = true; } catch (Exception ex) { Utility.Log.Write(ex); throw; } }
/// <summary> /// Builds a mesh using a projection (with terrain if requested) /// </summary> protected virtual void CreateProjectedMesh(Projection proj, bool bTerrain) { int baseIndex; UV geo; double sinLat, cosLat, sinLon, cosLon, height, latRange = North - South; double layerRadius = (double)quadTileSet.LayerRadius; double scaleFactor = 1.0 / (double)vertexCount; int thisVertexCount = vertexCount / 2 + (vertexCount % 2); int thisVertexCountPlus1 = thisVertexCount + 1; const double Degrees2Radians = Math.PI / 180.0; int totalVertexCount = thisVertexCountPlus1 * thisVertexCountPlus1; northWestVertices = new CustomVertex.PositionNormalTextured[totalVertexCount]; southWestVertices = new CustomVertex.PositionNormalTextured[totalVertexCount]; northEastVertices = new CustomVertex.PositionNormalTextured[totalVertexCount]; southEastVertices = new CustomVertex.PositionNormalTextured[totalVertexCount]; double uStep = (UR.U - UL.U) * scaleFactor; double vStep = (UL.V - LL.V) * scaleFactor; // figure out latrange (for terrain detail) if (bTerrain) { UV geoUL = proj.Inverse(UL); UV geoLR = proj.Inverse(LR); latRange = (geoUL.V - geoLR.V) * 180 / Math.PI; } baseIndex = 0; UV curUnprojected = new UV(UL.U, UL.V); for (int i = 0; i < thisVertexCountPlus1; i++) { for (int j = 0; j < thisVertexCountPlus1; j++) { geo = proj.Inverse(curUnprojected); sinLat = Math.Sin(geo.V); sinLon = Math.Sin(geo.U); cosLat = Math.Cos(geo.V); cosLon = Math.Cos(geo.U); height = layerRadius; if (bTerrain) { // Radians -> Degrees geo.U /= Degrees2Radians; geo.V /= Degrees2Radians; height += verticalExaggeration * quadTileSet.World.TerrainAccessor.GetElevationAt(geo.V, geo.U, Math.Abs(vertexCount / latRange)); } northWestVertices[baseIndex].X = (float)(height * cosLat * cosLon - localOrigin.X); northWestVertices[baseIndex].Y = (float)(height * cosLat * sinLon - localOrigin.Y); northWestVertices[baseIndex].Z = (float)(height * sinLat - localOrigin.Z); northWestVertices[baseIndex].Tu = (float)(j * scaleFactor); northWestVertices[baseIndex].Tv = (float)(i * scaleFactor); northWestVertices[baseIndex].Normal = new Vector3(northWestVertices[baseIndex].X + (float)localOrigin.X, northWestVertices[baseIndex].Y + (float)localOrigin.Y, northWestVertices[baseIndex].Z + (float)localOrigin.Z); northWestVertices[baseIndex].Normal.Normalize(); baseIndex += 1; curUnprojected.U += uStep; } curUnprojected.U = UL.U; curUnprojected.V -= vStep; } baseIndex = 0; curUnprojected = new UV(UL.U, UL.V - (UL.V - LL.V) / 2.0); for (int i = 0; i < thisVertexCountPlus1; i++) { for (int j = 0; j < thisVertexCountPlus1; j++) { geo = proj.Inverse(curUnprojected); sinLat = Math.Sin(geo.V); sinLon = Math.Sin(geo.U); cosLat = Math.Cos(geo.V); cosLon = Math.Cos(geo.U); height = layerRadius; if (bTerrain) { // Radians -> Degrees geo.U /= Degrees2Radians; geo.V /= Degrees2Radians; height += verticalExaggeration * quadTileSet.World.TerrainAccessor.GetElevationAt(geo.V, geo.U, Math.Abs(vertexCount / latRange)); } southWestVertices[baseIndex].X = (float)(height * cosLat * cosLon - localOrigin.X); southWestVertices[baseIndex].Y = (float)(height * cosLat * sinLon - localOrigin.Y); southWestVertices[baseIndex].Z = (float)(height * sinLat - localOrigin.Z); southWestVertices[baseIndex].Tu = (float)(j * scaleFactor); southWestVertices[baseIndex].Tv = (float)((i + thisVertexCount) * scaleFactor); southWestVertices[baseIndex].Normal = new Vector3(southWestVertices[baseIndex].X + (float)localOrigin.X, southWestVertices[baseIndex].Y + (float)localOrigin.Y, southWestVertices[baseIndex].Z + (float)localOrigin.Z); southWestVertices[baseIndex].Normal.Normalize(); baseIndex += 1; curUnprojected.U += uStep; } curUnprojected.U = UL.U; curUnprojected.V -= vStep; } baseIndex = 0; curUnprojected = new UV(UL.U + (UR.U - UL.U) / 2.0, UL.V); for (int i = 0; i < thisVertexCountPlus1; i++) { for (int j = 0; j < thisVertexCountPlus1; j++) { geo = proj.Inverse(curUnprojected); sinLat = Math.Sin(geo.V); sinLon = Math.Sin(geo.U); cosLat = Math.Cos(geo.V); cosLon = Math.Cos(geo.U); height = layerRadius; if (bTerrain) { // Radians -> Degrees geo.U /= Degrees2Radians; geo.V /= Degrees2Radians; height += verticalExaggeration * quadTileSet.World.TerrainAccessor.GetElevationAt(geo.V, geo.U, Math.Abs(vertexCount / latRange)); } northEastVertices[baseIndex].X = (float)(height * cosLat * cosLon - localOrigin.X); northEastVertices[baseIndex].Y = (float)(height * cosLat * sinLon - localOrigin.Y); northEastVertices[baseIndex].Z = (float)(height * sinLat - localOrigin.Z); northEastVertices[baseIndex].Tu = (float)((j + thisVertexCount) * scaleFactor); northEastVertices[baseIndex].Tv = (float)(i * scaleFactor); northEastVertices[baseIndex].Normal = new Vector3(northEastVertices[baseIndex].X + (float)localOrigin.X, northEastVertices[baseIndex].Y + (float)localOrigin.Y, northEastVertices[baseIndex].Z + (float)localOrigin.Z); northEastVertices[baseIndex].Normal.Normalize(); baseIndex += 1; curUnprojected.U += uStep; } curUnprojected.U = UL.U + (UR.U - UL.U) / 2.0; curUnprojected.V -= vStep; } baseIndex = 0; curUnprojected = new UV(UL.U + (UR.U - UL.U) / 2.0, UL.V - (UL.V - LL.V) / 2.0); for (int i = 0; i < thisVertexCountPlus1; i++) { for (int j = 0; j < thisVertexCountPlus1; j++) { geo = proj.Inverse(curUnprojected); sinLat = Math.Sin(geo.V); sinLon = Math.Sin(geo.U); cosLat = Math.Cos(geo.V); cosLon = Math.Cos(geo.U); height = layerRadius; if (bTerrain) { // Radians -> Degrees geo.U /= Degrees2Radians; geo.V /= Degrees2Radians; height += verticalExaggeration * quadTileSet.World.TerrainAccessor.GetElevationAt(geo.V, geo.U, Math.Abs(vertexCount / latRange)); } southEastVertices[baseIndex].X = (float)(height * cosLat * cosLon - localOrigin.X); southEastVertices[baseIndex].Y = (float)(height * cosLat * sinLon - localOrigin.Y); southEastVertices[baseIndex].Z = (float)(height * sinLat - localOrigin.Z); southEastVertices[baseIndex].Tu = (float)((j + thisVertexCount) * scaleFactor); southEastVertices[baseIndex].Tv = (float)((i + thisVertexCount) * scaleFactor); southEastVertices[baseIndex].Normal = new Vector3(southEastVertices[baseIndex].X + (float)localOrigin.X, southEastVertices[baseIndex].Y + (float)localOrigin.Y, southEastVertices[baseIndex].Z + (float)localOrigin.Z); southEastVertices[baseIndex].Normal.Normalize(); baseIndex += 1; curUnprojected.U += uStep; } curUnprojected.U = UL.U + (UR.U - UL.U) / 2.0; curUnprojected.V -= vStep; } vertexIndexes = new short[2 * thisVertexCount * thisVertexCount * 3]; for (int i = 0; i < thisVertexCount; i++) { baseIndex = (2 * 3 * i * thisVertexCount); for (int j = 0; j < thisVertexCount; j++) { vertexIndexes[baseIndex] = (short)(i * thisVertexCountPlus1 + j); vertexIndexes[baseIndex + 1] = (short)((i + 1) * thisVertexCountPlus1 + j); vertexIndexes[baseIndex + 2] = (short)(i * thisVertexCountPlus1 + j + 1); vertexIndexes[baseIndex + 3] = (short)(i * thisVertexCountPlus1 + j + 1); vertexIndexes[baseIndex + 4] = (short)((i + 1) * thisVertexCountPlus1 + j); vertexIndexes[baseIndex + 5] = (short)((i + 1) * thisVertexCountPlus1 + j + 1); baseIndex += 6; } } // JBTODO: Should we normalize here for elevated mesh? }