extends BrushShape
class_name CylinderShape
## A cylinder standing on the aimed surface: an N-gon prism inscribed in the bounds,
## its axis along the surface normal (TrenchBroom BasicShapes Cylinder). ONE convex
## brush — a regular N-gon prism is convex — so it is a single journal record.
func id() -> String:
return "cylinder"
func params() -> Array:
return [{"id": "segments", "label": "Sides", "type": "int", "default": 12,
"min": 3, "max": 32, "step": 1, "tip": "Sides of the polygon. More = rounder."}]
## The two in-surface axes (any order) for the surface axis `vert`.
static func across(vert: int) -> Array:
return [(vert + 1) % 3, (vert + 2) % 3]
## An ellipse of `n` points inscribed in [lo, hi] across axes a / b, as 2D points.
static func ring2d(lo: Vector3, hi: Vector3, a: int, b: int, n: int) -> Array[Vector2]:
var c := Vector2((lo[a] + hi[a]) * 0.5, (lo[b] + hi[b]) * 0.5)
var r := Vector2((hi[a] - lo[a]) * 0.5, (hi[b] - lo[b]) * 0.5)
var out: Array[Vector2] = []
for i in n:
var t := TAU * float(i) / float(n)
out.append(c + Vector2(cos(t) * r.x, sin(t) * r.y))
return out
func pieces(lo: Vector3, hi: Vector3, ctx: Dictionary) -> Array:
var vert: int = int(ctx["axis"])
var ab := across(vert)
var n := clampi(int(param(ctx, "segments")), 3, 32)
if hi[ab[0]] - lo[ab[0]] < 1.0e-4 or hi[ab[1]] - lo[ab[1]] < 1.0e-4 or hi[vert] - lo[vert] < 1.0e-4:
return []
var piece := ShapeKit.prism_piece(ring2d(lo, hi, ab[0], ab[1], n), ab[0], ab[1], vert, lo[vert], hi[vert])
return [piece] if not piece.is_empty() else []
func describe(_lo: Vector3, _hi: Vector3, ctx: Dictionary, size_text: String) -> String:
return "cylinder, %d sides, %s" % [clampi(int(param(ctx, "segments")), 3, 32), size_text]