gregtatum / quads

https://www.npmjs.com/package/quads
MIT License
35 stars 0 forks source link

quads - Geometry Tools

This 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.

Types

SimplicialComplex

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

Position

An array of 3 values representing a position [x, y, z].

Type: Array

Cell

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

Normal

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

API

averageNormalForPosition

Computes the average normal for a position given the connected cells.

Parameters

Returns Normal target

clone

Clones a cell. Returns the new cell.

Parameters

Returns Cell cloned cell

computeCellCenter

Computes the center of a single cell.

Parameters

Returns Position center

computeCenterPositions

Computes all of the centers of all the cells.

Parameters

Returns Array<Position> centers

computeNormals

Updates all of the normals for all the positions using #averageNormalForPosition. If a normal doesn't exist, then it is created.

Parameters

Returns SimplicialComplex

createBox

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

createBoxDisjoint

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

createQuad

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}

elementsFromQuads

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.

extrude

Given a target cell, first inset it, then move it along the cell's normal outwards by a given distance.

Parameters

extrudeDisjoint

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

flip

Flip a cell's normal to point the other way. Returns the cell.

Parameters

Returns Cell The cell

getCellFromEdge

Find a cell given two position indices. Optionally provide a previousCell that will not be matched against. Returns the first cell that matches.

Parameters

Returns Cell

getCellNormal

Compute a cell's normal regardless of it's neighboring cells.

Parameters

Returns Normal The target normal.

getCellsFromPositionIndex

Given a position index, find any cells that include it.

Parameters

Returns Array<Cell> The target cells.

getCenter

Computes the center of a cell.

Parameters

Returns Position center

getLoop

Gets a loop of cells. Given a single cell, start walking in both directions to select a loop. .

Parameters

Returns Array an array according to the type.

getNewGeometry

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

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

Returns Array<Cell> cells [q0, q1, q2, q3, targetCell]

insetDisjoint

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<Cell> cells [qL, qT, qR, qB, targetCell].

insetLoop

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

Returns SimplicialComplex

mergePositions

Combine all positions together and recompute the normals.

Parameters

Returns SimplicialComplex

mirror

Clone all existing geometry, and mirror it about the given axis.

Parameters

splitHorizontal

Split a cell horizontally.

 b--------c
 |        |
 ab------cd
 |        |
 a--------d

Parameters

splitHorizontalDisjoint

Split a cell horizontally into two new disconnected cells.

 b--------c
 |        |
 ab1----cd1
 ab2----cd2
 | target |
 a--------d

Parameters

splitLoop

Given a cell, walk along the mesh in both directions and split the cell.

*--------*--------*--------*--------*--------*--------*--------*
|        |        |        |        |        |        |        |
*        *<-------*--------*--cell--*--------*------->*        *
|        |        |        |        |        |        |        |
*--------*--------*--------*--------*--------*--------*--------*

Parameters

Returns SimplicialComplex

splitVertical

Split a cell horizontally.

 b---bc---c
 |   |    |
 |   |    |
 a---ad---d

Parameters

splitVerticalDisjoint

Split a cell horizontally into two new disconnected cells.

 b---bc1  bc2---c
 |     |  |     |
 |     |  |     |
 a---ad1  ad2---d

Parameters

subdivide

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 SimplicialComplex

updateNormals

Updates all of the normals for all the positions using #averageNormalForPosition. If a normal doesn't exist, then it is created.

Parameters

Returns SimplicialComplex

Three

splitVertical

Split a cell horizontally.

 b---bc---c
 |   |    |
 |   |    |
 a---ad---d

Parameters

splitVerticalDisjoint

Split a cell horizontally into two new disconnected cells.

 b---bc1  bc2---c
 |     |  |     |
 |     |  |     |
 a---ad1  ad2---d

Parameters

splitHorizontal

Split a cell horizontally.

 b--------c
 |        |
 ab------cd
 |        |
 a--------d

Parameters

splitHorizontalDisjoint

Split a cell horizontally into two new disconnected cells.

 b--------c
 |        |
 ab1----cd1
 ab2----cd2
 | target |
 a--------d

Parameters

inset

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.

extrude

Given a target cell, first inset it, then move it along the cell's normal outwards by a given distance.

Parameters

averageNormalForPosition

Computes the average normal for a position given the connected cells.

Parameters

Returns any the targetNormal

insetDisjoint

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.

extrudeDisjoint

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

getCenter

Computes the center of a cell

Parameters

Returns Array the targetPosition

clone

Clones a cell. Returns the new cell.

Parameters

Returns Array a new cell

updateNormals

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

getCellNormal

Compute a cell's normal regardless of it's neighboring cells.

Parameters

Returns Array The target normal.

getCellsFromPositionIndex

Given a position index, find any cells that include it.

Parameters

Returns Array The target cells.

flip

Flip a cell's normal to point the other way. Returns the cell.

Parameters

Returns Array The cell

createQuad

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}

createBoxDisjoint

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

createBox

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

mergePositions

Combine all positions together and recompute the normals.

Parameters

Returns Object mesh

elementsFromQuads

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.

computeNormals

Updates all of the normals for all the positions using #averageNormalForPosition. If a normal doesn't exist, then it is created.

Parameters

Returns Object The mesh

splitLoop

Given a cell, walk along the mesh in both directions and split the cell.

*--------*--------*--------*--------*--------*--------*--------*
|        |        |        |        |        |        |        |
*        *<-------*--------*--cell--*--------*------->*        *
|        |        |        |        |        |        |        |
*--------*--------*--------*--------*--------*--------*--------*

Parameters

Returns Object mesh

getCellFromEdge

Find a cell given two position indices. Optionally provide a previousCell that will not be matched against. Returns the first cell that matches.

Parameters

Returns Array Elements using the given ArrayType, which can be used by WebGL.

getNewGeometry

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

subdivide

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

computeCenterPositions

Computes all of the centers of all the cells.

Parameters

Returns any A new array

computeCellCenter

Computes the center of a single cell.

Parameters

Returns any A new array

insetLoop

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

Returns Object mesh

getLoop

Gets a loop of cells. Given a single cell, start walking in both directions to select a loop. .

Parameters

Returns Array an array according to the type.

mirror

Clone all existing geometry, and mirror it about the given axis.

Parameters