Example #1
0
        public void GetElevationRange()
        {
            TrimbleTINModel TTM = new TrimbleTINModel();

            TTM.LoadFromFile(Path.Combine("TestData", "Bug36372.ttm"));

            TTM.GetElevationRange(out var MinElev, out var MaxElev);

            MinElev.Should().BeApproximately(22.5, 0.001);
            MaxElev.Should().BeApproximately(37.33, 0.001);
        }
Example #2
0
        /// <summary>
        /// Builds a SuperElevation LOD to SuperElevationProfile specifications as one vertex buffer and one index buffer.
        /// The order in which the buffers are built reflects the nesting in the TrProfile.  The nesting order is:
        /// (Polylines (Vertices)).  All vertices and indices are built contiguously for an LOD.
        /// </summary>
        /// <param name="viewer">Viewer.</param>
        /// <param name="worldPosition">WorldPosition.</param>
        /// <param name="iLOD">Index of LOD mesh to be generated from profile.</param>
        /// <param name="iLODItem">Index of LOD mesh to be generated from profile.</param>
        public new ShapePrimitive BuildPrimitive(Viewer viewer, WorldPosition worldPosition, int iLOD, int iLODItem)
        {
            // Call for track section to initialize itself
            if (DTrackData.IsCurved == 0)
            {
                LinearGen();
            }
            else
            {
                CircArcGen();
            }

            // Count vertices and indices
            LOD     lod     = (LOD)TrProfile.LODs[iLOD];
            LODItem lodItem = (LODItem)lod.LODItems[iLODItem];

            NumVertices = (int)(lodItem.NumVertices * (NumSections + 1));
            NumIndices  = (short)(lodItem.NumSegments * NumSections * 6);
            // (Cells x 2 triangles/cell x 3 indices/triangle)

            // Allocate memory for vertices and indices
            VertexList          = new VertexPositionNormalTexture[NumVertices]; // numVertices is now aggregate
            TriangleListIndices = new short[NumIndices];                        // as is NumIndices

            // Build the mesh for lod
            VertexIndex = 0;
            IndexIndex  = 0;
            whichCase   = 0; //0: no elevation (MaxElev=0), 1: start (startE = 0, Max!=end),
            //2: end (end=0, max!=start), 3: middle (start>0, end>0), 4: start and finish in one

            if (StartElev.AlmostEqual(0f, 0.001f) && MaxElev.AlmostEqual(0f, 0.001f) && EndElv.AlmostEqual(0f, 0.001f))
            {
                whichCase = 0;                                                                                                        //no elev
            }
            else if (StartElev.AlmostEqual(0f, 0.001f) && EndElv.AlmostEqual(0f, 0.001f))
            {
                whichCase = 4;                                                                          //finish/start in one
            }
            else if (StartElev.AlmostEqual(0f, 0.001f) && !EndElv.AlmostEqual(0f, 0.001f))
            {
                whichCase = 1;                                                                           //start
            }
            else if (EndElv.AlmostEqual(0f, 0.001f) && !StartElev.AlmostEqual(0f, 0.001f))
            {
                whichCase = 2;                                                                           //finish
            }
            else
            {
                whichCase = 3; //in middle
            }
            Matrix PreRotation = Matrix.Identity;

            elevated = MaxElev;
            if (whichCase == 3 || whichCase == 2)
            {
                PreRotation = Matrix.CreateRotationZ(-elevated * Math.Sign(DTrackData.param1));
            }
            //if section is in the middle of curve, will only rotate the first set of vertex, others will follow the same rotation
            prevRotation = 0f;

            Vector3 tmp;

            // Initial load of baseline cross section polylines for this LOD only:
            foreach (Polyline pl in lodItem.Polylines)
            {
                foreach (Vertex v in pl.Vertices)
                {
                    tmp = new Vector3(v.Position.X, v.Position.Y, v.Position.Z);

                    if (whichCase == 3 || whichCase == 2)
                    {
                        tmp          = Vector3.Transform(tmp, PreRotation);
                        prevRotation = MaxElev;
                    }
                    VertexList[VertexIndex].Position          = tmp;
                    VertexList[VertexIndex].Normal            = v.Normal;
                    VertexList[VertexIndex].TextureCoordinate = v.TexCoord;
                    VertexIndex++;
                }
            }
            // Initial load of base cross section complete

            // Now generate and load subsequent cross sections
            OldRadius = -center;
            uint stride = VertexIndex;

            offSet = 0;

            for (uint i = 0; i < NumSections; i++)
            {
                currentRotation = determineRotation(DTrackData.param1);
                elevated        = currentRotation - prevRotation;
                prevRotation    = currentRotation;
                if (DTrackData.param1 > 0)
                {
                    elevated *= -1;
                }

                foreach (Polyline pl in lodItem.Polylines)
                {
                    uint plv = 0; // Polyline vertex index
                    foreach (Vertex v in pl.Vertices)
                    {
                        if (DTrackData.IsCurved == 0)
                        {
                            LinearGen(stride, pl);                           // Generation call
                        }
                        else
                        {
                            CircArcGen(stride, pl);
                        }

                        if (plv > 0)
                        {
                            // Sense for triangles is clockwise
                            // First triangle:
                            TriangleListIndices[IndexIndex++] = (short)VertexIndex;
                            TriangleListIndices[IndexIndex++] = (short)(VertexIndex - 1 - stride);
                            TriangleListIndices[IndexIndex++] = (short)(VertexIndex - 1);
                            // Second triangle:
                            TriangleListIndices[IndexIndex++] = (short)VertexIndex;
                            TriangleListIndices[IndexIndex++] = (short)(VertexIndex - stride);
                            TriangleListIndices[IndexIndex++] = (short)(VertexIndex - 1 - stride);
                        }
                        VertexIndex++;
                        plv++;
                    }
                }
                OldRadius = radius; // Get ready for next segment
                offSet++;
            }

            // Create and populate a new ShapePrimitive
            var indexBuffer = new IndexBuffer(viewer.GraphicsDevice, typeof(short), NumIndices, BufferUsage.WriteOnly);

            indexBuffer.SetData(TriangleListIndices);
            return(new ShapePrimitive(lodItem.LODMaterial, new SharedShape.VertexBufferSet(VertexList, viewer.GraphicsDevice), indexBuffer, 0, NumVertices, NumIndices / 3, new[] { -1 }, 0));
        }