示例#1
0
        internal FormatYielder Spawn(UnparsableAst child, ChildLocation childLocation = ChildLocation.Unknown)
        {
            if (childLocation == ChildLocation.Unknown)
            {
                return(new FormatYielder(this)
                {
                    topAncestorCacheForLeft = UnparsableAst.NonCalculated
                });
            }
            else
            {
                bool isLeftMostChild =
                    childLocation == ChildLocation.Only
                    ||
                    direction == Unparser.Direction.LeftToRight && childLocation == ChildLocation.First
                    ||
                    direction == Unparser.Direction.RightToLeft && childLocation == ChildLocation.Last;

                return(new FormatYielder(this)
                {
                    topAncestorCacheForLeft = isLeftMostChild
                        ? this.topAncestorCacheForLeft
                        : (child ?? UnparsableAst.NonCalculated)
                });
            }
        }
示例#2
0
        /// <summary>
        /// Create child tile terrain mesh
        /// Build the mesh with one extra vertice all around for proper normals calculations later on.
        /// Use the struts vertices to that effect. Struts are properly folded after normals calculations.
        /// </summary>
        protected void CreateElevatedMesh(ChildLocation corner, CustomVertex.PositionNormalTextured[] vertices,
            double meshBaseRadius, float[,] heightData)
        {
            // Figure out child lat/lon boundaries (radians)
            double north = MathEngine.DegreesToRadians(North);
            double west = MathEngine.DegreesToRadians(West);

            // Texture coordinate offsets
            float TuOffset = 0;
            float TvOffset = 0;

            switch (corner)
            {
                case ChildLocation.NorthWest:
                    // defaults are all good
                    break;
                case ChildLocation.NorthEast:
                    west = MathEngine.DegreesToRadians(0.5 * (West + East));
                    TuOffset = 0.5f;
                    break;
                case ChildLocation.SouthWest:
                    north = MathEngine.DegreesToRadians(0.5 * (North + South));
                    TvOffset = 0.5f;
                    break;
                case ChildLocation.SouthEast:
                    north = MathEngine.DegreesToRadians(0.5 * (North + South));
                    west = MathEngine.DegreesToRadians(0.5 * (West + East));
                    TuOffset = 0.5f;
                    TvOffset = 0.5f;
                    break;
            }

            double latitudeRadianSpan = MathEngine.DegreesToRadians(LatitudeSpan);
            double longitudeRadianSpan = MathEngine.DegreesToRadians(LongitudeSpan);

            double layerRadius = (double)QuadTileSet.LayerRadius;
            double scaleFactor = 1.0 / vertexCountElevated;
            int terrainLongitudeIndex = (int)(TuOffset * vertexCountElevated) + 1;
            int terrainLatitudeIndex = (int)(TvOffset * vertexCountElevated) + 1;

            int vertexCountElevatedPlus1 = vertexCountElevated / 2 + 1;

            double radius = 0;
            int vertexIndex = 0;
            for (int latitudeIndex = -1; latitudeIndex <= vertexCountElevatedPlus1; latitudeIndex++)
            {
                double latitudeFactor = latitudeIndex * scaleFactor;
                double latitude = north - latitudeFactor * latitudeRadianSpan;

                // Cache trigonometric values
                double cosLat = Math.Cos(latitude);
                double sinLat = Math.Sin(latitude);

                for (int longitudeIndex = -1; longitudeIndex <= vertexCountElevatedPlus1; longitudeIndex++)
                {

                    // Top of mesh for all (real terrain + struts)
                    radius = layerRadius +
                         heightData[terrainLatitudeIndex + latitudeIndex, terrainLongitudeIndex + longitudeIndex]
                         * verticalExaggeration;

                    double longitudeFactor = longitudeIndex * scaleFactor;

                    // Texture coordinates
                    vertices[vertexIndex].Tu = TuOffset + (float)longitudeFactor;
                    vertices[vertexIndex].Tv = TvOffset + (float)latitudeFactor;

                    // Convert from spherical (radians) to cartesian
                    double longitude = west + longitudeFactor * longitudeRadianSpan;
                    double radCosLat = radius * cosLat;
                    vertices[vertexIndex].X = (float)(radCosLat * Math.Cos(longitude) - localOrigin.X);
                    vertices[vertexIndex].Y = (float)(radCosLat * Math.Sin(longitude) - localOrigin.Y);
                    vertices[vertexIndex].Z = (float)(radius * sinLat - localOrigin.Z);

                    vertexIndex++;
                }
            }
        }
