quads
- Geometry ToolsThis package is a collection of quad geometry creation and manipulation tools. They can be used agnostic to any given library as they only operate on simple arrays and objects. Please note that this package is an early release, and the APIs may stabilize over time. More rigorous testing is also in the works.
This is a complicated math word that means an object with { positions, cells }
. The
word mesh
is used for convenience in this module, and normals
are included with
this object.
// A single quad oriented facing up.
const mesh = {
positions: [[-1, 0, -1], [-1, 0, 1], [1, 0, 1], [1, 0, -1]],
normals: [[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0]],
cells: [[0, 1, 2, 3]]
}
Additional attributes may be added for one's own applications. For example:
mesh.colors = mesh.positions.map(p => [0, p.y, 0])
Type: Object
Properties
An array of 3 values representing a position [x, y, z].
Type: Array
In a simplicial complex, a cell is an array of of indices that refer to a position or
some other attribute like normals. Quads have 4 indices, and this module uses the
convention of [a, b, c, d]
with clockwise winding order.
b-------c
| |
| |
a-------d
Type: Array
An array of 3 values, [x, y, z] representing a surface normal. A valid normal has a length of 1. Normals are used for lighting calculation, and for knowing which way a surface is oriented in space. Many operation rely on valid normals.
Type: Array
Computes the average normal for a position given the connected cells.
Parameters
mesh
SimplicialComplex positionIndex
Number target
Array? = []normalCache
Map? A Map can be provided to cache intermediate normal computations.positionIndexToCells
Map? A Map where positionIndex is mapped to its cell, used primarily internally.Returns Normal target
Clones a cell. Returns the new cell.
Parameters
mesh
SimplicialComplex cell
Cell Returns Cell cloned cell
Computes the center of a single cell.
Parameters
mesh
SimplicialComplex cell
Cell Returns Position center
Computes all of the centers of all the cells.
Parameters
mesh
SimplicialComplex Returns Array<Position> centers
Updates all of the normals for all the positions using #averageNormalForPosition. If a normal doesn't exist, then it is created.
Parameters
mesh
SimplicialComplex Returns SimplicialComplex
Creates a quad box of the given dimensions. This box will render as a
smoothed out box, as the normals are averaged. This is typically used for a
starting place for subdividing or extrusion operations. If the
optionalMesh
object is passed, then the box will be created inside of
that simplicial complex, otherwise a new mesh simplicial complex will be
generated.
Parameters
Returns SimplicialComplex
Creates a quad box of the given dimensions, but with non-joined positions. This box renders as a flat shaded box. If the optionalMesh object is passed, then the box will be created inside of that simplicial complex, otherwise a new mesh simplicial complex will be generated.
Parameters
Returns SimplicialComplex
Create a quad with options. If the optionalMesh object is passed, then the quad will be created inside of that simplicial complex, otherwise a new mesh simplicial complex will be generated. Both the mesh simplicial complex and the created cell are returned in an object.
Parameters
options
Object mesh
SimplicialComplex?= {} Examples
Usage:
const {mesh, cell} = createQuad({ positions: [[-1, 0, -1], [-1, 0, 1], [1, 0, 1], [1, 0, -1]] })
const {mesh, cell} = createQuad({ w: 1, h: 1 })
const {mesh, cell} = createQuad()
Returns Object {mesh, cell}
Returns an elements array using the given ArrayType
, which can be used by WebGL.
Parameters
mesh
SimplicialComplex drawMode
String?= 'triangles' ArrayType
typeof?= Uint16Array Returns Array Elements using the given ArrayType
, which can be used by WebGL.
Given a target cell, first inset it, then move it along the cell's normal outwards by a given distance.
Parameters
mesh
SimplicialComplex cell
Cell insetT
Number Value ranged from 0
to 1
, defaults to 0
extrude
Number Distance to extrude, defaults to 0
Given a target cell, first inset it, then move it along the cell's normal outwards by a given distance, but all new geometry generated will not share positions.
Parameters
mesh
SimplicialComplex cell
Cell insetT
Number = 0, ranged from 0
(the edge) to 1
(the center).extrude
Number = 0, the distance to extrude out.Flip a cell's normal to point the other way. Returns the cell.
Parameters
mesh
SimplicialComplex cell
Cell Returns Cell The cell
Find a cell given two position indices. Optionally provide a previousCell
that will not be matched against. Returns the first cell that matches.
Parameters
mesh
SimplicialComplex positionIndexA
Number positionIndexB
Number previousCell
Cell? Optional will not be matched againstReturns Cell
Compute a cell's normal regardless of it's neighboring cells.
Parameters
mesh
SimplicialComplex cell
Cell target
Normal? = []Returns Normal The target normal.
Given a position index, find any cells that include it.
Parameters
Returns Array<Cell> The target cells.
Computes the center of a cell.
Parameters
mesh
SimplicialComplex cell
Cell target
Position?= [] Returns Position center
Gets a loop of cells. Given a single cell, start walking in both directions to select a loop. .
Parameters
mesh
SimplicialComplex cell
Cell type
String can either be "cells"
, "positions"
, or "normals"
.opposite
Boolean will walk in the opposite direction, e.g. up and down, versus left and rightReturns Array an array according to the type
.
Get all newly created geometry of the given type from whatever arbitrary operations were done on the mesh. This assumes new geometry was created and not destroyed.
Parameters
Examples
Usage:
const extrudedCells = quad.getNewGeometry(mesh, "cells", () => {
quad.extrude(mesh, tipCell, 0.5, 3)
});
Returns Array
Inset a cell some value between 0
(its edges) and 1
(its center).
b----------c
|\ q1 /|
| \ / |
| f----g |
|q0| tC |q2| tc = targetCell
| e----h |
| / \ |
|/ q3 \|
a----------d
Parameters
mesh
SimplicialComplex cell
Cell t
Number Specifies where the split should be. Ranged from 0
to 1
, defaults to 0
.Returns Array<Cell> cells [q0, q1, q2, q3, targetCell]
Inset a cell some value between 0
(its edges) and 1
(its center), but
keep the new cells disjoint so they do not share any positions.
bT----------cT
bL \ qT / cR
|\ \ / /|
| \ fT----gT / |
| fL fM----gM gR |
|qL| | tC | |qR| tC = targetCell
| eL eM----hM hR |
| / eB----hB \ |
|/ / \ \|
aL / qB \ dR
aB----------dB
Parameters
mesh
SimplicialComplex cell
Cell t
Number? value between 0 - 1 (optional, default 0
)Returns Array<Cell> cells [qL, qT, qR, qB, targetCell]
.
Given a cell, walk a loop and inset the loop, where 0 is the inset being on the edge, and 1 the inset being in the enter. Setting opposite to true will make the cell walk the loop in the opposite direction, e.g. up/down rather than left/right.
*----*----*----*----*----*----*----*----*----*
| | | | | | | | | |
| | |<---|----|----|----|--->| | |
| | | | |cell| | | | |
| | |<---|----|----|----|--->| | |
| | | | | | | | | |
*----*----*----*----*----*----*----*----*----*
Parameters
mesh
SimplicialComplex cell
Cell t
Number?= 0.5 Specifies where the split should be. Ranged from 0
to 1
opposite
Boolean will walk in the opposite direction, e.g. up and down, versus left and rightReturns SimplicialComplex
Combine all positions together and recompute the normals.
Parameters
mesh
SimplicialComplex Returns SimplicialComplex
Clone all existing geometry, and mirror it about the given axis.
Parameters
mesh
SimplicialComplex cells
Cell axis
Number is either 0
, 1
, or 2
, which represents the x
, y
, and z
axis respectively.Split a cell horizontally.
b--------c
| |
ab------cd
| |
a--------d
Parameters
mesh
SimplicialComplex cell
Cell t
Number?= 0.5 Specifies where the split should be. Ranged from 0
to 1
targetCell
Split a cell horizontally into two new disconnected cells.
b--------c
| |
ab1----cd1
ab2----cd2
| target |
a--------d
Parameters
mesh
SimplicialComplex cell
Cell t
Number?= 0.5 Specifies where the split should be. Ranged from 0
to 1
targetCell
Given a cell, walk along the mesh in both directions and split the cell.
*--------*--------*--------*--------*--------*--------*--------*
| | | | | | | |
* *<-------*--------*--cell--*--------*------->* *
| | | | | | | |
*--------*--------*--------*--------*--------*--------*--------*
Parameters
mesh
SimplicialComplex cell
Cell t
Number?= 0.5 Specifies where the split should be. Ranged from 0
to 1
opposite
Boolean will walk in the opposite direction, e.g. up and down, versus left and rightReturns SimplicialComplex
Split a cell horizontally.
b---bc---c
| | |
| | |
a---ad---d
Parameters
mesh
SimplicialComplex cell
Cell t
Number?= 0.5 Specifies where the split should be. Ranged from 0
to 1
, defaults to 0.5
.targetCell
Split a cell horizontally into two new disconnected cells.
b---bc1 bc2---c
| | | |
| | | |
a---ad1 ad2---d
Parameters
mesh
SimplicialComplex cell
Cell t
Number?= 0.5 Specifies where the split should be. Ranged from 0
to 1
, defaults to 0.5
.targetCell
Use catmull clark subdivision to smooth out the geometry. All normals will be recomputed. Under the hood this is a convenience function for the module gl-catmull-clark.
Parameters
mesh
SimplicialComplex subdivisions
Number positions
Array<Position>?= mesh.positions cells
Cell?= mesh.cells Returns SimplicialComplex
Updates all of the normals for all the positions using #averageNormalForPosition. If a normal doesn't exist, then it is created.
Parameters
mesh
SimplicialComplex cell
Cell Returns SimplicialComplex
Split a cell horizontally.
b---bc---c
| | |
| | |
a---ad---d
Parameters
$0
Object quad
targetCell
Array t
Number Specifies where the split should be. Ranged from 0
to 1
_ref
Split a cell horizontally into two new disconnected cells.
b---bc1 bc2---c
| | | |
| | | |
a---ad1 ad2---d
Parameters
Split a cell horizontally.
b--------c
| |
ab------cd
| |
a--------d
Parameters
$0.positions
Array $0.cells
Array targetCell
Array t
Number Specifies where the split should be. Ranged from 0
to 1
_ref2
Split a cell horizontally into two new disconnected cells.
b--------c
| |
ab1----cd1
ab2----cd2
| target |
a--------d
Parameters
Inset a cell some value between 0
(its edges) and 1
(its center).
b----------c
|\ q1 /|
| \ / |
| f----g |
|q0| tQ |q2|
| e----h |
| / \ |
|/ q3 \|
a----------d
Parameters
Returns Array cells [q0, q1, q2, q3, tC]
where tC
is the targetCell
.
Given a target cell, first inset it, then move it along the cell's normal outwards by a given distance.
Parameters
Computes the average normal for a position given the connected cells.
Parameters
mesh
Object positionIndex
Number target
Array? = []normalCache
Map? = new Map() can be provided to cache intermediate normal computations.positionIndexToCells
Number Returns any the targetNormal
Inset a cell some value between 0
(its edges) and 1
(its center), but
keep the new cells disjoint so they do not share any positions.
bT----------cT
bL \ qT / cR
|\ \ / /|
| \ fT----gT / |
| fL fM----gM gR |
|qL| | tC | |qR| tC = targetCell
| eL eM----hM hR |
| / eB----hB \ |
|/ / \ \|
aL / qB \ dR
aB----------dB
Parameters
Returns Array cells [q0, q1, q2, q3, tC]
where tC
is the targetCell
.
Given a target cell, first inset it, then move it along the cell's normal outwards by a given distance, but all new geometry generated will not share positions.
Parameters
Computes the center of a cell
Parameters
Returns Array the targetPosition
Clones a cell. Returns the new cell.
Parameters
Returns Array a new cell
Updates all of the normals for all the positions using #averageNormalForPosition. If a normal doesn't exist, then it is created.
Parameters
Returns Object mesh
Compute a cell's normal regardless of it's neighboring cells.
Parameters
Returns Array The target normal.
Given a position index, find any cells that include it.
Parameters
Returns Array The target cells.
Flip a cell's normal to point the other way. Returns the cell.
Parameters
Returns Array The cell
Create a quad with options. If the optionalMesh object is passed, then the quad will be created inside of that simplicial complex, otherwise a new mesh simplicial complex will be generated. Both the mesh simplicial complex and the created cell are returned in an object.
Parameters
Examples
Usage:
const {mesh, cell} = createQuad({ positions: [[-1, 0, -1], [-1, 0, 1], [1, 0, 1], [1, 0, -1]] })
const {mesh, cell} = createQuad({ w: 1, h: 1 })
const {mesh, cell} = createQuad()
Returns Object {mesh, cell}
Creates a quad box of the given dimensions, but with non-joined positions. This box renders as a flat shaded box. If the optionalMesh object is passed, then the box will be created inside of that simplicial complex, otherwise a new mesh simplicial complex will be generated.
Parameters
Returns Object a simplicial complex
Creates a quad box of the given dimensions. This box will render as a
smoothed out box, as the normals are averaged. This is typically used for a
starting place for subdividing or extrusion operations. If the
optionalMesh
object is passed, then the box will be created inside of
that simplicial complex, otherwise a new mesh simplicial complex will be
generated.
Parameters
Returns Object a simplicial complex
Combine all positions together and recompute the normals.
Parameters
mesh
Object Returns Object mesh
Returns an elements array using the given ArrayType
, which can be used by WebGL.
Parameters
Returns Array Elements using the given ArrayType
, which can be used by WebGL.
Updates all of the normals for all the positions using #averageNormalForPosition. If a normal doesn't exist, then it is created.
Parameters
mesh
Object Returns Object The mesh
Given a cell, walk along the mesh in both directions and split the cell.
*--------*--------*--------*--------*--------*--------*--------*
| | | | | | | |
* *<-------*--------*--cell--*--------*------->* *
| | | | | | | |
*--------*--------*--------*--------*--------*--------*--------*
Parameters
mesh
Object cell
Array t
Number Specifies where the split should be. Ranged from 0
to 1
opposite
Boolean will walk in the opposite direction, e.g. up and down, versus left and rightReturns Object mesh
Find a cell given two position indices. Optionally provide a previousCell
that will not be matched against. Returns the first cell that matches.
Parameters
mesh
Object positionIndexA
Number positionIndexB
Number previousCell
Array? Optional will not be matched againstReturns Array Elements using the given ArrayType
, which can be used by WebGL.
Get all newly created geometry of the given type from whatever arbitrary operations were done on the mesh. This assumes new geometry was created and not destroyed.
Parameters
Examples
Usage:
const extrudedCells = quad.getNewGeometry(mesh, "cells", () => {
quad.extrude(mesh, tipCell, 0.5, 3)
});
Returns Array
Use catmull clark subdivision to smooth out the geometry. All normals will be recomputed. Under the hood this is a convenience function for the module gl-catmull-clark.
Parameters
Returns Object mesh
Computes all of the centers of all the cells.
Parameters
mesh
Object Returns any A new array
Computes the center of a single cell.
Parameters
Returns any A new array
Given a cell, walk a loop and inset the loop, where 0 is the inset being on the edge, and 1 the inset being in the enter. Setting opposite to true will make the cell walk the loop in the opposite direction, e.g. up/down rather than left/right.
*----*----*----*----*----*----*----*----*----*
| | | | | | | | | |
| | |<---|----|----|----|--->| | |
| | | | |cell| | | | |
| | |<---|----|----|----|--->| | |
| | | | | | | | | |
*----*----*----*----*----*----*----*----*----*
Parameters
mesh
Object cell
Array t
Number Specifies where the split should be. Ranged from 0
to 1
opposite
Boolean will walk in the opposite direction, e.g. up and down, versus left and rightReturns Object mesh
Gets a loop of cells. Given a single cell, start walking in both directions to select a loop. .
Parameters
mesh
Object cell
Array type
String can either be "cells"
, "positions"
, or "normals"
.opposite
Boolean will walk in the opposite direction, e.g. up and down, versus left and rightReturns Array an array according to the type
.
Clone all existing geometry, and mirror it about the given axis.
Parameters