Пример #1
0
        public void CanGetCentroid()
        {
            // ARRANGE
            var polygon = new List <Vector2d>()
            {
                new Vector2d(0, 0),
                new Vector2d(0, 10),
                new Vector2d(10, 10),
                new Vector2d(10, 0),
            };

            // ACT
            var center = PolygonUtils.GetCentroid(polygon);

            // ASSERT
            Assert.AreEqual(new Vector2d(5, 5), center);
        }
Пример #2
0
        public override List <MeshData> Build(Building building)
        {
            var roofOffset = building.Elevation + building.MinHeight + building.Height;
            var roofHeight = roofOffset + building.RoofHeight;

            // 1. detect the longest segment
            float    length;
            Vector2d longestStart;
            Vector2d longestEnd;

            GetLongestSegment(building.Footprint, out length, out longestStart, out longestEnd);

            // 2. get direction vector
            var ridgeDirection = (new Vector3((float)longestEnd.X, roofOffset, (float)longestEnd.Y) -
                                  new Vector3((float)longestStart.X, roofOffset, (float)longestStart.Y)).normalized;

            // 3. get centroid
            var centroidPoint  = PolygonUtils.GetCentroid(building.Footprint);
            var centroidVector = new Vector3((float)centroidPoint.X, roofHeight, (float)centroidPoint.Y);

            // 4. get something like center line
            Vector3 p1 = centroidVector + length * length * ridgeDirection;
            Vector3 p2 = centroidVector - length * length * ridgeDirection;

            // 5. detect segments which have intesection with center line
            Vector2d first, second;
            int      firstIndex, secondIndex;

            DetectIntersectSegments(building.Footprint, new Vector2d(p1.x, p1.z), new Vector2d(p2.x, p2.z),
                                    out first, out firstIndex, out second, out secondIndex);
            if (firstIndex == -1 || secondIndex == -1)
            {
                Trace.Warn(LogCategory, Strings.RoofGenFailed, Name, building.Id.ToString());
                return(base.Build(building));
            }

            // prepare mesh and its index
            var mesh             = CreateMesh(building.Footprint);
            var floorCount       = building.Levels;
            var floorVertexCount = mesh.Triangles.Count * 3 * 2 * floorCount;
            var roofVertexCount  = (building.Footprint.Count - 1) * 2 * 12;

            var vertexCount = roofVertexCount + floorVertexCount;
            var planeCount  = building.Footprint.Count + floorCount;

            bool limitIsReached = false;

            if (vertexCount * 2 > Consts.MaxMeshSize)
            {
                vertexCount    = roofVertexCount;
                planeCount     = building.Footprint.Count;
                limitIsReached = true;
            }

            var meshIndex = new MultiPlaneMeshIndex(planeCount, vertexCount);
            var meshData  = new MeshData(meshIndex, vertexCount);

            // 6. process all segments and create vertices
            FillMeshData(meshData, CustomizationService.GetGradient(building.RoofColor), roofOffset,
                         roofHeight, building.Footprint, first, firstIndex, second, secondIndex);

            if (!limitIsReached)
            {
                AttachFloors(new RoofContext()
                {
                    Mesh      = mesh,
                    MeshData  = meshData,
                    MeshIndex = meshIndex,

                    Bottom             = building.Elevation + building.MinHeight,
                    FloorCount         = floorCount,
                    FloorHeight        = building.Height / floorCount,
                    FloorFrontGradient = CustomizationService.GetGradient(building.FloorFrontColor),
                    FloorBackGradient  = CustomizationService.GetGradient(building.FloorBackColor),

                    IsLastRoof = false
                });

                return(new List <MeshData>(1)
                {
                    meshData
                });
            }

            var meshDataList = BuildFloors(building, building.Levels, false);

            meshDataList.Add(meshData);
            return(meshDataList);
        }
Пример #3
0
        /// <inheritdoc />
        public override List <MeshData> Build(Building building)
        {
            var center     = PolygonUtils.GetCentroid(building.Footprint);
            var roofOffset = building.Elevation + building.MinHeight + building.Height;
            var footprint  = building.Footprint;
            var roofHeight = building.RoofHeight;
            var floorCount = building.Levels;

            var length           = footprint.Count;
            var mesh             = CreateMesh(footprint);
            var roofVertexCount  = 12 * length;
            var floorVertexCount = mesh.Triangles.Count * 3 * 2 * floorCount;

            var vertexCount = roofVertexCount + floorVertexCount;
            var planeCount  = building.Footprint.Count + floorCount;

            bool limitIsReached = false;

            if (vertexCount * 2 > Consts.MaxMeshSize)
            {
                vertexCount    = roofVertexCount;
                planeCount     = building.Footprint.Count;
                limitIsReached = true;
            }

            var meshIndex = new MultiPlaneMeshIndex(planeCount, vertexCount);
            var meshData  = new MeshData(meshIndex, vertexCount);

            var roofGradient = CustomizationService.GetGradient(building.RoofColor);

            for (int i = 0; i < length; i++)
            {
                var nextIndex = i == (length - 1) ? 0 : i + 1;

                var v0 = new Vector3((float)footprint[i].X, roofOffset, (float)footprint[i].Y);
                var v1 = new Vector3((float)center.X, roofOffset + roofHeight, (float)center.Y);
                var v2 = new Vector3((float)footprint[nextIndex].X, roofOffset, (float)footprint[nextIndex].Y);

                var v01 = Vector3Utils.GetIntermediatePoint(v0, v1);
                var v12 = Vector3Utils.GetIntermediatePoint(v1, v2);
                var v02 = Vector3Utils.GetIntermediatePoint(v0, v2);

                meshIndex.AddPlane(v0, v1, v2, meshData.NextIndex);

                var color = GetColor(roofGradient, v0);
                meshData.AddTriangle(v0, v01, v02, color, color);

                color = GetColor(roofGradient, v01);
                meshData.AddTriangle(v02, v01, v12, color, color);

                color = GetColor(roofGradient, v02);
                meshData.AddTriangle(v2, v02, v12, color, color);

                color = GetColor(roofGradient, v01);
                meshData.AddTriangle(v01, v1, v12, color, color);
            }

            if (!limitIsReached)
            {
                AttachFloors(new RoofContext()
                {
                    Mesh      = mesh,
                    MeshData  = meshData,
                    MeshIndex = meshIndex,

                    Bottom             = building.Elevation + building.MinHeight,
                    FloorCount         = floorCount,
                    FloorHeight        = building.Height / floorCount,
                    FloorFrontGradient = CustomizationService.GetGradient(building.FloorFrontColor),
                    FloorBackGradient  = CustomizationService.GetGradient(building.FloorBackColor),

                    IsLastRoof = false,
                });

                return(new List <MeshData>(1)
                {
                    meshData
                });
            }

            var meshDataList = BuildFloors(building, building.Levels, false);

            meshDataList.Add(meshData);
            return(meshDataList);
        }