Beispiel #1
0
 /// <summary>
 /// Inverse (Go from lat/lon to specified projection)
 /// </summary>
 /// <param name="uv"></param>
 /// <returns></returns>
 public UV Inverse(UV uv)
 {
     return pj_inv(uv, projPJ);
 }
Beispiel #2
0
 static extern UV pj_inv(UV uv, IntPtr projPJ);
Beispiel #3
0
 /// <summary>
 /// Forward (Go from specified projection to lat/lon)
 /// </summary>
 /// <param name="uv"></param>
 /// <returns></returns>
 public UV Forward(UV uv)
 {
     return pj_fwd(uv, projPJ);
 }
Beispiel #4
0
 static extern UV pj_fwd(UV uv, IntPtr projPJ);
Beispiel #5
0
 /// <summary>
 /// This can be used by mesh calculation to calculate projected meshes for tiles
 /// </summary>
 internal virtual void GetProjectionCorners(IGeoSpatialDownloadTile tile, out UV ul, out UV ur, out UV ll, out UV lr)
 {
     // For normal quad tiles this is equal to the geographic coordinates
     ul = new UV(tile.West, tile.North);
     ur = new UV(tile.East, tile.North);
     ll = new UV(tile.West, tile.South);
     lr = new UV(tile.East, tile.South);
 }
Beispiel #6
0
        /// <summary>
        /// Update layer (called from worker thread)
        /// </summary>
        public override void Update(DrawArgs drawArgs)
        {
            try
            {
                if (this.isOn == false)
                {
                    return;
                }

                //NOTE for some reason Initialize is not getting called from the Plugin Menu Load/Unload
                //it does get called when the plugin loads from Startup
                //not sure what is going on, so i'll just call it manually
                if (this.isInitialized == false)
                {
                    this.Initialize(drawArgs);
                    return;
                }

                //get lat, lon
                double lat = drawArgs.WorldCamera.Latitude.Degrees;
                double lon = drawArgs.WorldCamera.Longitude.Degrees;
                double tilt = drawArgs.WorldCamera.Tilt.Degrees;
                //could go off distance, but this changes when view angle changes
                //Angle fov = drawArgs.WorldCamera.Fov; //stays at 45 degress
                //Angle viewRange = drawArgs.WorldCamera.ViewRange; //off of distance, same as TVR but changes when view angle changes
                Angle tvr = drawArgs.WorldCamera.TrueViewRange; //off of altitude
                //smallest altitude = 100m
                //tvr = .00179663198575926
                //start altitude = 12756273m
                //tvr = 180

                //WW _levelZeroTileSizeDegrees
                //180 90 45 22.5 11.25 5.625 2.8125 1.40625 .703125 .3515625 .17578125 .087890625 0.0439453125 0.02197265625 0.010986328125 0.0054931640625
                int zoomLevel = GetZoomLevelByTrueViewRange(tvr.Degrees);

                //VE tiles
                double metersY;
                double yMeters;
                int yMetersPerPixel;
                int row;

                double metersX = earthRadius * DegToRad(lon); //0
                double xMeters = earthHalfCirc + metersX; //20037508.342789244
                int xMetersPerPixel = (int)Math.Round(xMeters / MetersPerPixel(zoomLevel));
                int col = xMetersPerPixel / pixelsPerTile;

                //reproject - overrides row above
                //this correctly keeps me on the current tile that is being viewed
                UV uvCurrent = new UV(DegToRad(lon), DegToRad(lat));
                uvCurrent = proj.Forward(uvCurrent);
                metersY = uvCurrent.V;
                yMeters = earthHalfCirc - metersY;
                yMetersPerPixel = (int)Math.Round(yMeters / MetersPerPixel(zoomLevel));
                row = yMetersPerPixel / pixelsPerTile;

                //update mesh if VertEx changes
                if (prevVe != World.Settings.VerticalExaggeration)
                {
                    lock (veTiles.SyncRoot)
                    {
                        VeTile veTile;
                        for (int i = 0; i < veTiles.Count; i++)
                        {
                            veTile = (VeTile)veTiles[i];
                            if (veTile.VertEx != World.Settings.VerticalExaggeration)
                            {
                                veTile.CreateMesh(this.Opacity, World.Settings.VerticalExaggeration);
                            }
                        }
                    }
                }
                prevVe = World.Settings.VerticalExaggeration;

                //if within previous bounds and same zoom level, then exit
                if (row == prevRow && col == prevCol && zoomLevel == prevLvl && tilt == preTilt)
                {
                    return;
                }

                //System.Diagnostics.Debug.WriteLine("CHANGE");

                lock (veTiles.SyncRoot)
                {
                    VeTile veTile;
                    for (int i = 0; i < veTiles.Count; i++)
                    {
                        veTile = (VeTile)veTiles[i];
                        veTile.IsNeeded = false;
                    }
                }

                //metadata
                ArrayList alMetadata = null;

                //add current tiles first
                AddVeTile(drawArgs, row, col, zoomLevel, alMetadata);
                //then add other tiles outwards in surrounding circles
                AddNeighborTiles(drawArgs, row, col, zoomLevel, null, 1);
                AddNeighborTiles(drawArgs, row, col, zoomLevel, null, 2);
                AddNeighborTiles(drawArgs, row, col, zoomLevel, null, 3);
                // Extend tile grid if camera tilt above some values
                if (tilt > 45) AddNeighborTiles(drawArgs, row, col, zoomLevel, null, 4);
                if (tilt > 60) AddNeighborTiles(drawArgs, row, col, zoomLevel, null, 5);

                lock (veTiles.SyncRoot)
                {
                    VeTile veTile;
                    for (int i = 0; i < veTiles.Count; i++)
                    {
                        veTile = (VeTile)veTiles[i];
                        if (veTile.IsNeeded == false && veTile.DownloadInProgress == false)
                        {
                            veTile.Dispose();
                            veTiles.RemoveAt(i);
                            i--;
                        }
                    }
                }

                prevRow = row;
                prevCol = col;
                prevLvl = zoomLevel;
                preTilt = tilt;
            }
            catch (Exception ex)
            {
                Utility.Log.Write(ex);
            }
        }
