コード例 #1
0
ファイル: Cone.cs プロジェクト: erictuvesson/CSG
        public static void CreateSolid(this IGeometryBuilder builder, int tessellation)
        {
            Vector3 offset = new Vector3(0, -0.25f, 0);

            builder.AddVertex(Vector3.UnitY + offset, Vector3.UnitY);
            builder.AddVertex(Vector3.Zero + offset, -Vector3.UnitY);

            for (int i = 0; i < tessellation; ++i)
            {
                float angle = i * Algorithms.Helpers.TwoPi / tessellation;

                float dx = MathF.Cos(angle);
                float dz = MathF.Sin(angle);

                Vector3 normal = new Vector3(dx, 0, dz);

                builder.AddVertex(normal + offset, normal);

                builder.AddIndex(0);
                builder.AddIndex(2 + i);
                builder.AddIndex(2 + (i + 1) % tessellation);

                builder.AddIndex(1);
                builder.AddIndex(2 + (i + 1) % tessellation);
                builder.AddIndex(2 + i);
            }
        }
コード例 #2
0
ファイル: Cube.cs プロジェクト: erictuvesson/CSG
        public static void CreateSolid(this IGeometryBuilder builder, Vector3 size)
        {
            for (int i = 0; i < normals.Length; i++)
            {
                var normal = normals[i];

                Vector3 side1 = new Vector3(normal.Y, normal.Z, normal.X);
                Vector3 side2 = Vector3.Cross(normal, side1);

                builder.AddIndex(builder.CurrentVertex + 0);
                builder.AddIndex(builder.CurrentVertex + 1);
                builder.AddIndex(builder.CurrentVertex + 2);

                builder.AddIndex(builder.CurrentVertex + 0);
                builder.AddIndex(builder.CurrentVertex + 2);
                builder.AddIndex(builder.CurrentVertex + 3);

                builder.AddVertex(((normal - side1 - side2) / 2.0f) * size, normal, Vector2.Zero);
                builder.AddVertex(((normal - side1 + side2) / 2.0f) * size, normal, Vector2.UnitX);
                builder.AddVertex(((normal + side1 + side2) / 2.0f) * size, normal, Vector2.One);
                builder.AddVertex(((normal + side1 - side2) / 2.0f) * size, normal, Vector2.UnitY);
            }
        }
コード例 #3
0
        public static void CreateSolid(this IGeometryBuilder builder, Vector3 start, Vector3 end, float radius, int tessellation)
        {
            builder.AddVertex(start * 0.5f, start);
            builder.AddVertex(-end * 0.5f, -end);

            float diameter = radius / 2.0f;

            for (int i = 0; i < tessellation; ++i)
            {
                float angle = i * Algorithms.Helpers.TwoPi / tessellation;

                float dx = MathF.Cos(angle);
                float dz = MathF.Sin(angle);

                Vector3 normal = new Vector3(dx, 0.0f, dz);

                builder.AddVertex(normal + (diameter * start), normal);
                builder.AddVertex(normal - (diameter * start), normal);

                builder.AddIndex(0);
                builder.AddIndex(2 + (i * 2));
                builder.AddIndex(2 + (((i * 2) + 2) % (tessellation * 2)));

                builder.AddIndex(2 + (i * 2));
                builder.AddIndex(2 + (i * 2) + 1);
                builder.AddIndex(2 + (((i * 2) + 2) % (tessellation * 2)));

                builder.AddIndex(1);
                builder.AddIndex(2 + (((i * 2) + 3) % (tessellation * 2)));
                builder.AddIndex(2 + (i * 2) + 1);

                builder.AddIndex(2 + (i * 2) + 1);
                builder.AddIndex(2 + (((i * 2) + 3) % (tessellation * 2)));
                builder.AddIndex(2 + (((i * 2) + 2) % (tessellation * 2)));
            }
        }