示例#3
0
        /// <summary>
        /// Create child tile terrain mesh
        /// </summary>
        protected void CreateElevatedMesh(ChildLocation corner, CustomVertex.PositionTextured[] vertices, double meshBaseRadius, float[,] heightData)
        {
            // Figure out child lat/lon boundaries (radians)
            double north = MathEngine.DegreesToRadians(North);
            double west  = MathEngine.DegreesToRadians(West);

            // Texture coordinate offsets
            float TuOffset = 0;
            float TvOffset = 0;

            switch (corner)
            {
            case ChildLocation.NorthWest:
                // defaults are all good
                break;

            case ChildLocation.NorthEast:
                west     = MathEngine.DegreesToRadians(0.5 * (West + East));
                TuOffset = 0.5f;
                break;

            case ChildLocation.SouthWest:
                north    = MathEngine.DegreesToRadians(0.5 * (North + South));
                TvOffset = 0.5f;
                break;

            case ChildLocation.SouthEast:
                north    = MathEngine.DegreesToRadians(0.5 * (North + South));
                west     = MathEngine.DegreesToRadians(0.5 * (West + East));
                TuOffset = 0.5f;
                TvOffset = 0.5f;
                break;
            }

            double latitudeRadianSpan  = MathEngine.DegreesToRadians(LatitudeSpan);
            double longitudeRadianSpan = MathEngine.DegreesToRadians(LongitudeSpan);

            double layerRadius           = (double)QuadTileSet.LayerRadius;
            double scaleFactor           = 1.0 / vertexCountElevated;
            int    terrainLongitudeIndex = (int)(TuOffset * vertexCountElevated);
            int    terrainLatitudeIndex  = (int)(TvOffset * vertexCountElevated);

            int vertexCountElevatedPlus1 = vertexCountElevated / 2 + 1;

            double radius      = 0;
            int    vertexIndex = 0;

            for (int latitudeIndex = -1; latitudeIndex <= vertexCountElevatedPlus1; latitudeIndex++)
            {
                int latitudePoint = latitudeIndex;
                if (latitudePoint < 0)
                {
                    latitudePoint = 0;
                }
                else if (latitudePoint >= vertexCountElevatedPlus1)
                {
                    latitudePoint = vertexCountElevatedPlus1 - 1;
                }

                double latitudeFactor = latitudePoint * scaleFactor;
                double latitude       = north - latitudeFactor * latitudeRadianSpan;

                // Cache trigonometric values
                double cosLat = Math.Cos(latitude);
                double sinLat = Math.Sin(latitude);

                for (int longitudeIndex = -1; longitudeIndex <= vertexCountElevatedPlus1; longitudeIndex++)
                {
                    int longitudePoint = longitudeIndex;
                    if (longitudePoint < 0)
                    {
                        longitudePoint = 0;
                    }
                    else if (longitudePoint >= vertexCountElevatedPlus1)
                    {
                        longitudePoint = vertexCountElevatedPlus1 - 1;
                    }

                    if (longitudeIndex != longitudePoint ||
                        latitudeIndex != latitudePoint)
                    {
                        if (heightData != null &&
                            (!renderStruts || m_CurrentOpacity < 255))
                        {
                            radius = layerRadius + heightData[terrainLatitudeIndex + latitudePoint, terrainLongitudeIndex + longitudePoint] * verticalExaggeration;
                        }
                        else
                        {
                            radius = meshBaseRadius;
                        }

                        //			// Mesh base (flat)
                        //			radius = meshBaseRadius;
                    }
                    else
                    {
                        // Top of mesh (real terrain)
                        radius = layerRadius + heightData[terrainLatitudeIndex + latitudeIndex, terrainLongitudeIndex + longitudeIndex] * verticalExaggeration;
                    }

                    double longitudeFactor = longitudePoint * scaleFactor;

                    // Texture coordinates
                    vertices[vertexIndex].Tu = TuOffset + (float)longitudeFactor;
                    vertices[vertexIndex].Tv = TvOffset + (float)latitudeFactor;

                    // Convert from spherical (radians) to cartesian
                    double longitude = west + longitudeFactor * longitudeRadianSpan;
                    double radCosLat = radius * cosLat;
                    vertices[vertexIndex].X = (float)(radCosLat * Math.Cos(longitude) - localOrigin.X);
                    vertices[vertexIndex].Y = (float)(radCosLat * Math.Sin(longitude) - localOrigin.Y);
                    vertices[vertexIndex].Z = (float)(radius * sinLat - localOrigin.Z);

                    vertexIndex++;
                }
            }
        }
示例#4
0
 internal FormatYielder Spawn(ChildLocation childLocation = ChildLocation.Unknown)
 {
     return(Spawn(child: null, childLocation: childLocation));
 }
示例#5
0
        internal FormatYielder Spawn(UnparsableAst child, ChildLocation childLocation = ChildLocation.Unknown)
        {
            if (childLocation == ChildLocation.Unknown)
            {
                return new FormatYielder(this)
                {
                    topAncestorCacheForLeft = UnparsableAst.NonCalculated
                };
            }
            else
            {
                bool isLeftMostChild =
                    childLocation == ChildLocation.Only
                    ||
                    direction == Unparser.Direction.LeftToRight && childLocation == ChildLocation.First
                    ||
                    direction == Unparser.Direction.RightToLeft && childLocation == ChildLocation.Last;

                return new FormatYielder(this)
                {
                    topAncestorCacheForLeft = isLeftMostChild
                        ? this.topAncestorCacheForLeft
                        : (child ?? UnparsableAst.NonCalculated)
                };
            }
        }
示例#6
0
 internal FormatYielder Spawn(ChildLocation childLocation = ChildLocation.Unknown)
 {
     return Spawn(child: null, childLocation: childLocation);
 }