Beispiel #7
0
        //NOTE this is a mix from Mashi's Reproject and WW for terrain
        internal void CreateMesh(byte opacity, float verticalExaggeration)
        {
            this.vertEx = verticalExaggeration;

            meshPointCount = 32; //64; //96 // How many vertices for each direction in mesh (total: n^2)
            //vertices = new CustomVertex.PositionColoredTextured[meshPointCount * meshPointCount];

            // Build mesh with one extra row and col around the terrain for normal computation and struts
            vertices = new CustomVertex.PositionNormalTextured[(meshPointCount + 2) * (meshPointCount + 2)];

            int upperBound = meshPointCount - 1;
            float scaleFactor = (float)1 / upperBound;
            //using(Projection proj = new Projection(m_projectionParameters))
            //{
            double uStep = (UR.U - UL.U) / upperBound;
            double vStep = (UL.V - LL.V) / upperBound;
            UV curUnprojected = new UV(UL.U - uStep, UL.V + vStep);

            // figure out latrange (for terrain detail)
            UV geoUL = _proj.Inverse(m_ul);
            UV geoLR = _proj.Inverse(m_lr);
            double latRange = (geoUL.U - geoLR.U) * 180 / Math.PI;

            North = geoUL.V * 180 / Math.PI;
            South = geoLR.V * 180 / Math.PI;
            West = geoUL.U * 180 / Math.PI;
            East = geoLR.U * 180 / Math.PI;

            float meshBaseRadius = (float)_layerRadius;

            UV geo;
            Point3d pos;
            double height = 0;
            for (int i = 0; i < meshPointCount + 2; i++)
            {
                for (int j = 0; j < meshPointCount + 2; j++)
                {
                    geo = _proj.Inverse(curUnprojected);

                    // Radians -> Degrees
                    geo.U *= 180 / Math.PI;
                    geo.V *= 180 / Math.PI;

                    if (_terrainAccessor != null)
                    {
                            height = verticalExaggeration * _terrainAccessor.GetElevationAt(geo.V, geo.U, Math.Abs(upperBound / latRange));
                    }

                    pos = MathEngine.SphericalToCartesian(
                         geo.V,
                         geo.U,
                         _layerRadius + height);
                    int idx = i * (meshPointCount + 2) + j;
                    vertices[idx].X = (float)pos.X;
                    vertices[idx].Y = (float)pos.Y;
                    vertices[idx].Z = (float)pos.Z;

                    vertices[idx].Tu = (j - 1) * scaleFactor;
                    vertices[idx].Tv = (i - 1) * scaleFactor;
                    curUnprojected.U += uStep;
                }
                curUnprojected.U = UL.U - uStep;
                curUnprojected.V -= vStep;
            }

            int slices = meshPointCount + 1;
            indices = new short[2 * slices * slices * 3];
            for (int i = 0; i < slices; i++)
            {
                for (int j = 0; j < slices; j++)
                {
                    indices[(2 * 3 * i * slices) + 6 * j] = (short)(i * (meshPointCount + 2) + j);
                    indices[(2 * 3 * i * slices) + 6 * j + 1] = (short)((i + 1) * (meshPointCount + 2) + j);
                    indices[(2 * 3 * i * slices) + 6 * j + 2] = (short)(i * (meshPointCount + 2) + j + 1);

                    indices[(2 * 3 * i * slices) + 6 * j + 3] = (short)(i * (meshPointCount + 2) + j + 1);
                    indices[(2 * 3 * i * slices) + 6 * j + 4] = (short)((i + 1) * (meshPointCount + 2) + j);
                    indices[(2 * 3 * i * slices) + 6 * j + 5] = (short)((i + 1) * (meshPointCount + 2) + j + 1);
                }
            }

            // Compute normals and fold struts
            calculate_normals();
            fold_struts(false, meshBaseRadius);
        }
Beispiel #8
0
        /// <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?
        }