コード例 #4
0
ファイル: Torus.cs プロジェクト: erictuvesson/CSG
        public static void CreateSolid(this IGeometryBuilder builder, int tessellation)
        {
            // First we loop around the main ring of the torus.
            for (int i = 0; i < tessellation; ++i)
            {
                float outerAngle = i * Algorithms.Helpers.TwoPi / tessellation;

                // Create a transform matrix that will align geometry to
                // slice perpendicularly though the current ring position.
                var transform = Matrix4x4.CreateTranslation(1, 0, 0) *
                                Matrix4x4.CreateRotationY(outerAngle);

                // Now we loop along the other axis, around the side of the tube.
                for (int j = 0; j < tessellation; j++)
                {
                    float innerAngle = j * Algorithms.Helpers.TwoPi / tessellation;

                    float dx = MathF.Cos(innerAngle);
                    float dy = MathF.Sin(innerAngle);

                    // Create a vertex.
                    Vector3 normal   = new Vector3(dx, dy, 0);
                    Vector3 position = normal / 2.0f;

                    position = Vector3.Transform(position, transform);
                    normal   = Vector3.TransformNormal(normal, transform);

                    builder.AddVertex(position, normal);

                    // And create indices for two triangles.
                    int nextI = (i + 1) % tessellation;
                    int nextJ = (j + 1) % tessellation;

                    builder.AddIndex(i * tessellation + j);
                    builder.AddIndex(i * tessellation + nextJ);
                    builder.AddIndex(nextI * tessellation + j);

                    builder.AddIndex(i * tessellation + nextJ);
                    builder.AddIndex(nextI * tessellation + nextJ);
                    builder.AddIndex(nextI * tessellation + j);
                }
            }
        }
コード例 #5
0
ファイル: Sphere.cs プロジェクト: erictuvesson/CSG
        public static void CreateSolid(this IGeometryBuilder builder, float radius, int tessellation)
        {
            int verticalSegments   = tessellation;
            int horizontalSegments = tessellation * 2;

            // Start with a single vertex at the bottom of the sphere.
            builder.AddVertex(Vector3.UnitY, -Vector3.UnitY);

            // Create rings of vertices at progressively higher latitudes.
            for (int i = 0; i < verticalSegments - 1; ++i)
            {
                float latitude = ((i + 1.0f) * Algorithms.Helpers.Pi / verticalSegments) - Algorithms.Helpers.PiOver2;

                float dy  = MathF.Sin(latitude);
                float dxz = MathF.Cos(latitude);

                // Create a single ring of vertices at this latitude.
                for (int j = 0; j < horizontalSegments; j++)
                {
                    float longitude = j * Algorithms.Helpers.TwoPi / horizontalSegments;

                    float dx = MathF.Cos(longitude) * dxz;
                    float dz = MathF.Sin(longitude) * dxz;

                    Vector3 normal = new Vector3(dx, dy, dz) * radius;

                    builder.AddVertex(normal, normal);
                }
            }

            // Finish with a single vertex at the top of the sphere.
            builder.AddVertex(Vector3.UnitY, Vector3.UnitY);

            // Create a fan connecting the bottom vertex to the bottom latitude ring.
            for (int i = 0; i < horizontalSegments; ++i)
            {
                builder.AddIndex(0);
                builder.AddIndex(1 + ((i + 1) % horizontalSegments));
                builder.AddIndex(1 + i);
            }

            // Fill the sphere body with triangles joining each pair of latitude rings.
            for (int i = 0; i < verticalSegments - 2; ++i)
            {
                for (int j = 0; j < horizontalSegments; j++)
                {
                    int nextI = i + 1;
                    int nextJ = (j + 1) % horizontalSegments;

                    builder.AddIndex(1 + (i * horizontalSegments) + j);
                    builder.AddIndex(1 + (i * horizontalSegments) + nextJ);
                    builder.AddIndex(1 + (nextI * horizontalSegments) + j);

                    builder.AddIndex(1 + (i * horizontalSegments) + nextJ);
                    builder.AddIndex(1 + (nextI * horizontalSegments) + nextJ);
                    builder.AddIndex(1 + (nextI * horizontalSegments) + j);
                }
            }

            // Create a fan connecting the top vertex to the top latitude ring.
            for (int i = 0; i < horizontalSegments; ++i)
            {
                builder.AddIndex(builder.CurrentVertex - 1);
                builder.AddIndex(builder.CurrentVertex - 2 - ((i + 1) % horizontalSegments));
                builder.AddIndex(builder.CurrentVertex - 2 - i);
            }
        }