From 794fb0b4f4eed6e052803f14066dd2a16e7a2e05 Mon Sep 17 00:00:00 2001 From: Kaydax Date: Tue, 30 Nov 2021 23:43:45 -0500 Subject: [PATCH 1/5] Fix sphere top and bottom vertexes to account for radius as to not generate a spike --- src/CSG/Geometry/Sphere.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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) From 3e127ba1d60728925d1f84483a9e398558e18f23 Mon Sep 17 00:00:00 2001 From: arduano Date: Thu, 2 Dec 2021 12:15:12 +1100 Subject: [PATCH 2/5] fixed your cylinder --- src/CSG/Geometry/Cylinder.cs | 63 ++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/src/CSG/Geometry/Cylinder.cs b/src/CSG/Geometry/Cylinder.cs index 1813884..13374cf 100644 --- a/src/CSG/Geometry/Cylinder.cs +++ b/src/CSG/Geometry/Cylinder.cs @@ -13,37 +13,60 @@ 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)); + } - 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); + var mat = Matrix4x4.CreateFromAxisAngle(dir, angle); + var normal = Vector3.Transform(Vector3.UnitZ, mat); + var rotated = normal * radius; - 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)); } } } From 164db71003a4a7913c78456dc2f90240134df351 Mon Sep 17 00:00:00 2001 From: Kaydax Date: Thu, 2 Dec 2021 17:46:20 -0500 Subject: [PATCH 3/5] Make cube scale more in line with how other Geometry scales --- src/CSG/Geometry/Cube.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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); } } } From cd99194a5341ff13b8766769957a8bc4d67568ce Mon Sep 17 00:00:00 2001 From: arduano Date: Fri, 3 Dec 2021 10:34:13 +1100 Subject: [PATCH 4/5] Fixed rotation --- src/CSG/Geometry/Cylinder.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CSG/Geometry/Cylinder.cs b/src/CSG/Geometry/Cylinder.cs index 13374cf..dc9a917 100644 --- a/src/CSG/Geometry/Cylinder.cs +++ b/src/CSG/Geometry/Cylinder.cs @@ -35,12 +35,13 @@ 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)); + for (int i = 0; i < tessellation; ++i) { float angle = i * Algorithms.Helpers.TwoPi / tessellation; - var mat = Matrix4x4.CreateFromAxisAngle(dir, angle); - var normal = Vector3.Transform(Vector3.UnitZ, mat); + var normal = Vector3.Transform(perp, Quaternion.CreateFromAxisAngle(dir, angle)); var rotated = normal * radius; builder.AddVertex(rotated + start, dir); // Top surface From 1184688db43df242c8f7e38b7c6806ec10b4b010 Mon Sep 17 00:00:00 2001 From: Kaydax Date: Thu, 2 Dec 2021 18:59:05 -0500 Subject: [PATCH 5/5] Flip input order on operations so you can do them in order correctly --- src/CSG/Shape.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 .