示例#1
0
        public static void GeneratePrism(int axis, double radius, double height, int segments, bool insideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (radius <= 0 || segments < 3)
            {
                GetEmptyData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
                return;
            }
            int segmentsHeight = 1;
            int nextVertex     = 0;

            Point[] polygon = GenerateCircleZ(segments + 1, radius, 360, ref nextVertex);
            FromZAxisToAxis(polygon, axis);

            var halfVector = GetAxisVector(axis) * height * 0.5;

            Matrix4[] m = GetTransformsOfLinePath(segmentsHeight + 1, -halfVector, halfVector);

            Point center0 = new Point(m[0] * Vector3.Zero, nextVertex++);
            Point center1 = new Point(m[m.Length - 1] * Vector3.Zero, nextVertex++);

            Point[][] legs = GenerateLegs(polygon, m, nextVertex, false);

            int rawVertexCount = CommonPipeBuilder.GetLegsRawVertexCount(legs) + 2 * CommonPipeBuilder.GetPolygonAdaptiveRawVertexCount(polygon);
            var builder        = new CommonPipeBuilder(rawVertexCount, segments * (legs.Length - 1) + 2);

            builder.AddLegs(legs, insideOut);
            builder.AddPolygonAdaptive(legs[0], center0, !insideOut, !insideOut);
            builder.AddPolygonAdaptive(legs[legs.Length - 1], center1, insideOut, insideOut);
            builder.GetData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
        }
示例#2
0
        public static void GenerateDoor(int axis, double width, double height, double depth, double doorWidth, double doorHeight, bool insideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (width <= doorWidth)
            {
                width     = Math.Max(width, doorWidth);
                doorWidth = width - 1e-6;
            }
            if (height <= doorHeight)
            {
                height     = Math.Max(height, doorHeight);
                doorHeight = height - 1e-6;
            }
            if (width <= 0 || height <= 0 || doorWidth <= 0 || doorHeight <= 0)
            {
                GetEmptyData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
                return;
            }

            double halfWidth      = width * 0.5;
            double halfWidthInner = doorWidth * 0.5;
            double heightInner    = doorHeight;
            int    segmentsDepth  = 1;

            Point[] pointsInner =
            {
                new Point(new Vector3(halfWidthInner,            0, 0), 0),
                new Point(new Vector3(halfWidthInner,  heightInner, 0), 1),
                new Point(new Vector3(-halfWidthInner, heightInner, 0), 2),
                new Point(new Vector3(-halfWidthInner,           0, 0), 3),
            };
            Point[] pointsOuter =
            {
                new Point(new Vector3(halfWidth,       0, 0), 4),
                new Point(new Vector3(halfWidth,  height, 0), 5),
                new Point(new Vector3(-halfWidth, height, 0), 6),
                new Point(new Vector3(-halfWidth,      0, 0), 7),
            };

            int nextVertex = 8;

            FromZAxisToAxis(pointsInner, axis);
            FromZAxisToAxis(pointsOuter, axis);

            var halfVector = 0.5 * depth * GetAxisVector(axis);

            Matrix4[] m         = GetTransformsOfLinePath(segmentsDepth + 1, -halfVector, halfVector);
            Point[][] legsInner = GenerateLegs(pointsInner, m, nextVertex, false);
            Point[][] legsOuter = GenerateLegs(pointsOuter, m, nextVertex, false);

            int rawVertexCount = CommonPipeBuilder.GetLegsRawVertexCount(legsInner) + 2 * CommonPipeBuilder.GetPolygon2RawVertexCount(legsOuter[0]);
            var builder        = new CommonPipeBuilder(rawVertexCount, 3 + 2);

            builder.AddLegs(legsInner, !insideOut);
            builder.AddPolygon2(legsOuter[0], legsInner[0], !insideOut, !insideOut);                   //normal противоположна от направления смещения legs поэтому !insideOut
            builder.AddPolygon2(legsOuter[legsOuter.Length - 1], legsInner[legsInner.Length - 1], insideOut, insideOut);

            builder.GetData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
        }
