diff --git a/src/CSG/Geometry/Cube.cs b/src/CSG/Geometry/Cube.cs index 6d6a876..9500164 100644 --- a/src/CSG/Geometry/Cube.cs +++ b/src/CSG/Geometry/Cube.cs @@ -31,10 +31,10 @@ public static void CreateSolid(this IGeometryBuilder builder, Vector3 size) 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); + builder.AddVertex(((normal - side1 - side2)) * size, normal, Vector2.Zero); + builder.AddVertex(((normal - side1 + side2)) * size, normal, Vector2.UnitX); + builder.AddVertex(((normal + side1 + side2)) * size, normal, Vector2.One); + builder.AddVertex(((normal + side1 - side2)) * size, normal, Vector2.UnitY); } } } diff --git a/src/CSG/Geometry/Cylinder.cs b/src/CSG/Geometry/Cylinder.cs index 1813884..dc9a917 100644 --- a/src/CSG/Geometry/Cylinder.cs +++ b/src/CSG/Geometry/Cylinder.cs @@ -13,37 +13,61 @@ public static void CreateSolid(this IGeometryBuilder builder, float radius, int 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); + var dir = start - end; + if (dir == Vector3.Zero) + { + dir = new Vector3(1, 0, 0); + } + dir = Vector3.Normalize(dir); + + builder.AddVertex(start, dir); + builder.AddVertex(end, -dir); + + var sTop = 0; + var sBottom = 1; + var sEdgeTop = 2; + var sEdgeBottom = 3; + + var stride = 4; + + int getIndex(int i, int offset) + { + return 2 + (((i * stride) + offset) % (tessellation * stride)); + } + + var perp = Vector3.Normalize(Vector3.Cross(new Vector3(dir.Z, dir.X, dir.Y), dir)); - 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); + var normal = Vector3.Transform(perp, Quaternion.CreateFromAxisAngle(dir, angle)); + var rotated = normal * radius; - Vector3 normal = new Vector3(dx, 0.0f, dz); - - builder.AddVertex(normal + (diameter * start), normal); - builder.AddVertex(normal - (diameter * start), normal); + builder.AddVertex(rotated + start, dir); // Top surface + builder.AddVertex(rotated + end, -dir); // Bottom surface + builder.AddVertex(rotated + start, normal); // Top edge + builder.AddVertex(rotated + end, normal); // Bottom edge + // Top face 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(getIndex(i + 1, sTop)); + builder.AddIndex(getIndex(i, sTop)); + // Bottom face builder.AddIndex(1); - builder.AddIndex(2 + (((i * 2) + 3) % (tessellation * 2))); - builder.AddIndex(2 + (i * 2) + 1); + builder.AddIndex(getIndex(i, sBottom)); + builder.AddIndex(getIndex(i + 1, sBottom)); + + // Side face 1 + builder.AddIndex(getIndex(i, sEdgeTop)); + builder.AddIndex(getIndex(i + 1, sEdgeBottom)); + builder.AddIndex(getIndex(i, sEdgeBottom)); - builder.AddIndex(2 + (i * 2) + 1); - builder.AddIndex(2 + (((i * 2) + 3) % (tessellation * 2))); - builder.AddIndex(2 + (((i * 2) + 2) % (tessellation * 2))); + // Side face 2 + builder.AddIndex(getIndex(i + 1, sEdgeBottom)); + builder.AddIndex(getIndex(i, sEdgeTop)); + builder.AddIndex(getIndex(i + 1, sEdgeTop)); } } } diff --git a/src/CSG/Geometry/Sphere.cs b/src/CSG/Geometry/Sphere.cs index 51a112e..f0a35e8 100644 --- a/src/CSG/Geometry/Sphere.cs +++ b/src/CSG/Geometry/Sphere.cs @@ -17,7 +17,7 @@ public static void CreateSolid(this IGeometryBuilder builder, float radius, int int horizontalSegments = tessellation * 2; // Start with a single vertex at the bottom of the sphere. - builder.AddVertex(Vector3.UnitY, -Vector3.UnitY); + builder.AddVertex(-Vector3.UnitY * radius, -Vector3.UnitY * radius); // Create rings of vertices at progressively higher latitudes. for (int i = 0; i < verticalSegments - 1; ++i) @@ -42,7 +42,7 @@ public static void CreateSolid(this IGeometryBuilder builder, float radius, int } // Finish with a single vertex at the top of the sphere. - builder.AddVertex(Vector3.UnitY, Vector3.UnitY); + builder.AddVertex(Vector3.UnitY * radius, Vector3.UnitY * radius); // Create a fan connecting the bottom vertex to the bottom latitude ring. for (int i = 0; i < horizontalSegments; ++i) diff --git a/src/CSG/Shape.cs b/src/CSG/Shape.cs index 1cbe0af..49d28c4 100644 --- a/src/CSG/Shape.cs +++ b/src/CSG/Shape.cs @@ -110,7 +110,7 @@ protected Shape(SerializationInfo info, StreamingContext context) /// /// public GeneratedShape Do(ShapeOperation operation, Shape other) - => Do(operation, this, other); + => Do(operation, other, this); /// /// Perform a operation with shape. @@ -118,7 +118,7 @@ public GeneratedShape Do(ShapeOperation operation, Shape other) /// /// public GeneratedShape Union(Shape other) - => Union(this, other); + => Union(other, this); /// /// Perform a operation with shape. @@ -126,7 +126,7 @@ public GeneratedShape Union(Shape other) /// /// public GeneratedShape Subtract(Shape other) - => Subtract(this, other); + => Subtract(other, this); /// /// Perform a operation with shape. @@ -134,7 +134,7 @@ public GeneratedShape Subtract(Shape other) /// /// public GeneratedShape Intersect(Shape other) - => Intersect(this, other); + => Intersect(other, this); /// /// Create polygons of the .