Builtin Library
- ..
- .metadata264 B
- README.md4.5 KB
- init.luau9.5 KB
- merge.module
README.md
geometry.merge
Put values together by kind. Geometries are laid end to end; rasters are laid over one grid. With pack on, every geometry is first packed into a piece (instances.pack) and the result is a piece set for instances.to_points.
Geometries: the parts wired to a through h, then every part in parts, are joined by core.concat: each part's points, vertices and primitives after the ones before it, the links renumbered, point ids kept unique (each part's moved past the ids before it), the columns marked as holding point ids moved with them, and the detail holding the union of the parts' detail (a name held with different values keeps the first part's value and is listed in report). The result carries every attribute any part carries. A part that lacks an attribute takes, for each of its elements:
- a numeric attribute (
Bool,Int,UInt,Float,Vec2,Vec3,Vec4,Color,Quat,Transform,Mat4): the value an element without the attribute has, cast to the type the first part with elements holds it as: the rest of the component field it feeds, or the identitypoints.posereads an instance attribute as (orientandrotunrotated,scaleandpscale1,up+Y,transandpivotzero), else zero in every lane. Two exceptions on the point class:idtakes the point's own place in its part (then moved like every id), and a column marked as holding point ids takes -1; - a text or record attribute (
String,Record,Mesh,Materialand the other value types): no value.
So a part merged without scale, pscale or orient poses as it did alone, and copies instances.to_points places on its points stand at full size. Any other numeric attribute a part lacks stands at zero on its elements: give every part the attribute before merging (attribute.set, or a write such as part.point.weight = 1 on the part that lacks it) when a missing value has to read as something else. An attribute held at two different widths is refused by name; one held as two types of one width is cast by value.
Merging piece sets: a piece set is a geometry of points, one point a piece, so merging piece sets (the pieces of several instances.pack calls) joins their points into one piece set holding every piece in laying-down order, the way merging any points does, and instances.to_points places each of its pieces once per target point. The group value each piece carries stays as it was written: instances.pack of a whole geometry with no name writes 0, so pieces packed one by one and merged all carry variant 0, and a match on variant then reads them as one value. Give each instances.pack a name, or merge the geometries with pack on, which numbers the pieces 0 upward across the whole merge (or names them from names).
Merging one kind answers that value; merging geometries and rasters together answers one value holding both, which io.output and io.export take.
Inputs
a...h(Geometry or Raster, optional). A part. Parts are laid down in socket order a through h, thenparts, whatever order they were wired in, so a's elements keep index 0 upward and each later part's are pushed past the ones before it.parts(List<Geometry or Raster>, optional). Any number of further parts, in list order, appended after the lettered ones.pack(Bool, default false). On, every geometry is packed before the merge exactly asinstances.packpacks a whole geometry (its own material): one piece point per geometry, carryinggroup. The result is a piece set.group(String, default "variant"). Withpack, the attribute each piece point carries: its name fromnames, else its 0-based index among the geometries. The same input and default asinstances.pack; empty writes none.names(List<String>, optional). Withpack, one name per geometry in the order they are laid down (a through h, thenparts). Unwired, each geometry takes its index. The names are all given or none.
Outputs
value(Geometry, Raster, or a value holding both). What the merge made.report(List). One row per detail attribute the geometries hold with different values.
local both = g.geometry.merge({ a = g.mesh.box({}), b = g.geometry.transform({ geometry = g.mesh.sphere({}), translate = vector.create(2, 0, 0) }) }).value
local kit = g.geometry.merge({ a = g.mesh.box({}), b = g.mesh.sphere({}), pack = true, names = { "crate", "ball" } }).value