示例#3
0
        public static void GeneratePolygonBasedPolyhedron(Vector3[] points, bool clockwise, double height, bool insideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (points.Length < 3)
            {
                GetEmptyData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
                return;
            }

            var normal = Plane.FromPoints(points[0], points[1], points[2]).Normal;

            if (clockwise)
            {
                normal    = -normal;
                insideOut = !insideOut;
            }

            int segmentsHeight = 1;

            Point[] polygon = new Point[points.Length + 1];
            for (int i = 0; i < points.Length; i++)
            {
                polygon[i] = new Point(points[i], i);
            }
            polygon[polygon.Length - 1] = polygon[0];
            int nextVertex = points.Length;

            //var halfVector = normal * height * 0.5;
            Matrix4[] m    = GetTransformsOfLinePath(segmentsHeight + 1, Vector3.Zero, normal * height);
            Point[][] legs = GenerateLegs(polygon, m, nextVertex, false);

            Vector3[] pos = new Vector3[points.Length];
            for (int i = 0; i < points.Length; i++)
            {
                pos[i] = legs[0][i].Position;
            }


            int[] triangles = MathAlgorithms.TriangulatePolygon(pos);               //the same for the top and the bottom


            int rawVertexCount = CommonPipeBuilder.GetLegsRawVertexCount(legs) + 2 * triangles.Length;
            var builder        = new CommonPipeBuilder(rawVertexCount, points.Length * (legs.Length - 1) + 2);

            builder.AddLegs(legs, insideOut);
            builder.AddPolygon(legs[0], triangles, !insideOut, !insideOut);
            builder.AddPolygon(legs[legs.Length - 1], triangles, insideOut, insideOut);
            builder.GetData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
        }
示例#4
0
        public static void GeneratePipe(int axis, double radius, double height, double thickness, int segments, int segmentsHeight, bool insideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (radius < thickness)
            {
                thickness = radius - 1e-6;
            }
            if (radius <= 0 || segments < 3)
            {
                GetEmptyData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
                return;
            }

            bool hasTopBottom  = 0 < thickness;
            int  legPointCount = segments + 1;
            int  vertexOffset  = 0;

            Point[] polygonOuter = GenerateCircleZ(legPointCount, radius, 360, ref vertexOffset);
            FromZAxisToAxis(polygonOuter, axis);
            Point[] polygonInner = GenerateCircleZ(legPointCount, radius - thickness, 360, ref vertexOffset);
            FromZAxisToAxis(polygonInner, axis);

            var halfVector = 0.5 * height * GetAxisVector(axis);

            Matrix4[] m         = GetTransformsOfLinePath(segmentsHeight + 1, -halfVector, halfVector);
            var       legsOuter = GenerateLegs(polygonOuter, m, vertexOffset, false);
            var       legsInner = GenerateLegs(polygonInner, m, vertexOffset, false);

            int rawVertexCount = 2 * CommonPipeBuilder.GetLegsRawVertexCount(legsOuter) + (hasTopBottom ? 2 * CommonPipeBuilder.GetPolygon2RawVertexCount(polygonOuter) : 0);
            int faceCount      = 2 * segments * (legsOuter.Length - 1) + (hasTopBottom ? 2 : 0);
            var builder        = new CommonPipeBuilder(rawVertexCount, faceCount, true);

            builder.AddLegs(legsOuter, insideOut, 1);
            builder.AddLegs(legsInner, !insideOut, 1);

            if (hasTopBottom)
            {
                //top,bottom
                builder.AddPolygon2(legsOuter[0], legsInner[0], !insideOut, false);
                builder.AddPolygon2(legsOuter[legsOuter.Length - 1], legsInner[legsInner.Length - 1], insideOut, false);
            }

            builder.GetData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
        }
示例#5
0
        public static void GenerateTorus(int axis, double radius, int segments, Degree circumference, double tubeRadius, int tubeSegments, Degree tubeCircumference, /*bool smooth, */ bool insideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (radius < tubeRadius)
            {
                tubeRadius = radius;
            }
            bool loopOfLegs = Math.Abs(circumference.ToDouble() - 360) < 1e-5;
            bool endCapes   = !loopOfLegs;

            if (radius <= 0 || tubeRadius <= 0 || segments < 3 || tubeSegments < 3 || circumference <= 0 || tubeCircumference <= 0)
            {
                GetEmptyData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
                return;
            }

            ReplaceAxes(out int axis0, out int axis1, axis);

            int nextVertex = 0;

            Point[] polygon = GenerateCircleZ(tubeSegments + 1, tubeRadius, tubeCircumference, ref nextVertex);
            FromZAxisToAxis(polygon, axis0);               //сечение тора
            Matrix4[] m    = GetTransformsOfRotationCircle(segments + 1, axis, circumference, (radius - tubeRadius) * GetAxisVector(axis1));
            var       legs = GenerateLegs(polygon, m, nextVertex, loopOfLegs);

            int rawVertexCount = CommonPipeBuilder.GetLegsRawVertexCount(legs) + (endCapes ? 2 * CommonPipeBuilder.GetPolygonAdaptiveRawVertexCount(polygon) : 0);
            var builder        = new CommonPipeBuilder(rawVertexCount, (legs.Length - 1) * tubeSegments + (endCapes ? 2 : 0), true);

            builder.AddLegs(legs, insideOut, 1);

            //ToDo ?? Нужны ли крышки когда circumference<360 ?  Может опцию endCapes ?
            //Add capes
            if (endCapes)
            {
                nextVertex *= legs.Length;
                Point center0 = new Point(m[0] * Vector3.Zero, nextVertex++);
                Point center1 = new Point(m[m.Length - 1] * Vector3.Zero, nextVertex++);

                builder.AddPolygonAdaptive(legs[0], center0, !insideOut, !insideOut);                     //normal противоположна от направления смещения legs поэтому !insideOut
                builder.AddPolygonAdaptive(legs[legs.Length - 1], center1, insideOut, insideOut);
            }

            builder.GetData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
        }
