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 .