Skip to main content

New primitive shapes

· 3 min read
Balaur

Ten 3D primitives and six 2D ones, paths given thickness, booleans in both dimensions, a cloner, and a word as a mesh.

Every object, one row per category

What landed

  • Primitives. Torus, pyramid, prism, tube, rounded cuboid; ellipse, star and ngon in 2D. segments, rings, sides, corner_radius on all of them.

    The primitives row

  • Paths. path2d and path3d assets. Extrude with a bevel, lathe, sweep along a rail, stroke.

    An arch extruded, a goblet revolved, a rail swept

  • Booleans. boolean3d and boolean2d over a node's children: union, difference, intersection. Operands stay editable; moving one recomputes. Booleans nest.

    Union, difference and intersection of a cube and a ball

  • In 2D. shape2d gained ellipse, star and ngon, and boolean2d joins, cuts and intersects filled outlines the same way. The 2D booleans run on i_overlay, which works in fixed-point integers and so lands on the same vertices on every platform.

    Ellipse, star, ngon and capsule; a rect and a circle joined, cut and intersected

  • Cloner. Linear, radial, grid. seed and random scatter the copies. A thousand copies are one draw call, custom materials included.

    A row, a ring and a scattered grid

  • Text. kind = "text" on a mesh asset: a word as geometry, counters kept as holes, sized in world units, sitting on its baseline.

  • Colours and morph targets. Both survive a glTF import now. A morph weight is a property, so a clip drives it as mesh/morph.<name>. Vertex colours reach a material that asks: features = { vertex_color = true }.

    A word as a mesh, and a triangle coloured per vertex

Why one mesher

  • A collider fitted to a torus is a torus, not the box around one.
  • A ray picks the shape that is drawn.
  • Tests measure meshes: closed, outward-facing, the exact volume a boolean should have.
  • Deterministic by construction: libm for the curves, and a BSP that is dot products and lerps with no transcendental to pin.
  • The meshers are the engine's own, not a renderer's and not parry's: core builds the triangles, and physics fits its colliders to them. Parry stays where it belongs, under the colliders and the geometry3d toolkit.
[[assets]]
id = "ring"
type = "mesh"
kind = "torus"
radius = 1.1
tube_radius = 0.28

[nodes.mesh]
source = "#ring"

[nodes.collider3d]
kind = "trimesh"
mesh = "#ring"

Try it

  • examples/objects: five rows, one per category, then the 2D layer, and the camera walks them. It runs in the browser too.
  • The manual and the generated asset and component references.