OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / maps / shapes / cylinder_shape.gd

45 lines · gd ref:
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]