示例#6
0
        //ToDo : Логичнее когда главное направление для оси, в направлении входа. При axis=1,2 арка стоит, при axis=2 лежит на боку - тогда задать default axis=2
        //ToDo ??? Надо ли сделать чтобы нижние поверхности были паралельны земле при circumference<180 ?(тогда угол у внутреннего кольца будет меньше).
        public static void GenerateArch(int axis, double radius, double thickness, double depth, int segments, int segmentsDepth, Degree circumference, bool endCapes, bool insideOut, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (radius < thickness)
            {
                thickness = radius;
            }

            if (radius <= 0 || segments < 2 || segmentsDepth < 0 || circumference <= 0)
            {
                GetEmptyData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
                return;
            }

            //ToDo ??? endCapes это передняя/задняя или нижние поверхности ?
            bool frontBack = endCapes && 1e-8 < thickness;
            bool bottom    = endCapes;

            int legPointCount = segments + 1;
            int nextVertex    = 0;

            double startAngle = ((Math.PI - circumference.InRadians()) / 2);

            Point[] outer = GenerateCircleZ(legPointCount, radius, circumference, ref nextVertex, startAngle);
            FromZAxisToAxis(outer, axis);
            Point[] inner = GenerateCircleZ(legPointCount, radius - thickness, circumference, ref nextVertex, startAngle);
            FromZAxisToAxis(inner, axis);
            Point[] down1 = { inner[0], outer[0] };
            Point[] down2 = { outer[outer.Length - 1], inner[inner.Length - 1] };

            var halfVector = 0.5 * depth * GetAxisVector(axis);

            Matrix4[] m = GetTransformsOfLinePath(segmentsDepth + 1, -halfVector, halfVector);

            var legsOuter = GenerateLegs(outer, m, nextVertex, false);
            var legsInner = GenerateLegs(inner, m, nextVertex, false);

            Point[][] legsDown1 = null;
            Point[][] legsDown2 = null;
            if (bottom)
            {
                legsDown1 = GenerateLegs(down1, m, nextVertex, false);
                legsDown2 = GenerateLegs(down2, m, nextVertex, false);
            }

            int rawVertexCount = 2 * CommonPipeBuilder.GetLegsRawVertexCount(legsOuter) +
                                 (legsDown1 == null ? 0 : 2 * CommonPipeBuilder.GetLegsRawVertexCount(legsDown1)) +
                                 (frontBack ? 2 * CommonPipeBuilder.GetPolygon2RawVertexCount(outer) : 0);
            int faceCount = 2 * segments * (legsOuter.Length - 1) + 2 * (bottom ? legsOuter.Length - 1 : 0) + (frontBack ? 2 : 0);
            var builder   = new CommonPipeBuilder(rawVertexCount, faceCount, true);

            builder.AddLegs(legsOuter, insideOut, 1);
            builder.AddLegs(legsInner, !insideOut, 1);

            if (bottom)
            {
                builder.AddLegs(legsDown1, insideOut);
                builder.AddLegs(legsDown2, insideOut);
            }

            if (frontBack)
            {
                builder.AddPolygon2(legsOuter[0], legsInner[0], !insideOut, !insideOut);                       //normal противоположна от направления смещения legs поэтому !insideOut
                builder.AddPolygon2(legsOuter[legsOuter.Length - 1], legsInner[legsInner.Length - 1], insideOut, insideOut);
            }

            builder.GetData(out positions, out normals, out tangents, out texCoords, out indices, out faces);
        }