math 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +1605 -0
- package/LICENSE +21 -0
- package/README.md +197 -0
- package/dist/color/color.js +136 -0
- package/dist/color/color.js.map +1 -0
- package/dist/color/colorspace.js +43 -0
- package/dist/color/colorspace.js.map +1 -0
- package/dist/color/hsl.js +123 -0
- package/dist/color/hsl.js.map +1 -0
- package/dist/color/index.js +7 -0
- package/dist/color/index.js.map +1 -0
- package/dist/color/parse.js +276 -0
- package/dist/color/parse.js.map +1 -0
- package/dist/core/angle.js +43 -0
- package/dist/core/angle.js.map +1 -0
- package/dist/core/euler.js +212 -0
- package/dist/core/euler.js.map +1 -0
- package/dist/core/mat2.js +385 -0
- package/dist/core/mat2.js.map +1 -0
- package/dist/core/mat2d.js +422 -0
- package/dist/core/mat2d.js.map +1 -0
- package/dist/core/mat3.js +749 -0
- package/dist/core/mat3.js.map +1 -0
- package/dist/core/mat4.js +2197 -0
- package/dist/core/mat4.js.map +1 -0
- package/dist/core/polar.js +200 -0
- package/dist/core/polar.js.map +1 -0
- package/dist/core/quat.js +730 -0
- package/dist/core/quat.js.map +1 -0
- package/dist/core/quat2.js +883 -0
- package/dist/core/quat2.js.map +1 -0
- package/dist/core/scalar.js +112 -0
- package/dist/core/scalar.js.map +1 -0
- package/dist/core/spherical.js +248 -0
- package/dist/core/spherical.js.map +1 -0
- package/dist/core/vec2.js +597 -0
- package/dist/core/vec2.js.map +1 -0
- package/dist/core/vec3.js +916 -0
- package/dist/core/vec3.js.map +1 -0
- package/dist/core/vec4.js +573 -0
- package/dist/core/vec4.js.map +1 -0
- package/dist/geometry/circumcircle.js +39 -0
- package/dist/geometry/circumcircle.js.map +1 -0
- package/dist/geometry/index.js +6 -0
- package/dist/geometry/index.js.map +1 -0
- package/dist/geometry/polygon2-decompose.js +411 -0
- package/dist/geometry/polygon2-decompose.js.map +1 -0
- package/dist/geometry/polygon2-triangulate.js +222 -0
- package/dist/geometry/polygon2-triangulate.js.map +1 -0
- package/dist/geometry/quickhull2.js +123 -0
- package/dist/geometry/quickhull2.js.map +1 -0
- package/dist/geometry/quickhull3.js +605 -0
- package/dist/geometry/quickhull3.js.map +1 -0
- package/dist/ik/fabrik2.js +675 -0
- package/dist/ik/fabrik2.js.map +1 -0
- package/dist/ik/fabrik3.js +912 -0
- package/dist/ik/fabrik3.js.map +1 -0
- package/dist/ik/index.js +5 -0
- package/dist/ik/index.js.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/noise/fractal.js +185 -0
- package/dist/noise/fractal.js.map +1 -0
- package/dist/noise/index.js +16 -0
- package/dist/noise/index.js.map +1 -0
- package/dist/noise/perlin2d.js +50 -0
- package/dist/noise/perlin2d.js.map +1 -0
- package/dist/noise/perlin3d.js +72 -0
- package/dist/noise/perlin3d.js.map +1 -0
- package/dist/noise/permutation.js +120 -0
- package/dist/noise/permutation.js.map +1 -0
- package/dist/noise/simplex2d.js +84 -0
- package/dist/noise/simplex2d.js.map +1 -0
- package/dist/noise/simplex3d.js +147 -0
- package/dist/noise/simplex3d.js.map +1 -0
- package/dist/noise/simplex4d.js +149 -0
- package/dist/noise/simplex4d.js.map +1 -0
- package/dist/noise/worley2d.js +50 -0
- package/dist/noise/worley2d.js.map +1 -0
- package/dist/noise/worley3d.js +61 -0
- package/dist/noise/worley3d.js.map +1 -0
- package/dist/random/index.js +9 -0
- package/dist/random/index.js.map +1 -0
- package/dist/random/isaac32.js +164 -0
- package/dist/random/isaac32.js.map +1 -0
- package/dist/random/isaac64.js +215 -0
- package/dist/random/isaac64.js.map +1 -0
- package/dist/random/mulberry32.js +48 -0
- package/dist/random/mulberry32.js.map +1 -0
- package/dist/random/random.js +120 -0
- package/dist/random/random.js.map +1 -0
- package/dist/shapes/box2.js +300 -0
- package/dist/shapes/box2.js.map +1 -0
- package/dist/shapes/box3.js +550 -0
- package/dist/shapes/box3.js.map +1 -0
- package/dist/shapes/circle.js +6 -0
- package/dist/shapes/circle.js.map +1 -0
- package/dist/shapes/frustum.js +662 -0
- package/dist/shapes/frustum.js.map +1 -0
- package/dist/shapes/index.js +25 -0
- package/dist/shapes/index.js.map +1 -0
- package/dist/shapes/obb3.js +557 -0
- package/dist/shapes/obb3.js.map +1 -0
- package/dist/shapes/plane3.js +267 -0
- package/dist/shapes/plane3.js.map +1 -0
- package/dist/shapes/polygon2.js +451 -0
- package/dist/shapes/polygon2.js.map +1 -0
- package/dist/shapes/raycast3.js +164 -0
- package/dist/shapes/raycast3.js.map +1 -0
- package/dist/shapes/segment2.js +82 -0
- package/dist/shapes/segment2.js.map +1 -0
- package/dist/shapes/sphere.js +23 -0
- package/dist/shapes/sphere.js.map +1 -0
- package/dist/shapes/triangle2.js +79 -0
- package/dist/shapes/triangle2.js.map +1 -0
- package/dist/shapes/triangle3.js +60 -0
- package/dist/shapes/triangle3.js.map +1 -0
- package/dist/src/color/color.d.ts +50 -0
- package/dist/src/color/colorspace.d.ts +15 -0
- package/dist/src/color/hsl.d.ts +28 -0
- package/dist/src/color/index.d.ts +5 -0
- package/dist/src/color/parse.d.ts +15 -0
- package/dist/src/core/angle.d.ts +29 -0
- package/dist/src/core/arrays.d.ts +4 -0
- package/dist/src/core/euler.d.ts +78 -0
- package/dist/src/core/index.d.ts +27 -0
- package/dist/src/core/mat2.d.ts +217 -0
- package/dist/src/core/mat2d.d.ts +218 -0
- package/dist/src/core/mat3.d.ts +295 -0
- package/dist/src/core/mat4.d.ts +667 -0
- package/dist/src/core/polar.d.ts +151 -0
- package/dist/src/core/quat.d.ts +370 -0
- package/dist/src/core/quat2.d.ts +344 -0
- package/dist/src/core/scalar.d.ts +75 -0
- package/dist/src/core/spherical.d.ts +165 -0
- package/dist/src/core/vec2.d.ts +403 -0
- package/dist/src/core/vec3.d.ts +493 -0
- package/dist/src/core/vec4.d.ts +336 -0
- package/dist/src/geometry/circumcircle.d.ts +9 -0
- package/dist/src/geometry/index.d.ts +5 -0
- package/dist/src/geometry/polygon2-decompose.d.ts +25 -0
- package/dist/src/geometry/polygon2-triangulate.d.ts +15 -0
- package/dist/src/geometry/quickhull2.d.ts +10 -0
- package/dist/src/geometry/quickhull3.d.ts +27 -0
- package/dist/src/ik/fabrik2.d.ts +314 -0
- package/dist/src/ik/fabrik3.d.ts +371 -0
- package/dist/src/ik/index.d.ts +2 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/noise/fractal.d.ts +95 -0
- package/dist/src/noise/index.d.ts +9 -0
- package/dist/src/noise/perlin2d.d.ts +19 -0
- package/dist/src/noise/perlin3d.d.ts +20 -0
- package/dist/src/noise/permutation.d.ts +22 -0
- package/dist/src/noise/simplex2d.d.ts +19 -0
- package/dist/src/noise/simplex3d.d.ts +20 -0
- package/dist/src/noise/simplex4d.d.ts +24 -0
- package/dist/src/noise/worley2d.d.ts +22 -0
- package/dist/src/noise/worley3d.d.ts +23 -0
- package/dist/src/random/index.d.ts +8 -0
- package/dist/src/random/isaac32.d.ts +62 -0
- package/dist/src/random/isaac64.d.ts +75 -0
- package/dist/src/random/mulberry32.d.ts +43 -0
- package/dist/src/random/random.d.ts +67 -0
- package/dist/src/shapes/box2.d.ts +174 -0
- package/dist/src/shapes/box3.d.ts +213 -0
- package/dist/src/shapes/circle.d.ts +7 -0
- package/dist/src/shapes/frustum.d.ts +147 -0
- package/dist/src/shapes/index.d.ts +20 -0
- package/dist/src/shapes/obb3.d.ts +105 -0
- package/dist/src/shapes/plane3.d.ts +130 -0
- package/dist/src/shapes/polygon2.d.ts +155 -0
- package/dist/src/shapes/raycast3.d.ts +42 -0
- package/dist/src/shapes/segment2.d.ts +34 -0
- package/dist/src/shapes/sphere.d.ts +19 -0
- package/dist/src/shapes/triangle2.d.ts +53 -0
- package/dist/src/shapes/triangle3.d.ts +29 -0
- package/dist/src/time/easing.d.ts +21 -0
- package/dist/src/time/index.d.ts +6 -0
- package/dist/src/time/spring-core.d.ts +15 -0
- package/dist/src/time/spring.d.ts +36 -0
- package/dist/src/time/spring2.d.ts +11 -0
- package/dist/src/time/spring3.d.ts +11 -0
- package/dist/src/time/spring4.d.ts +11 -0
- package/dist/time/easing.js +24 -0
- package/dist/time/easing.js.map +1 -0
- package/dist/time/index.js +11 -0
- package/dist/time/index.js.map +1 -0
- package/dist/time/spring-core.js +48 -0
- package/dist/time/spring-core.js.map +1 -0
- package/dist/time/spring.js +62 -0
- package/dist/time/spring.js.map +1 -0
- package/dist/time/spring2.js +31 -0
- package/dist/time/spring2.js.map +1 -0
- package/dist/time/spring3.js +32 -0
- package/dist/time/spring3.js.map +1 -0
- package/dist/time/spring4.js +32 -0
- package/dist/time/spring4.js.map +1 -0
- package/package.json +90 -16
- package/skills/math/SKILL.md +140 -0
- package/AUTHORS +0 -1
- package/Cakefile +0 -28
- package/math.coffee +0 -112
- package/math.js +0 -141
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fabrik3.js","sources":["../../src/ik/fabrik3.ts"],"sourcesContent":["import { type Mat3, mat3, type Quat, quat, type Vec3, vec3 } from '../core';\n\n// FABRIK (Forward And Backward Reaching Inverse Kinematics) for 3D chains.\n//\n// Two passes, each preserving every bone length exactly: `forward` drags the chain onto the target\n// from the effector back, `backward` pushes it out from a pinned base. Both are exported, because\n// `forward` alone with no base pin is a follower - a rope or tentacle whose head leads and whose\n// body trails - and that wants one pass per frame rather than a converged solve.\n//\n// The constraint model follows Caliko, the reference implementation accompanying Aristidou &\n// Lasenby (2011), \"FABRIK: A fast, iterative solver for the Inverse Kinematics problem\".\n\n/**\n * How a joint may rotate relative to the bone before it.\n *\n * A {@link JointType.BALL} joint with a `rotor` of PI is unconstrained, which is the default, so\n * there is no separate \"no constraint\" type.\n */\nexport enum JointType {\n /** Rotates freely within a cone of `rotor` radians about the previous bone's direction. */\n BALL = 0,\n /** Rotates only in the plane perpendicular to `rotationAxis`, which is in world space. */\n GLOBAL_HINGE = 1,\n /**\n * Rotates only in the plane perpendicular to `rotationAxis`, which is fixed in the previous\n * bone's frame.\n *\n * That frame comes from {@link mat3.fromDirection}, so local **+Z** is the previous bone's own\n * direction and local +X and +Y are perpendicular to it. (`fabrik2` uses +Y for the same idea,\n * so a rig ported from 2D needs its axes rotated.) The frame's roll about the bone is arbitrary\n * and flips near world -Z, so a hinge whose parent swings through there will pop - hinge about a\n * `GLOBAL_HINGE` axis you rebuild from your own frame if the parent turns freely.\n */\n LOCAL_HINGE = 2,\n}\n\n/**\n * How the first bone in a chain is constrained.\n *\n * The first bone has no bone before it to be constrained against, so it is constrained against a\n * direction held on the chain instead. `GLOBAL_` types read that direction as world space, while\n * `LOCAL_` types read it relative to the bone this chain is connected to, and so only mean\n * anything for a chain in a {@link Structure3}, where {@link solveStructure} resolves them.\n *\n * A `LOCAL_` direction is read in the host bone's frame from {@link mat3.fromDirection}, where\n * **+Z** is the host bone's own direction. (`fabrik2`'s equivalent uses +Y.) That frame's roll is\n * arbitrary and flips near world -Z, so a host bone that swings through there makes the constraint\n * pop.\n */\nexport enum BaseboneConstraintType {\n /** The first bone may point anywhere. */\n NONE = 0,\n /** Confined to a cone of `baseboneRotor` radians about a world-space direction. */\n GLOBAL_ROTOR = 1,\n /** Confined to a cone of `baseboneRotor` radians about a direction relative to the host bone. */\n LOCAL_ROTOR = 2,\n /** Confined to the plane perpendicular to a world-space hinge axis. */\n GLOBAL_HINGE = 3,\n /** Confined to the plane perpendicular to a hinge axis relative to the host bone. */\n LOCAL_HINGE = 4,\n}\n\n/** Which end of a host bone a connected chain hangs off. */\nexport enum BoneConnectionPoint {\n /** The host bone's start - the joint it shares with the bone before it. */\n START = 0,\n /** The host bone's end. */\n END = 1,\n}\n\n/**\n * A joint's rotational limits.\n *\n * Which fields apply depends on `type`: `rotor` for {@link JointType.BALL}, and `rotationAxis`,\n * `referenceAxis`, `clockwise` and `anticlockwise` for the two hinge types. All angles are in\n * radians, and a limit of PI means unconstrained.\n */\nexport type Joint3 = {\n /** Which of the fields below apply. */\n type: JointType;\n /** Ball: the half-angle of the cone about the previous bone's direction, in [0, PI]. */\n rotor: number;\n /** Hinge: how far the bone may swing clockwise of `referenceAxis`, in [0, PI]. */\n clockwise: number;\n /** Hinge: how far the bone may swing anticlockwise of `referenceAxis`, in [0, PI]. */\n anticlockwise: number;\n /** Hinge: the axis the bone rotates about. Unit length. */\n rotationAxis: Vec3;\n /** Hinge: the zero direction the clockwise and anticlockwise limits are measured from. Unit length, perpendicular to `rotationAxis`. */\n referenceAxis: Vec3;\n};\n\n/** A single bone: two points, the fixed distance between them, and how it may rotate. */\nexport type Bone3 = {\n /** The joint shared with the previous bone; on the first bone, the base. */\n start: Vec3;\n /** The joint shared with the next bone; on the last bone, the end effector. */\n end: Vec3;\n /** The rest distance between `start` and `end`, preserved by every solve. */\n length: number;\n /** How far this bone may rotate away from the bone before it. */\n joint: Joint3;\n};\n\n/**\n * A chain of bones, from the base (index 0) to the end effector (the last bone's `end`).\n *\n * Allocate one with {@link createChain3}, fill it with {@link addBone} or\n * {@link addConsecutiveBone}, then solve it every frame.\n *\n * `bones[0].joint` is unused - the first bone is governed by the chain's basebone fields instead,\n * so a joint's fields never change meaning with its index.\n */\nexport type Chain3 = {\n /**\n * The bones, base first and end effector last.\n *\n * Neighbours share a point - bone `i`'s end is bone `i + 1`'s start - and the solver keeps it\n * that way, so moving one moves the other.\n */\n bones: Bone3[];\n /** The sum of every bone length - the chain's reach. Maintained by {@link addBone}. */\n length: number;\n /** Where the base of the chain is pinned when `fixedBase` is set. */\n base: Vec3;\n /** Whether `backward` pins the base to `base`. Clear it to let the whole chain drift. Forced on for a chain connected in a structure. */\n fixedBase: boolean;\n /** How the first bone is held; see {@link BaseboneConstraintType}. */\n baseboneConstraintType: BaseboneConstraintType;\n /** The cone axis or hinge axis, in the space named by `baseboneConstraintType`. Unit length. */\n baseboneAxis: Vec3;\n /** The hinge reference axis, in the space named by `baseboneConstraintType`. Unit length. */\n baseboneReferenceAxis: Vec3;\n /** `baseboneAxis` in world space. Equal to it for `GLOBAL_` types; resolved by {@link solveStructure} for `LOCAL_` ones. */\n baseboneWorldAxis: Vec3;\n /** `baseboneReferenceAxis` in world space. */\n baseboneWorldReferenceAxis: Vec3;\n /** The half-angle of the basebone cone, in [0, PI]. */\n baseboneRotor: number;\n /** The basebone hinge's clockwise limit, in [0, PI]. */\n baseboneClockwise: number;\n /** The basebone hinge's anticlockwise limit, in [0, PI]. */\n baseboneAnticlockwise: number;\n /** The target this chain solves for inside a {@link Structure3} when `useEmbeddedTarget` is set. */\n embeddedTarget: Vec3;\n /**\n * Whether this chain solves for its own `embeddedTarget` instead of the target passed to\n * {@link solveStructure}. Ignored outside a {@link Structure3}.\n */\n useEmbeddedTarget: boolean;\n /** The most iterations {@link solve} will run. */\n maxIterations: number;\n /** {@link solve} stops as soon as the effector is this close to the target. */\n solveDistanceThreshold: number;\n /**\n * How still an iteration must be before {@link solve} treats the chain as stuck.\n *\n * Only consulted on an iteration that fails to beat the best distance so far, and compared\n * against the previous iteration rather than the best - so a solve that is slowly getting worse\n * runs its full budget. That is deliberate: FABRIK often worsens before it improves, and every\n * stricter rule tried here bought fewer iterations at a disproportionate cost in final pose.\n */\n minIterationChange: number;\n /** The distance from the effector to the target after the last {@link solve}. */\n solveDistance: number;\n /** Scratch holding the best pose {@link solve} has seen, six numbers per bone. Grown by {@link addBone}. */\n bestSolution: number[];\n};\n\n/** A chain's attachment to a bone in another chain of the same structure. */\nexport type Connection = {\n /** The index of the host chain in `structure.chains`, or -1 for a chain that hangs off nothing. */\n hostChain: number;\n /** The index of the host bone within that chain. */\n hostBone: number;\n /** Which end of the host bone this chain's base is pinned to. */\n point: BoneConnectionPoint;\n};\n\n/** A set of chains, each optionally hanging off a bone of another. */\nexport type Structure3 = {\n /** Solved in insertion order, so a connected chain always sees its host already posed. */\n chains: Chain3[];\n /** Parallel to `chains`. */\n connections: Connection[];\n};\n\n// the most iterations a solve runs before giving up on reaching the target\nconst DEFAULT_MAX_ITERATIONS = 20;\n\n// how close the effector must get before a solve stops early. in world units, so scale it with the\n// scene - the default suits a chain a few units long\nconst DEFAULT_SOLVE_DISTANCE_THRESHOLD = 0.01;\n\n// how little an iteration may improve the solve distance before it counts as stalled. a constrained\n// chain can reach a pose no further iteration improves on while still short of the threshold, and\n// without this it would burn every remaining iteration going nowhere. two orders of magnitude below\n// the distance threshold, so a solve still closing in on the target is never mistaken for a stalled\n// one\nconst DEFAULT_MIN_ITERATION_CHANGE = 1e-4;\n\n// below this squared length a vector carries no usable direction - 1e-12 in length terms, well above\n// a normalize's noise floor and well below anything meaningful. every test against it also checks\n// for NaN, so a value poisoned upstream takes the same fallback instead of spreading down the chain\nconst DEGENERATE_SQUARED_LENGTH = 1e-24;\n\n/**\n * Normalizes `axis` into `out`, leaving `out` untouched if `axis` has no direction to give.\n *\n * A zero axis cannot be normalized, and storing one turns every constraint that reads it into NaN.\n * `out` always starts as a valid unit vector, so keeping it is the safe fallback.\n */\nfunction setUnitAxis(out: Vec3, axis: Vec3): Vec3 {\n if (!hasDirection(vec3.squaredLength(axis))) return out;\n return vec3.normalize(out, axis);\n}\n\n/**\n * Whether a squared length is a usable magnitude: a real number, and not effectively zero.\n *\n * NaN counts as unusable. A value poisoned upstream then takes the same fallback as a zero-length\n * one, instead of spreading down the chain and leaving it stuck.\n */\nfunction hasDirection(squaredLength: number): boolean {\n if (Number.isNaN(squaredLength)) return false;\n return squaredLength >= DEGENERATE_SQUARED_LENGTH;\n}\n\n/** Creates an unconstrained joint. */\nexport function createJoint3(): Joint3 {\n return {\n type: JointType.BALL,\n rotor: Math.PI,\n clockwise: Math.PI,\n anticlockwise: Math.PI,\n rotationAxis: [0, 0, 1],\n referenceAxis: [1, 0, 0],\n };\n}\n\n/** Creates an empty chain with a fixed base at the origin and no basebone constraint. */\nexport function createChain3(): Chain3 {\n return {\n bones: [],\n length: 0,\n base: [0, 0, 0],\n fixedBase: true,\n baseboneConstraintType: BaseboneConstraintType.NONE,\n baseboneAxis: [0, 1, 0],\n baseboneReferenceAxis: [1, 0, 0],\n baseboneWorldAxis: [0, 1, 0],\n baseboneWorldReferenceAxis: [1, 0, 0],\n baseboneRotor: Math.PI,\n baseboneClockwise: Math.PI,\n baseboneAnticlockwise: Math.PI,\n embeddedTarget: [0, 0, 0],\n useEmbeddedTarget: false,\n maxIterations: DEFAULT_MAX_ITERATIONS,\n solveDistanceThreshold: DEFAULT_SOLVE_DISTANCE_THRESHOLD,\n minIterationChange: DEFAULT_MIN_ITERATION_CHANGE,\n solveDistance: Number.POSITIVE_INFINITY,\n bestSolution: [],\n };\n}\n\n/**\n * Appends a bone spanning `start` to `end`, copying both.\n *\n * The bone's length is taken from the distance between them. When this is the first bone the\n * chain's base is moved to `start`.\n *\n * @param chain the chain to append to\n * @param start the bone's start point\n * @param end the bone's end point\n * @param joint the bone's joint, or a fresh unconstrained one if omitted\n * @returns the appended bone\n */\nexport function addBone(chain: Chain3, start: Vec3, end: Vec3, joint: Joint3 = createJoint3()): Bone3 {\n const bone: Bone3 = {\n start: [start[0], start[1], start[2]],\n end: [end[0], end[1], end[2]],\n length: vec3.distance(start, end),\n joint,\n };\n\n if (chain.bones.length === 0) {\n chain.base[0] = start[0];\n chain.base[1] = start[1];\n chain.base[2] = start[2];\n }\n\n chain.bones.push(bone);\n chain.length += bone.length;\n\n // six numbers of best-pose scratch per bone, so `solve` never allocates\n chain.bestSolution.push(0, 0, 0, 0, 0, 0);\n\n return bone;\n}\n\n/**\n * Appends a bone starting where the chain currently ends, running `length` along `direction`.\n *\n * @param chain the chain to append to, which must already have at least one bone\n * @param direction the direction to extend in, assumed to be unit length\n * @param length the length of the new bone\n * @param joint the bone's joint, or a fresh unconstrained one if omitted\n * @returns the appended bone\n */\nexport function addConsecutiveBone(chain: Chain3, direction: Vec3, length: number, joint: Joint3 = createJoint3()): Bone3 {\n const previous = chain.bones[chain.bones.length - 1];\n\n _addConsecutive_end[0] = previous.end[0] + direction[0] * length;\n _addConsecutive_end[1] = previous.end[1] + direction[1] * length;\n _addConsecutive_end[2] = previous.end[2] + direction[2] * length;\n\n return addBone(chain, previous.end, _addConsecutive_end, joint);\n}\n\nconst _addConsecutive_end: Vec3 = [0, 0, 0];\n\n/**\n * Prepends a bone at the base end, extending the chain backward.\n *\n * This is what a follower grows with: driven by {@link forward} alone the base end is the tail.\n *\n * `joint` becomes the joint of the bone that was previously first, because that is the junction the\n * new bone creates. The new first bone's own joint is unused, as always.\n *\n * @param chain the chain to prepend to, which must already have at least one bone\n * @param direction the direction the new bone points, from its own start toward the existing chain. Assumed to be unit length\n * @param length the length of the new bone\n * @param joint the joint for the junction this creates, or a fresh unconstrained one if omitted\n * @returns the prepended bone\n */\nexport function addBoneAtBase(chain: Chain3, direction: Vec3, length: number, joint: Joint3 = createJoint3()): Bone3 {\n const first = chain.bones[0];\n\n // the bone that was first now sits at index 1, so it is the one whose joint governs the new\n // junction. its old joint was the unused basebone slot\n first.joint = joint;\n\n const bone: Bone3 = {\n start: [\n first.start[0] - direction[0] * length,\n first.start[1] - direction[1] * length,\n first.start[2] - direction[2] * length,\n ],\n end: [first.start[0], first.start[1], first.start[2]],\n length,\n joint: createJoint3(),\n };\n\n chain.bones.unshift(bone);\n chain.length += length;\n\n chain.base[0] = bone.start[0];\n chain.base[1] = bone.start[1];\n chain.base[2] = bone.start[2];\n\n chain.bestSolution.push(0, 0, 0, 0, 0, 0);\n\n return bone;\n}\n\n/**\n * Sets a ball-joint constraint: the bone may rotate within a cone of `rotor` radians about the\n * direction of the bone before it.\n *\n * @param joint the joint to configure\n * @param rotor the half-angle of the cone in radians, clamped to [0, PI]\n * @returns the joint\n */\nexport function setBallJoint(joint: Joint3, rotor: number): Joint3 {\n joint.type = JointType.BALL;\n joint.rotor = clampAngle(rotor);\n return joint;\n}\n\n/**\n * Sets a hinge constraint: the bone may only rotate in the plane perpendicular to `rotationAxis`,\n * and within `clockwise` / `anticlockwise` radians of `referenceAxis` in that plane.\n *\n * `referenceAxis` is projected onto the hinge plane and normalized, so it need only be roughly\n * perpendicular. Pass PI for both limits for a hinge that spins freely.\n *\n * @param joint the joint to configure\n * @param type either {@link JointType.GLOBAL_HINGE} (axes in world space) or {@link JointType.LOCAL_HINGE} (axes relative to the previous bone)\n * @param rotationAxis the hinge axis, assumed to be unit length\n * @param clockwise the clockwise limit in radians, clamped to [0, PI]\n * @param anticlockwise the anticlockwise limit in radians, clamped to [0, PI]\n * @param referenceAxis the zero direction the limits are measured from\n * @returns the joint\n */\nexport function setHingeJoint(\n joint: Joint3,\n type: JointType.GLOBAL_HINGE | JointType.LOCAL_HINGE,\n rotationAxis: Vec3,\n clockwise: number,\n anticlockwise: number,\n referenceAxis: Vec3,\n): Joint3 {\n joint.type = type;\n joint.clockwise = clampAngle(clockwise);\n joint.anticlockwise = clampAngle(anticlockwise);\n\n setUnitAxis(joint.rotationAxis, rotationAxis);\n orthonormalize(joint.referenceAxis, referenceAxis, joint.rotationAxis);\n\n return joint;\n}\n\n/**\n * Confines the first bone to a cone of `rotor` radians about `axis`.\n *\n * @param chain the chain to configure\n * @param type either {@link BaseboneConstraintType.GLOBAL_ROTOR} or {@link BaseboneConstraintType.LOCAL_ROTOR}\n * @param axis the cone axis, assumed to be unit length\n * @param rotor the half-angle of the cone in radians, clamped to [0, PI]\n * @returns the chain\n */\nexport function setBaseboneRotorConstraint(\n chain: Chain3,\n type: BaseboneConstraintType.GLOBAL_ROTOR | BaseboneConstraintType.LOCAL_ROTOR,\n axis: Vec3,\n rotor: number,\n): Chain3 {\n chain.baseboneConstraintType = type;\n chain.baseboneRotor = clampAngle(rotor);\n\n setUnitAxis(chain.baseboneAxis, axis);\n vec3.copy(chain.baseboneWorldAxis, chain.baseboneAxis);\n\n return chain;\n}\n\n/**\n * Confines the first bone to the plane perpendicular to `rotationAxis`, within `clockwise` /\n * `anticlockwise` radians of `referenceAxis`.\n *\n * @param chain the chain to configure\n * @param type either {@link BaseboneConstraintType.GLOBAL_HINGE} or {@link BaseboneConstraintType.LOCAL_HINGE}\n * @param rotationAxis the hinge axis, assumed to be unit length\n * @param clockwise the clockwise limit in radians, clamped to [0, PI]\n * @param anticlockwise the anticlockwise limit in radians, clamped to [0, PI]\n * @param referenceAxis the zero direction the limits are measured from\n * @returns the chain\n */\nexport function setBaseboneHingeConstraint(\n chain: Chain3,\n type: BaseboneConstraintType.GLOBAL_HINGE | BaseboneConstraintType.LOCAL_HINGE,\n rotationAxis: Vec3,\n clockwise: number,\n anticlockwise: number,\n referenceAxis: Vec3,\n): Chain3 {\n chain.baseboneConstraintType = type;\n chain.baseboneClockwise = clampAngle(clockwise);\n chain.baseboneAnticlockwise = clampAngle(anticlockwise);\n\n setUnitAxis(chain.baseboneAxis, rotationAxis);\n orthonormalize(chain.baseboneReferenceAxis, referenceAxis, chain.baseboneAxis);\n\n vec3.copy(chain.baseboneWorldAxis, chain.baseboneAxis);\n vec3.copy(chain.baseboneWorldReferenceAxis, chain.baseboneReferenceAxis);\n\n return chain;\n}\n\n/**\n * Moves the chain's pinned base, without moving the bones.\n *\n * The next {@link backward} or {@link solve} pulls the chain to it.\n */\nexport function setBaseLocation(chain: Chain3, base: Vec3): Chain3 {\n chain.base[0] = base[0];\n chain.base[1] = base[1];\n chain.base[2] = base[2];\n return chain;\n}\n\n/**\n * Lays the chain out straight from its base along `direction`, discarding the current pose.\n *\n * A dead-straight chain is the worst starting pose for {@link solve} - see the note there. Bend\n * `direction` slightly between bones instead if the chain will be solved cold.\n */\nexport function straighten(chain: Chain3, direction: Vec3): Chain3 {\n const bones = chain.bones;\n\n let x = chain.base[0];\n let y = chain.base[1];\n let z = chain.base[2];\n\n for (let i = 0; i < bones.length; i++) {\n const bone = bones[i];\n\n bone.start[0] = x;\n bone.start[1] = y;\n bone.start[2] = z;\n\n x += direction[0] * bone.length;\n y += direction[1] * bone.length;\n z += direction[2] * bone.length;\n\n bone.end[0] = x;\n bone.end[1] = y;\n bone.end[2] = z;\n }\n\n return chain;\n}\n\n/**\n * Writes the end effector's position - the last bone's end - into `out`.\n *\n * A chain with no bones has its base as its effector, matching {@link solve}, which treats an empty\n * chain as a supported state rather than an error.\n */\nexport function getEffector(out: Vec3, chain: Chain3): Vec3 {\n const count = chain.bones.length;\n return vec3.copy(out, count === 0 ? chain.base : chain.bones[count - 1].end);\n}\n\n/** Writes the unit direction of bone `index`, from its start toward its end, into `out`. */\nexport function getBoneDirection(out: Vec3, chain: Chain3, index: number): Vec3 {\n const bone = chain.bones[index];\n vec3.subtract(out, bone.end, bone.start);\n return normalizeOr(out, UP);\n}\n\n/**\n * Writes the rotation taking `up` onto the direction of bone `index` into `out`.\n *\n * Use it to orient a mesh along a bone, passing whichever axis the mesh is modelled along - `up`\n * is `[0, 1, 0]` for a cylinder or capsule built along Y. The roll about the bone is arbitrary.\n */\nexport function getBoneRotation(out: Quat, chain: Chain3, index: number, up: Vec3): Quat {\n getBoneDirection(_boneRotation_direction, chain, index);\n return quat.rotationTo(out, up, _boneRotation_direction);\n}\n\nconst _boneRotation_direction: Vec3 = [0, 0, 0];\n\n/** Whether `target` is within reach of the chain's base, so a solve can place the effector exactly on it. */\nexport function isReachable(chain: Chain3, target: Vec3): boolean {\n return vec3.squaredDistance(chain.base, target) <= chain.length * chain.length;\n}\n\n/**\n * The forward pass: snaps the end effector onto `target` and drags the rest of the chain after it.\n *\n * A non-finite target leaves the chain untouched rather than poisoning it.\n *\n * The base is not pinned, so the whole chain moves. Run alone once per frame this is a follower\n * rather than a solver - a rope or tentacle whose head leads. Pair it with {@link backward}, or use\n * {@link solve}, to keep the base put.\n *\n * @param chain the chain to move, mutated in place\n * @param target where the end effector should go\n * @returns the chain\n */\nexport function forward(chain: Chain3, target: Vec3): Chain3 {\n const bones = chain.bones;\n const count = bones.length;\n\n if (count === 0) return chain;\n\n // a non-finite target would be written straight into the effector and spread down the chain\n if (!Number.isFinite(target[0]) || !Number.isFinite(target[1]) || !Number.isFinite(target[2])) return chain;\n\n // snap the effector onto the target. the rest of the pass follows from it\n const effector = bones[count - 1];\n effector.end[0] = target[0];\n effector.end[1] = target[1];\n effector.end[2] = target[2];\n\n // the outer-to-inner direction of the bone one step further out, which is what a joint on this\n // bone is constrained against on this pass. undefined for the effector itself.\n let hasReference = false;\n\n for (let i = count - 1; i >= 0; i--) {\n const bone = bones[i];\n const start = bone.start;\n const end = bone.end;\n\n // this bone's outer-to-inner direction\n let dx = start[0] - end[0];\n let dy = start[1] - end[1];\n let dz = start[2] - end[2];\n\n const squaredLength = dx * dx + dy * dy + dz * dz;\n\n if (!hasDirection(squaredLength)) {\n // the two ends coincide, so there is no direction to preserve. carry on along the bone\n // further out, or straight up if this is the effector\n dx = hasReference ? _pass_reference[0] : UP[0];\n dy = hasReference ? _pass_reference[1] : UP[1];\n dz = hasReference ? _pass_reference[2] : UP[2];\n } else {\n const inverseLength = 1 / Math.sqrt(squaredLength);\n dx *= inverseLength;\n dy *= inverseLength;\n dz *= inverseLength;\n }\n\n constrainForward(chain, i, dx, dy, dz, hasReference);\n dx = _pass_direction[0];\n dy = _pass_direction[1];\n dz = _pass_direction[2];\n\n const x = end[0] + dx * bone.length;\n const y = end[1] + dy * bone.length;\n const z = end[2] + dz * bone.length;\n\n start[0] = x;\n start[1] = y;\n start[2] = z;\n\n // the previous bone shares this point\n if (i > 0) {\n const previousEnd = bones[i - 1].end;\n previousEnd[0] = x;\n previousEnd[1] = y;\n previousEnd[2] = z;\n }\n\n _pass_reference[0] = dx;\n _pass_reference[1] = dy;\n _pass_reference[2] = dz;\n hasReference = true;\n }\n\n return chain;\n}\n\n/**\n * The backward pass: pins the base and pushes each bone outward from it.\n *\n * Basebone constraints and hinge reference-axis limits are applied here only - the forward pass\n * skips the latter, because clamping on both degrades the solution.\n *\n * @param chain the chain to move, mutated in place\n * @param base where the base should go, used only when `chain.fixedBase` is set\n * @returns the chain\n */\nexport function backward(chain: Chain3, base: Vec3): Chain3 {\n const bones = chain.bones;\n const count = bones.length;\n\n if (count === 0) return chain;\n if (!Number.isFinite(base[0]) || !Number.isFinite(base[1]) || !Number.isFinite(base[2])) return chain;\n\n if (chain.fixedBase) {\n const start = bones[0].start;\n start[0] = base[0];\n start[1] = base[1];\n start[2] = base[2];\n }\n\n let hasReference = false;\n\n for (let i = 0; i < count; i++) {\n const bone = bones[i];\n const start = bone.start;\n const end = bone.end;\n\n // this bone's inner-to-outer direction\n let dx = end[0] - start[0];\n let dy = end[1] - start[1];\n let dz = end[2] - start[2];\n\n const squaredLength = dx * dx + dy * dy + dz * dz;\n\n if (!hasDirection(squaredLength)) {\n dx = hasReference ? _pass_reference[0] : UP[0];\n dy = hasReference ? _pass_reference[1] : UP[1];\n dz = hasReference ? _pass_reference[2] : UP[2];\n } else {\n const inverseLength = 1 / Math.sqrt(squaredLength);\n dx *= inverseLength;\n dy *= inverseLength;\n dz *= inverseLength;\n }\n\n constrainBackward(chain, i, dx, dy, dz, hasReference);\n dx = _pass_direction[0];\n dy = _pass_direction[1];\n dz = _pass_direction[2];\n\n // when the base is free, the first bone swings about its end rather than its start\n if (i === 0 && !chain.fixedBase) {\n start[0] = end[0] - dx * bone.length;\n start[1] = end[1] - dy * bone.length;\n start[2] = end[2] - dz * bone.length;\n }\n\n const x = start[0] + dx * bone.length;\n const y = start[1] + dy * bone.length;\n const z = start[2] + dz * bone.length;\n\n end[0] = x;\n end[1] = y;\n end[2] = z;\n\n if (i < count - 1) {\n const nextStart = bones[i + 1].start;\n nextStart[0] = x;\n nextStart[1] = y;\n nextStart[2] = z;\n }\n\n _pass_reference[0] = dx;\n _pass_reference[1] = dy;\n _pass_reference[2] = dz;\n hasReference = true;\n }\n\n return chain;\n}\n\n/**\n * One full FABRIK iteration - {@link forward} then {@link backward}. Often enough on its own for an\n * unconstrained chain reaching a nearby target. use {@link solve} to iterate to a tolerance.\n *\n * @param chain the chain to move, mutated in place\n * @param target where the end effector should go\n * @returns the distance from the effector to `target` afterwards\n */\nexport function iterate(chain: Chain3, target: Vec3): number {\n if (chain.bones.length === 0) return Number.POSITIVE_INFINITY;\n\n forward(chain, target);\n backward(chain, chain.base);\n\n return vec3.distance(chain.bones[chain.bones.length - 1].end, target);\n}\n\n/**\n * Solves the chain for `target`, iterating until it is close enough, stops improving, or runs out\n * of attempts.\n *\n * A constrained chain does not converge monotonically, so the best pose seen is kept and restored.\n *\n * A dead-straight chain is the worst case to solve cold: every direction lies on one line, leaving\n * nothing sideways to bend it with. Give it a slight bend if the first solve matters.\n *\n * @param chain the chain to solve, mutated in place\n * @param target where the end effector should go\n * @returns the distance from the effector to `target`, also stored as `chain.solveDistance`\n */\nexport function solve(chain: Chain3, target: Vec3): number {\n const count = chain.bones.length;\n\n if (count === 0) {\n chain.solveDistance = Number.POSITIVE_INFINITY;\n return chain.solveDistance;\n }\n\n // in case bones were pushed onto the chain directly rather than through addBone\n if (chain.bestSolution.length < count * 6) {\n chain.bestSolution.length = count * 6;\n chain.bestSolution.fill(0);\n }\n\n let best = Number.POSITIVE_INFINITY;\n let previous = Number.POSITIVE_INFINITY;\n\n for (let i = 0; i < chain.maxIterations; i++) {\n const distance = iterate(chain, target);\n\n if (distance < best) {\n best = distance;\n saveSolution(chain);\n\n if (distance <= chain.solveDistanceThreshold) break;\n } else if (Math.abs(distance - previous) < chain.minIterationChange) {\n // ground to a halt - more iterations will not improve on what we already have\n break;\n }\n\n previous = distance;\n }\n\n if (best !== Number.POSITIVE_INFINITY) {\n restoreSolution(chain);\n }\n\n chain.solveDistance = best;\n\n return best;\n}\n\n/** Creates an empty structure. */\nexport function createStructure3(): Structure3 {\n return { chains: [], connections: [] };\n}\n\n/**\n * Adds a chain that hangs off nothing, solving directly for the structure's target.\n *\n * @returns the index of the added chain\n */\nexport function addChain(structure: Structure3, chain: Chain3): number {\n structure.chains.push(chain);\n structure.connections.push({ hostChain: -1, hostBone: 0, point: BoneConnectionPoint.END });\n return structure.chains.length - 1;\n}\n\n/**\n * Adds a chain whose base is pinned to one end of a bone in a chain already in the structure.\n *\n * Add the host first: {@link solveStructure} walks chains in insertion order, so a chain always\n * sees its host already posed.\n *\n * @param structure the structure to add to\n * @param chain the chain to add\n * @param hostChain the index of the chain to hang off\n * @param hostBone the index of the bone within that chain\n * @param point which end of the host bone to attach to\n * @returns the index of the added chain\n */\nexport function connectChain(\n structure: Structure3,\n chain: Chain3,\n hostChain: number,\n hostBone: number,\n point: BoneConnectionPoint,\n): number {\n structure.chains.push(chain);\n structure.connections.push({ hostChain, hostBone, point });\n return structure.chains.length - 1;\n}\n\n/**\n * Solves every chain in the structure.\n *\n * A connected chain has its base moved onto its host bone's connection point and any `LOCAL_`\n * basebone constraint resolved through the host bone's frame first. A chain with\n * `useEmbeddedTarget` set solves for its own `embeddedTarget` instead - how a walker's legs each\n * reach their own foothold.\n *\n * @param structure the structure to solve, mutated in place\n * @param target the target for every chain that does not use an embedded target\n */\nexport function solveStructure(structure: Structure3, target: Vec3): void {\n const chains = structure.chains;\n\n for (let i = 0; i < chains.length; i++) {\n const chain = chains[i];\n const connection = structure.connections[i];\n\n if (connection.hostChain >= 0) {\n const host = chains[connection.hostChain];\n const hostBone = host.bones[connection.hostBone];\n\n setBaseLocation(chain, connection.point === BoneConnectionPoint.START ? hostBone.start : hostBone.end);\n\n // being connected IS what fixes this chain's base - a connected chain with a free base\n // would drift away from the host it is supposed to hang off, so the flag is not the\n // caller's to clear here\n chain.fixedBase = true;\n\n const type = chain.baseboneConstraintType;\n\n if (type === BaseboneConstraintType.LOCAL_ROTOR || type === BaseboneConstraintType.LOCAL_HINGE) {\n // the constraint is expressed in the host bone's frame, so rotate it into the world\n getBoneDirection(_structure_direction, host, connection.hostBone);\n basisFromDirection(_structure_basis, _structure_direction);\n\n vec3.transformMat3(chain.baseboneWorldAxis, chain.baseboneAxis, _structure_basis);\n vec3.normalize(chain.baseboneWorldAxis, chain.baseboneWorldAxis);\n\n if (type === BaseboneConstraintType.LOCAL_HINGE) {\n vec3.transformMat3(chain.baseboneWorldReferenceAxis, chain.baseboneReferenceAxis, _structure_basis);\n orthonormalize(chain.baseboneWorldReferenceAxis, chain.baseboneWorldReferenceAxis, chain.baseboneWorldAxis);\n }\n }\n }\n\n solve(chain, chain.useEmbeddedTarget ? chain.embeddedTarget : target);\n }\n}\n\nconst _structure_direction: Vec3 = [0, 0, 0];\nconst _structure_basis: Mat3 = /* @__PURE__ */ mat3.create();\n\n/* internals */\n\nconst UP: Vec3 = [0, 1, 0];\n\n// the direction the current pass is constraining against - the previous bone's, whichever way the\n// pass is walking - and the constrained result handed back from `constrain*`\nconst _pass_reference: Vec3 = [0, 0, 0];\nconst _pass_direction: Vec3 = [0, 0, 0];\nconst _constrain_axis: Vec3 = [0, 0, 0];\nconst _constrain_reference: Vec3 = [0, 0, 0];\nconst _constrain_basis: Mat3 = /* @__PURE__ */ mat3.create();\n\nfunction clampAngle(radians: number): number {\n return radians < 0 ? 0 : radians > Math.PI ? Math.PI : radians;\n}\n\n/** Writes the component of `a` perpendicular to the unit vector `axis`, normalized. */\nfunction orthonormalize(out: Vec3, a: Vec3, axis: Vec3): Vec3 {\n // the component of `a` perpendicular to `axis`\n vec3.scaleAndAdd(out, a, axis, -vec3.dot(a, axis));\n\n if (!hasDirection(vec3.squaredLength(out))) {\n // `a` is parallel to `axis`, so it names no direction in the plane - any will do\n return vec3.perpendicular(out, axis);\n }\n\n return vec3.normalize(out, out);\n}\n\n/** Normalizes `out` in place, falling back to `fallback` when it has no length. */\nfunction normalizeOr(out: Vec3, fallback: Vec3): Vec3 {\n if (!hasDirection(vec3.squaredLength(out))) {\n return vec3.copy(out, fallback);\n }\n return vec3.normalize(out, out);\n}\n\n/**\n * Flattens a direction into a hinge's plane.\n *\n * A direction parallel to the hinge axis projects to nothing, leaving no in-plane direction to\n * normalize. Fall back to the hinge's reference axis, which lies in the plane by construction.\n */\nfunction projectOntoHinge(out: Vec3, x: number, y: number, z: number, axis: Vec3, referenceAxis: Vec3): Vec3 {\n const d = x * axis[0] + y * axis[1] + z * axis[2];\n\n out[0] = x - axis[0] * d;\n out[1] = y - axis[1] * d;\n out[2] = z - axis[2] * d;\n\n if (!hasDirection(vec3.squaredLength(out))) {\n return vec3.copy(out, referenceAxis);\n }\n\n return vec3.normalize(out, out);\n}\n\n/** Rotates the unit vector `a` about the unit vector `axis` by `radians` (Rodrigues). */\nfunction rotateAboutAxis(out: Vec3, a: Vec3, axis: Vec3, radians: number): Vec3 {\n const ax = a[0];\n const ay = a[1];\n const az = a[2];\n const kx = axis[0];\n const ky = axis[1];\n const kz = axis[2];\n\n const c = Math.cos(radians);\n const s = Math.sin(radians);\n const d = (kx * ax + ky * ay + kz * az) * (1 - c);\n\n out[0] = ax * c + (ky * az - kz * ay) * s + kx * d;\n out[1] = ay * c + (kz * ax - kx * az) * s + ky * d;\n out[2] = az * c + (kx * ay - ky * ax) * s + kz * d;\n\n return out;\n}\n\n/** Flattens into the hinge plane, then clamps the swing about the reference axis. Writes `_pass_direction`. */\nfunction constrainHinge(\n x: number,\n y: number,\n z: number,\n axis: Vec3,\n referenceAxis: Vec3,\n clockwise: number,\n anticlockwise: number,\n): void {\n projectOntoHinge(_pass_direction, x, y, z, axis, referenceAxis);\n\n if (clockwise >= Math.PI && anticlockwise >= Math.PI) return;\n\n // anticlockwise about the hinge axis is positive\n const signed = vec3.signedAngle(referenceAxis, _pass_direction, axis);\n\n if (signed > anticlockwise) {\n rotateAboutAxis(_pass_direction, referenceAxis, axis, anticlockwise);\n } else if (signed < -clockwise) {\n rotateAboutAxis(_pass_direction, referenceAxis, axis, -clockwise);\n }\n}\n\n/**\n * Builds an orthonormal basis with `direction` as its Z axis, into `out`.\n *\n * Used to express a joint axis relative to the bone it hangs off. The X and Y axes are picked\n * arbitrarily but deterministically (the Frisvad method), because a bone frame has no meaningful\n * \"up\" to anchor them to - unlike a look-at matrix, which takes one and fails when the direction is\n * parallel to it.\n *\n * No choice of X and Y varies continuously over the whole sphere. This one is continuous everywhere\n * except at `direction` = (0, 0, -1), where the basis flips, so a local hinge whose parent swings\n * through there will pop.\n */\nfunction basisFromDirection(out: Mat3, direction: Vec3): Mat3 {\n const x = direction[0];\n const y = direction[1];\n const z = direction[2];\n\n if (z < -0.9999999) {\n // the antipode, where the construction below divides by zero\n out[0] = 0;\n out[1] = -1;\n out[2] = 0;\n out[3] = -1;\n out[4] = 0;\n out[5] = 0;\n out[6] = x;\n out[7] = y;\n out[8] = z;\n return out;\n }\n\n const a = 1 / (1 + z);\n const b = -x * y * a;\n\n // column 0 - the X axis\n out[0] = 1 - x * x * a;\n out[1] = b;\n out[2] = -x;\n\n // column 1 - the Y axis\n out[3] = b;\n out[4] = 1 - y * y * a;\n out[5] = -y;\n\n // column 2 - the Z axis, which is `direction` itself\n out[6] = x;\n out[7] = y;\n out[8] = z;\n\n return out;\n}\n\n/** Resolves a local hinge's axes into world space through the frame of bone `index - 1`. */\nfunction resolveLocalHinge(chain: Chain3, index: number, joint: Joint3): void {\n getBoneDirection(_constrain_axis, chain, index - 1);\n basisFromDirection(_constrain_basis, _constrain_axis);\n\n vec3.transformMat3(_constrain_axis, joint.rotationAxis, _constrain_basis);\n vec3.normalize(_constrain_axis, _constrain_axis);\n\n vec3.transformMat3(_constrain_reference, joint.referenceAxis, _constrain_basis);\n orthonormalize(_constrain_reference, _constrain_reference, _constrain_axis);\n}\n\n/**\n * Constrains a bone's outer-to-inner direction during the forward pass.\n *\n * Two joints limit it. This bone's own hinge confines it to a plane. The rotor bounding its bend\n * away from the bone further out belongs to the joint between the two, which is the next bone's, so\n * a rotor means the same angle on both passes.\n *\n * Hinge reference-axis limits are left to the backward pass, because clamping on both lands on\n * worse poses.\n *\n * Writes the result into `_pass_direction`, which starts out holding the unconstrained direction,\n * so a branch that does not apply can simply return.\n */\nfunction constrainForward(chain: Chain3, index: number, x: number, y: number, z: number, hasReference: boolean): void {\n // start from the unconstrained direction. each branch below narrows it if it applies\n _pass_direction[0] = x;\n _pass_direction[1] = y;\n _pass_direction[2] = z;\n\n // first: whatever confines this bone's own orientation, neighbours aside\n if (index === 0) {\n const type = chain.baseboneConstraintType;\n\n if (type === BaseboneConstraintType.GLOBAL_HINGE || type === BaseboneConstraintType.LOCAL_HINGE) {\n projectOntoHinge(_pass_direction, x, y, z, chain.baseboneWorldAxis, chain.baseboneWorldReferenceAxis);\n return;\n }\n\n // a basebone rotor is measured against the base's own axis, which this pass knows nothing\n // about - the backward pass applies it\n } else {\n const joint = chain.bones[index].joint;\n\n if (joint.type === JointType.GLOBAL_HINGE) {\n projectOntoHinge(_pass_direction, x, y, z, joint.rotationAxis, joint.referenceAxis);\n return;\n }\n\n if (joint.type === JointType.LOCAL_HINGE) {\n resolveLocalHinge(chain, index, joint);\n projectOntoHinge(_pass_direction, x, y, z, _constrain_axis, _constrain_reference);\n return;\n }\n }\n\n // the rotor shared with the bone one step further out. the end effector has no such bone\n if (!hasReference) return;\n\n const outer = chain.bones[index + 1].joint;\n\n if (outer.type !== JointType.BALL || outer.rotor >= Math.PI) return;\n\n _pass_direction[0] = x;\n _pass_direction[1] = y;\n _pass_direction[2] = z;\n vec3.rotateTowards(_pass_direction, _pass_reference, _pass_direction, outer.rotor);\n}\n\n/**\n * Constrains a bone's inner-to-outer direction during the backward pass.\n *\n * Writes the result into `_pass_direction`, which starts out holding the unconstrained direction,\n * so a branch that does not apply can simply return.\n */\nfunction constrainBackward(chain: Chain3, index: number, x: number, y: number, z: number, hasReference: boolean): void {\n // start from the unconstrained direction. each branch below narrows it if it applies\n _pass_direction[0] = x;\n _pass_direction[1] = y;\n _pass_direction[2] = z;\n\n if (index === 0) {\n switch (chain.baseboneConstraintType) {\n case BaseboneConstraintType.GLOBAL_ROTOR:\n case BaseboneConstraintType.LOCAL_ROTOR: {\n if (chain.baseboneRotor >= Math.PI) return;\n vec3.rotateTowards(_pass_direction, chain.baseboneWorldAxis, _pass_direction, chain.baseboneRotor);\n return;\n }\n case BaseboneConstraintType.GLOBAL_HINGE:\n case BaseboneConstraintType.LOCAL_HINGE: {\n constrainHinge(\n x,\n y,\n z,\n chain.baseboneWorldAxis,\n chain.baseboneWorldReferenceAxis,\n chain.baseboneClockwise,\n chain.baseboneAnticlockwise,\n );\n return;\n }\n default:\n return;\n }\n }\n\n const joint = chain.bones[index].joint;\n\n switch (joint.type) {\n case JointType.BALL: {\n if (!hasReference || joint.rotor >= Math.PI) return;\n vec3.rotateTowards(_pass_direction, _pass_reference, _pass_direction, joint.rotor);\n return;\n }\n case JointType.GLOBAL_HINGE: {\n constrainHinge(x, y, z, joint.rotationAxis, joint.referenceAxis, joint.clockwise, joint.anticlockwise);\n return;\n }\n case JointType.LOCAL_HINGE: {\n resolveLocalHinge(chain, index, joint);\n constrainHinge(x, y, z, _constrain_axis, _constrain_reference, joint.clockwise, joint.anticlockwise);\n return;\n }\n default:\n return;\n }\n}\n\nfunction saveSolution(chain: Chain3): void {\n const bones = chain.bones;\n const solution = chain.bestSolution;\n\n for (let i = 0; i < bones.length; i++) {\n const bone = bones[i];\n const offset = i * 6;\n\n solution[offset] = bone.start[0];\n solution[offset + 1] = bone.start[1];\n solution[offset + 2] = bone.start[2];\n solution[offset + 3] = bone.end[0];\n solution[offset + 4] = bone.end[1];\n solution[offset + 5] = bone.end[2];\n }\n}\n\nfunction restoreSolution(chain: Chain3): void {\n const bones = chain.bones;\n const solution = chain.bestSolution;\n\n for (let i = 0; i < bones.length; i++) {\n const bone = bones[i];\n const offset = i * 6;\n\n bone.start[0] = solution[offset];\n bone.start[1] = solution[offset + 1];\n bone.start[2] = solution[offset + 2];\n bone.end[0] = solution[offset + 3];\n bone.end[1] = solution[offset + 4];\n bone.end[2] = solution[offset + 5];\n }\n}\n"],"names":["vec3.squaredLength","vec3.normalize","vec3.distance","vec3.copy","vec3.subtract","quat.rotationTo","vec3.squaredDistance","vec3.transformMat3","mat3.create","vec3.scaleAndAdd","vec3.dot","vec3.perpendicular","vec3.signedAngle","vec3.rotateTowards"],"mappings":"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"}
|
package/dist/ik/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export { EPSILON, binomial, clamp, equals, fade, lagrange, lerp, remap, remapClamp, repeat, round } from './core/scalar.js';
|
|
2
|
+
export { DEGREES_TO_RADIANS, RADIANS_TO_DEGREES, degreesToRadians, deltaAngle, radiansToDegrees, wrapAngle } from './core/angle.js';
|
|
3
|
+
import * as vec2 from './core/vec2.js';
|
|
4
|
+
export { vec2 };
|
|
5
|
+
import * as vec3 from './core/vec3.js';
|
|
6
|
+
export { vec3 };
|
|
7
|
+
import * as vec4 from './core/vec4.js';
|
|
8
|
+
export { vec4 };
|
|
9
|
+
import * as euler from './core/euler.js';
|
|
10
|
+
export { euler };
|
|
11
|
+
import * as quat from './core/quat.js';
|
|
12
|
+
export { quat };
|
|
13
|
+
import * as quat2 from './core/quat2.js';
|
|
14
|
+
export { quat2 };
|
|
15
|
+
import * as mat2 from './core/mat2.js';
|
|
16
|
+
export { mat2 };
|
|
17
|
+
import * as mat2d from './core/mat2d.js';
|
|
18
|
+
export { mat2d };
|
|
19
|
+
import * as mat3 from './core/mat3.js';
|
|
20
|
+
export { mat3 };
|
|
21
|
+
import * as mat4 from './core/mat4.js';
|
|
22
|
+
export { mat4 };
|
|
23
|
+
import * as spherical from './core/spherical.js';
|
|
24
|
+
export { spherical };
|
|
25
|
+
import * as polar from './core/polar.js';
|
|
26
|
+
export { polar };
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// Fractal combinators: helpers that layer octaves of ANY base noise source into
|
|
2
|
+
// the richer fields used for terrain, clouds, and marble. They are generic - the
|
|
3
|
+
// `sample` callback receives the current octave's frequency and returns the base
|
|
4
|
+
// noise at your coordinates scaled by it, so the same helper works with any
|
|
5
|
+
// generator at any dimension:
|
|
6
|
+
//
|
|
7
|
+
// fbm((f) => simplex2d.sample(gen, x * f, y * f), 5, 2, 0.5)
|
|
8
|
+
// fbm((f) => simplex3d.sample(gen, x * f, y * f, z * f), 5, 2, 0.5)
|
|
9
|
+
/**
|
|
10
|
+
* Fractional Brownian motion: sums octaves of a noise source at increasing
|
|
11
|
+
* frequency and decreasing amplitude - the workhorse for natural-looking
|
|
12
|
+
* heightmaps and clouds. Given a source in [-1, 1], returns a value in [-1, 1].
|
|
13
|
+
*
|
|
14
|
+
* @param sample receives an octave frequency, returns the base noise scaled by it
|
|
15
|
+
* @param octaves number of octaves to sum
|
|
16
|
+
* @param lacunarity frequency multiplier between octaves
|
|
17
|
+
* @param gain amplitude multiplier between octaves
|
|
18
|
+
* @returns the summed, normalized noise value
|
|
19
|
+
*/
|
|
20
|
+
function fbm(sample, octaves, lacunarity, gain) {
|
|
21
|
+
let frequency = 1;
|
|
22
|
+
let amplitude = 1;
|
|
23
|
+
let sum = 0;
|
|
24
|
+
let norm = 0;
|
|
25
|
+
for (let o = 0; o < octaves; o++) {
|
|
26
|
+
sum += amplitude * sample(frequency);
|
|
27
|
+
norm += amplitude;
|
|
28
|
+
frequency *= lacunarity;
|
|
29
|
+
amplitude *= gain;
|
|
30
|
+
}
|
|
31
|
+
return norm === 0 ? 0 : sum / norm;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Ridged multifractal: like {@link fbm}, but each octave is folded to
|
|
35
|
+
* `1 - abs(noise)`, filling the field with sharp ridges - the classic mountain
|
|
36
|
+
* range / canyon look. Given a source in [-1, 1], returns a value in [0, 1].
|
|
37
|
+
*
|
|
38
|
+
* @param sample receives an octave frequency, returns the base noise scaled by it
|
|
39
|
+
* @param octaves number of octaves to sum
|
|
40
|
+
* @param lacunarity frequency multiplier between octaves
|
|
41
|
+
* @param gain amplitude multiplier between octaves
|
|
42
|
+
* @returns the summed, normalized ridged value
|
|
43
|
+
*/
|
|
44
|
+
function ridged(sample, octaves, lacunarity, gain) {
|
|
45
|
+
let frequency = 1;
|
|
46
|
+
let amplitude = 1;
|
|
47
|
+
let sum = 0;
|
|
48
|
+
let norm = 0;
|
|
49
|
+
for (let o = 0; o < octaves; o++) {
|
|
50
|
+
sum += amplitude * (1 - Math.abs(sample(frequency)));
|
|
51
|
+
norm += amplitude;
|
|
52
|
+
frequency *= lacunarity;
|
|
53
|
+
amplitude *= gain;
|
|
54
|
+
}
|
|
55
|
+
return norm === 0 ? 0 : sum / norm;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Billow noise: like {@link fbm}, but each octave is folded to `2*abs(noise) - 1`,
|
|
59
|
+
* giving puffy, rounded, cloud-like lobes. Given a source in [-1, 1], returns a
|
|
60
|
+
* value in [-1, 1].
|
|
61
|
+
*
|
|
62
|
+
* @param sample receives an octave frequency, returns the base noise scaled by it
|
|
63
|
+
* @param octaves number of octaves to sum
|
|
64
|
+
* @param lacunarity frequency multiplier between octaves
|
|
65
|
+
* @param gain amplitude multiplier between octaves
|
|
66
|
+
* @returns the summed, normalized billow value
|
|
67
|
+
*/
|
|
68
|
+
function billow(sample, octaves, lacunarity, gain) {
|
|
69
|
+
let frequency = 1;
|
|
70
|
+
let amplitude = 1;
|
|
71
|
+
let sum = 0;
|
|
72
|
+
let norm = 0;
|
|
73
|
+
for (let o = 0; o < octaves; o++) {
|
|
74
|
+
sum += amplitude * (2 * Math.abs(sample(frequency)) - 1);
|
|
75
|
+
norm += amplitude;
|
|
76
|
+
frequency *= lacunarity;
|
|
77
|
+
amplitude *= gain;
|
|
78
|
+
}
|
|
79
|
+
return norm === 0 ? 0 : sum / norm;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Domain warping (2D): offsets a point by a noise-derived vector, so feeding the
|
|
83
|
+
* result back into a noise source bends and swirls it - marble, meandering
|
|
84
|
+
* terrain, organic distortion. The two axes sample the warp noise at
|
|
85
|
+
* decorrelated offsets so they don't move in lockstep.
|
|
86
|
+
*
|
|
87
|
+
* @param out the receiving Vec2 (the warped point)
|
|
88
|
+
* @param sample the warp noise source, sampled at (x, y)
|
|
89
|
+
* @param x x coordinate
|
|
90
|
+
* @param y y coordinate
|
|
91
|
+
* @param amount displacement scale (default 1)
|
|
92
|
+
* @returns out
|
|
93
|
+
*/
|
|
94
|
+
function domainWarp2(out, sample, x, y, amount = 1) {
|
|
95
|
+
out[0] = x + amount * sample(x, y);
|
|
96
|
+
out[1] = y + amount * sample(x + 5.2, y + 1.3);
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Domain warping (3D): offsets a point by a noise-derived vector so a noise
|
|
101
|
+
* source sampled at the result is bent and swirled. See {@link domainWarp2}.
|
|
102
|
+
*
|
|
103
|
+
* @param out the receiving Vec3 (the warped point)
|
|
104
|
+
* @param sample the warp noise source, sampled at (x, y, z)
|
|
105
|
+
* @param x x coordinate
|
|
106
|
+
* @param y y coordinate
|
|
107
|
+
* @param z z coordinate
|
|
108
|
+
* @param amount displacement scale (default 1)
|
|
109
|
+
* @returns out
|
|
110
|
+
*/
|
|
111
|
+
function domainWarp3(out, sample, x, y, z, amount = 1) {
|
|
112
|
+
out[0] = x + amount * sample(x, y, z);
|
|
113
|
+
out[1] = y + amount * sample(x + 5.2, y + 1.3, z + 2.8);
|
|
114
|
+
out[2] = z + amount * sample(x + 1.7, y + 9.2, z + 3.5);
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Curl of a 2D scalar noise potential - a divergence-free (incompressible) flow
|
|
119
|
+
* field. Particles advected through it swirl like a fluid and never converge to
|
|
120
|
+
* sinks or fly apart, which is why it's the cheap go-to for procedural smoke /
|
|
121
|
+
* flow. Given a scalar potential psi(x, y), the flow is (d psi/dy, -d psi/dx),
|
|
122
|
+
* with the derivatives taken by central differences of step `eps`.
|
|
123
|
+
*
|
|
124
|
+
* @param out the receiving Vec2 (the flow velocity)
|
|
125
|
+
* @param sample the scalar potential noise, sampled at (x, y)
|
|
126
|
+
* @param x x coordinate
|
|
127
|
+
* @param y y coordinate
|
|
128
|
+
* @param eps finite-difference step (default 1e-4)
|
|
129
|
+
* @returns out
|
|
130
|
+
*/
|
|
131
|
+
function curl2(out, sample, x, y, eps = 1e-4) {
|
|
132
|
+
const inv = 1 / (2 * eps);
|
|
133
|
+
const dpdx = (sample(x + eps, y) - sample(x - eps, y)) * inv;
|
|
134
|
+
const dpdy = (sample(x, y + eps) - sample(x, y - eps)) * inv;
|
|
135
|
+
out[0] = dpdy;
|
|
136
|
+
out[1] = -dpdx;
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
// large, arbitrary offsets that decorrelate the three potential components in curl3
|
|
140
|
+
const C3_O2X = 123.4;
|
|
141
|
+
const C3_O2Y = 55.7;
|
|
142
|
+
const C3_O2Z = -19.2;
|
|
143
|
+
const C3_O3X = -73.1;
|
|
144
|
+
const C3_O3Y = 218.9;
|
|
145
|
+
const C3_O3Z = 90.3;
|
|
146
|
+
/**
|
|
147
|
+
* Curl of a 3D noise vector potential - a divergence-free 3D flow field for
|
|
148
|
+
* volumetric smoke / fluid motion. The three potential components reuse a single
|
|
149
|
+
* `sample` at large, decorrelating offsets, and the flow is their curl,
|
|
150
|
+
* `∇ × psi`, with derivatives taken by central differences of step `eps`.
|
|
151
|
+
*
|
|
152
|
+
* @param out the receiving Vec3 (the flow velocity)
|
|
153
|
+
* @param sample the scalar potential noise, sampled at (x, y, z)
|
|
154
|
+
* @param x x coordinate
|
|
155
|
+
* @param y y coordinate
|
|
156
|
+
* @param z z coordinate
|
|
157
|
+
* @param eps finite-difference step (default 1e-4)
|
|
158
|
+
* @returns out
|
|
159
|
+
*/
|
|
160
|
+
function curl3(out, sample, x, y, z, eps = 1e-4) {
|
|
161
|
+
const inv = 1 / (2 * eps);
|
|
162
|
+
// potential 1 at (x, y, z): partials in y and z
|
|
163
|
+
const dp1dy = (sample(x, y + eps, z) - sample(x, y - eps, z)) * inv;
|
|
164
|
+
const dp1dz = (sample(x, y, z + eps) - sample(x, y, z - eps)) * inv;
|
|
165
|
+
// potential 2 at the +O2 offset: partials in x and z
|
|
166
|
+
const x2 = x + C3_O2X;
|
|
167
|
+
const y2 = y + C3_O2Y;
|
|
168
|
+
const z2 = z + C3_O2Z;
|
|
169
|
+
const dp2dx = (sample(x2 + eps, y2, z2) - sample(x2 - eps, y2, z2)) * inv;
|
|
170
|
+
const dp2dz = (sample(x2, y2, z2 + eps) - sample(x2, y2, z2 - eps)) * inv;
|
|
171
|
+
// potential 3 at the +O3 offset: partials in x and y
|
|
172
|
+
const x3 = x + C3_O3X;
|
|
173
|
+
const y3 = y + C3_O3Y;
|
|
174
|
+
const z3 = z + C3_O3Z;
|
|
175
|
+
const dp3dx = (sample(x3 + eps, y3, z3) - sample(x3 - eps, y3, z3)) * inv;
|
|
176
|
+
const dp3dy = (sample(x3, y3 + eps, z3) - sample(x3, y3 - eps, z3)) * inv;
|
|
177
|
+
// curl = ( dp3/dy - dp2/dz, dp1/dz - dp3/dx, dp2/dx - dp1/dy )
|
|
178
|
+
out[0] = dp3dy - dp2dz;
|
|
179
|
+
out[1] = dp1dz - dp3dx;
|
|
180
|
+
out[2] = dp2dx - dp1dy;
|
|
181
|
+
return out;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export { billow, curl2, curl3, domainWarp2, domainWarp3, fbm, ridged };
|
|
185
|
+
//# sourceMappingURL=fractal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fractal.js","sources":["../../src/noise/fractal.ts"],"sourcesContent":["import type { Vec2 } from '../core/vec2';\nimport type { Vec3 } from '../core/vec3';\n\n// Fractal combinators: helpers that layer octaves of ANY base noise source into\n// the richer fields used for terrain, clouds, and marble. They are generic - the\n// `sample` callback receives the current octave's frequency and returns the base\n// noise at your coordinates scaled by it, so the same helper works with any\n// generator at any dimension:\n//\n// fbm((f) => simplex2d.sample(gen, x * f, y * f), 5, 2, 0.5)\n// fbm((f) => simplex3d.sample(gen, x * f, y * f, z * f), 5, 2, 0.5)\n\n/**\n * Fractional Brownian motion: sums octaves of a noise source at increasing\n * frequency and decreasing amplitude - the workhorse for natural-looking\n * heightmaps and clouds. Given a source in [-1, 1], returns a value in [-1, 1].\n *\n * @param sample receives an octave frequency, returns the base noise scaled by it\n * @param octaves number of octaves to sum\n * @param lacunarity frequency multiplier between octaves\n * @param gain amplitude multiplier between octaves\n * @returns the summed, normalized noise value\n */\nexport function fbm(sample: (frequency: number) => number, octaves: number, lacunarity: number, gain: number): number {\n let frequency = 1;\n let amplitude = 1;\n let sum = 0;\n let norm = 0;\n for (let o = 0; o < octaves; o++) {\n sum += amplitude * sample(frequency);\n norm += amplitude;\n frequency *= lacunarity;\n amplitude *= gain;\n }\n return norm === 0 ? 0 : sum / norm;\n}\n\n/**\n * Ridged multifractal: like {@link fbm}, but each octave is folded to\n * `1 - abs(noise)`, filling the field with sharp ridges - the classic mountain\n * range / canyon look. Given a source in [-1, 1], returns a value in [0, 1].\n *\n * @param sample receives an octave frequency, returns the base noise scaled by it\n * @param octaves number of octaves to sum\n * @param lacunarity frequency multiplier between octaves\n * @param gain amplitude multiplier between octaves\n * @returns the summed, normalized ridged value\n */\nexport function ridged(\n sample: (frequency: number) => number,\n octaves: number,\n lacunarity: number,\n gain: number,\n): number {\n let frequency = 1;\n let amplitude = 1;\n let sum = 0;\n let norm = 0;\n for (let o = 0; o < octaves; o++) {\n sum += amplitude * (1 - Math.abs(sample(frequency)));\n norm += amplitude;\n frequency *= lacunarity;\n amplitude *= gain;\n }\n return norm === 0 ? 0 : sum / norm;\n}\n\n/**\n * Billow noise: like {@link fbm}, but each octave is folded to `2*abs(noise) - 1`,\n * giving puffy, rounded, cloud-like lobes. Given a source in [-1, 1], returns a\n * value in [-1, 1].\n *\n * @param sample receives an octave frequency, returns the base noise scaled by it\n * @param octaves number of octaves to sum\n * @param lacunarity frequency multiplier between octaves\n * @param gain amplitude multiplier between octaves\n * @returns the summed, normalized billow value\n */\nexport function billow(\n sample: (frequency: number) => number,\n octaves: number,\n lacunarity: number,\n gain: number,\n): number {\n let frequency = 1;\n let amplitude = 1;\n let sum = 0;\n let norm = 0;\n for (let o = 0; o < octaves; o++) {\n sum += amplitude * (2 * Math.abs(sample(frequency)) - 1);\n norm += amplitude;\n frequency *= lacunarity;\n amplitude *= gain;\n }\n return norm === 0 ? 0 : sum / norm;\n}\n\n/**\n * Domain warping (2D): offsets a point by a noise-derived vector, so feeding the\n * result back into a noise source bends and swirls it - marble, meandering\n * terrain, organic distortion. The two axes sample the warp noise at\n * decorrelated offsets so they don't move in lockstep.\n *\n * @param out the receiving Vec2 (the warped point)\n * @param sample the warp noise source, sampled at (x, y)\n * @param x x coordinate\n * @param y y coordinate\n * @param amount displacement scale (default 1)\n * @returns out\n */\nexport function domainWarp2(out: Vec2, sample: (x: number, y: number) => number, x: number, y: number, amount = 1): Vec2 {\n out[0] = x + amount * sample(x, y);\n out[1] = y + amount * sample(x + 5.2, y + 1.3);\n return out;\n}\n\n/**\n * Domain warping (3D): offsets a point by a noise-derived vector so a noise\n * source sampled at the result is bent and swirled. See {@link domainWarp2}.\n *\n * @param out the receiving Vec3 (the warped point)\n * @param sample the warp noise source, sampled at (x, y, z)\n * @param x x coordinate\n * @param y y coordinate\n * @param z z coordinate\n * @param amount displacement scale (default 1)\n * @returns out\n */\nexport function domainWarp3(\n out: Vec3,\n sample: (x: number, y: number, z: number) => number,\n x: number,\n y: number,\n z: number,\n amount = 1,\n): Vec3 {\n out[0] = x + amount * sample(x, y, z);\n out[1] = y + amount * sample(x + 5.2, y + 1.3, z + 2.8);\n out[2] = z + amount * sample(x + 1.7, y + 9.2, z + 3.5);\n return out;\n}\n\n/**\n * Curl of a 2D scalar noise potential - a divergence-free (incompressible) flow\n * field. Particles advected through it swirl like a fluid and never converge to\n * sinks or fly apart, which is why it's the cheap go-to for procedural smoke /\n * flow. Given a scalar potential psi(x, y), the flow is (d psi/dy, -d psi/dx),\n * with the derivatives taken by central differences of step `eps`.\n *\n * @param out the receiving Vec2 (the flow velocity)\n * @param sample the scalar potential noise, sampled at (x, y)\n * @param x x coordinate\n * @param y y coordinate\n * @param eps finite-difference step (default 1e-4)\n * @returns out\n */\nexport function curl2(out: Vec2, sample: (x: number, y: number) => number, x: number, y: number, eps = 1e-4): Vec2 {\n const inv = 1 / (2 * eps);\n const dpdx = (sample(x + eps, y) - sample(x - eps, y)) * inv;\n const dpdy = (sample(x, y + eps) - sample(x, y - eps)) * inv;\n out[0] = dpdy;\n out[1] = -dpdx;\n return out;\n}\n\n// large, arbitrary offsets that decorrelate the three potential components in curl3\nconst C3_O2X = 123.4;\nconst C3_O2Y = 55.7;\nconst C3_O2Z = -19.2;\nconst C3_O3X = -73.1;\nconst C3_O3Y = 218.9;\nconst C3_O3Z = 90.3;\n\n/**\n * Curl of a 3D noise vector potential - a divergence-free 3D flow field for\n * volumetric smoke / fluid motion. The three potential components reuse a single\n * `sample` at large, decorrelating offsets, and the flow is their curl,\n * `∇ × psi`, with derivatives taken by central differences of step `eps`.\n *\n * @param out the receiving Vec3 (the flow velocity)\n * @param sample the scalar potential noise, sampled at (x, y, z)\n * @param x x coordinate\n * @param y y coordinate\n * @param z z coordinate\n * @param eps finite-difference step (default 1e-4)\n * @returns out\n */\nexport function curl3(\n out: Vec3,\n sample: (x: number, y: number, z: number) => number,\n x: number,\n y: number,\n z: number,\n eps = 1e-4,\n): Vec3 {\n const inv = 1 / (2 * eps);\n\n // potential 1 at (x, y, z): partials in y and z\n const dp1dy = (sample(x, y + eps, z) - sample(x, y - eps, z)) * inv;\n const dp1dz = (sample(x, y, z + eps) - sample(x, y, z - eps)) * inv;\n\n // potential 2 at the +O2 offset: partials in x and z\n const x2 = x + C3_O2X;\n const y2 = y + C3_O2Y;\n const z2 = z + C3_O2Z;\n const dp2dx = (sample(x2 + eps, y2, z2) - sample(x2 - eps, y2, z2)) * inv;\n const dp2dz = (sample(x2, y2, z2 + eps) - sample(x2, y2, z2 - eps)) * inv;\n\n // potential 3 at the +O3 offset: partials in x and y\n const x3 = x + C3_O3X;\n const y3 = y + C3_O3Y;\n const z3 = z + C3_O3Z;\n const dp3dx = (sample(x3 + eps, y3, z3) - sample(x3 - eps, y3, z3)) * inv;\n const dp3dy = (sample(x3, y3 + eps, z3) - sample(x3, y3 - eps, z3)) * inv;\n\n // curl = ( dp3/dy - dp2/dz, dp1/dz - dp3/dx, dp2/dx - dp1/dy )\n out[0] = dp3dy - dp2dz;\n out[1] = dp1dz - dp3dx;\n out[2] = dp2dx - dp1dy;\n return out;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { billow, curl2, curl3, domainWarp2, domainWarp3, fbm, ridged } from './fractal.js';
|
|
2
|
+
import * as perlin2d from './perlin2d.js';
|
|
3
|
+
export { perlin2d };
|
|
4
|
+
import * as perlin3d from './perlin3d.js';
|
|
5
|
+
export { perlin3d };
|
|
6
|
+
import * as simplex2d from './simplex2d.js';
|
|
7
|
+
export { simplex2d };
|
|
8
|
+
import * as simplex3d from './simplex3d.js';
|
|
9
|
+
export { simplex3d };
|
|
10
|
+
import * as simplex4d from './simplex4d.js';
|
|
11
|
+
export { simplex4d };
|
|
12
|
+
import * as worley2d from './worley2d.js';
|
|
13
|
+
export { worley2d };
|
|
14
|
+
import * as worley3d from './worley3d.js';
|
|
15
|
+
export { worley3d };
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { lerp, fade } from '../core/scalar.js';
|
|
2
|
+
import { createPermutation } from './permutation.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a 2D Perlin noise generator with the given seed.
|
|
6
|
+
*
|
|
7
|
+
* @param seed The seed value for the noise generator
|
|
8
|
+
* @returns A generator to pass to {@link sample}
|
|
9
|
+
*/
|
|
10
|
+
function create(seed) {
|
|
11
|
+
return createPermutation(seed);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Samples 2D Perlin noise.
|
|
15
|
+
*
|
|
16
|
+
* @param generator A generator created with {@link create}
|
|
17
|
+
* @param x X coordinate
|
|
18
|
+
* @param y Y coordinate
|
|
19
|
+
* @returns The noise value at (x, y)
|
|
20
|
+
*/
|
|
21
|
+
function sample({ perm, grad3 }, x, y) {
|
|
22
|
+
// Find unit grid cell containing point
|
|
23
|
+
let X = Math.floor(x);
|
|
24
|
+
let Y = Math.floor(y);
|
|
25
|
+
// Get relative xy coordinates of point within that cell
|
|
26
|
+
x = x - X;
|
|
27
|
+
y = y - Y;
|
|
28
|
+
// Wrap the integer cells at 255 (smaller integer period can be introduced here)
|
|
29
|
+
X = X & 255;
|
|
30
|
+
Y = Y & 255;
|
|
31
|
+
const x1 = x - 1;
|
|
32
|
+
const y1 = y - 1;
|
|
33
|
+
// Hashed gradient indices of the four corners (flat xyz triples in grad3)
|
|
34
|
+
const g00 = (X + perm[Y]) * 3;
|
|
35
|
+
const g01 = (X + perm[Y + 1]) * 3;
|
|
36
|
+
const g10 = (X + 1 + perm[Y]) * 3;
|
|
37
|
+
const g11 = (X + 1 + perm[Y + 1]) * 3;
|
|
38
|
+
// Calculate noise contributions from each of the four corners
|
|
39
|
+
const n00 = grad3[g00] * x + grad3[g00 + 1] * y;
|
|
40
|
+
const n01 = grad3[g01] * x + grad3[g01 + 1] * y1;
|
|
41
|
+
const n10 = grad3[g10] * x1 + grad3[g10 + 1] * y;
|
|
42
|
+
const n11 = grad3[g11] * x1 + grad3[g11 + 1] * y1;
|
|
43
|
+
// Compute the fade curve value for x
|
|
44
|
+
const u = fade(x);
|
|
45
|
+
// Interpolate the four results
|
|
46
|
+
return lerp(lerp(n00, n10, u), lerp(n01, n11, u), fade(y));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { create, sample };
|
|
50
|
+
//# sourceMappingURL=perlin2d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perlin2d.js","sources":["../../src/noise/perlin2d.ts"],"sourcesContent":["import { fade, lerp } from '../core/scalar';\nimport { createPermutation, type Permutation } from './permutation';\n\n/** A seeded 2D Perlin noise generator. Create one with {@link create}. */\nexport type Perlin2DGenerator = Permutation;\n\n/**\n * Creates a 2D Perlin noise generator with the given seed.\n *\n * @param seed The seed value for the noise generator\n * @returns A generator to pass to {@link sample}\n */\nexport function create(seed: number): Perlin2DGenerator {\n return createPermutation(seed);\n}\n\n/**\n * Samples 2D Perlin noise.\n *\n * @param generator A generator created with {@link create}\n * @param x X coordinate\n * @param y Y coordinate\n * @returns The noise value at (x, y)\n */\nexport function sample({ perm, grad3 }: Perlin2DGenerator, x: number, y: number): number {\n // Find unit grid cell containing point\n let X = Math.floor(x);\n let Y = Math.floor(y);\n // Get relative xy coordinates of point within that cell\n x = x - X;\n y = y - Y;\n // Wrap the integer cells at 255 (smaller integer period can be introduced here)\n X = X & 255;\n Y = Y & 255;\n\n const x1 = x - 1;\n const y1 = y - 1;\n\n // Hashed gradient indices of the four corners (flat xyz triples in grad3)\n const g00 = (X + perm[Y]) * 3;\n const g01 = (X + perm[Y + 1]) * 3;\n const g10 = (X + 1 + perm[Y]) * 3;\n const g11 = (X + 1 + perm[Y + 1]) * 3;\n\n // Calculate noise contributions from each of the four corners\n const n00 = grad3[g00] * x + grad3[g00 + 1] * y;\n const n01 = grad3[g01] * x + grad3[g01 + 1] * y1;\n const n10 = grad3[g10] * x1 + grad3[g10 + 1] * y;\n const n11 = grad3[g11] * x1 + grad3[g11 + 1] * y1;\n\n // Compute the fade curve value for x\n const u = fade(x);\n\n // Interpolate the four results\n return lerp(lerp(n00, n10, u), lerp(n01, n11, u), fade(y));\n}\n"],"names":[],"mappings":";;;AAMA;;;;;AAKG;AACG,SAAU,MAAM,CAAC,IAAY,EAAA;AAC/B,IAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC;AAClC;AAEA;;;;;;;AAOG;AACG,SAAU,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAqB,EAAE,CAAS,EAAE,CAAS,EAAA;;IAE3E,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;;AAErB,IAAA,CAAC,GAAG,CAAC,GAAG,CAAC;AACT,IAAA,CAAC,GAAG,CAAC,GAAG,CAAC;;AAET,IAAA,CAAC,GAAG,CAAC,GAAG,GAAG;AACX,IAAA,CAAC,GAAG,CAAC,GAAG,GAAG;AAEX,IAAA,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC;AAChB,IAAA,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC;;AAGhB,IAAA,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7B,IAAA,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AACjC,IAAA,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,IAAA,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;;AAGrC,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;AAC/C,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE;AAChD,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;AAChD,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE;;AAGjD,IAAA,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;;IAGjB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9D;;;;"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { lerp, fade } from '../core/scalar.js';
|
|
2
|
+
import { createPermutation } from './permutation.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a 3D Perlin noise generator with the given seed.
|
|
6
|
+
*
|
|
7
|
+
* @param seed The seed value for the noise generator
|
|
8
|
+
* @returns A generator to pass to {@link sample}
|
|
9
|
+
*/
|
|
10
|
+
function create(seed) {
|
|
11
|
+
return createPermutation(seed);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Samples 3D Perlin noise.
|
|
15
|
+
*
|
|
16
|
+
* @param generator A generator created with {@link create}
|
|
17
|
+
* @param x X coordinate
|
|
18
|
+
* @param y Y coordinate
|
|
19
|
+
* @param z Z coordinate
|
|
20
|
+
* @returns The noise value at (x, y, z)
|
|
21
|
+
*/
|
|
22
|
+
function sample({ perm, grad3 }, x, y, z) {
|
|
23
|
+
// Find unit grid cell containing point
|
|
24
|
+
let X = Math.floor(x);
|
|
25
|
+
let Y = Math.floor(y);
|
|
26
|
+
let Z = Math.floor(z);
|
|
27
|
+
// Get relative xyz coordinates of point within that cell
|
|
28
|
+
x = x - X;
|
|
29
|
+
y = y - Y;
|
|
30
|
+
z = z - Z;
|
|
31
|
+
// Wrap the integer cells at 255 (smaller integer period can be introduced here)
|
|
32
|
+
X = X & 255;
|
|
33
|
+
Y = Y & 255;
|
|
34
|
+
Z = Z & 255;
|
|
35
|
+
const x1 = x - 1;
|
|
36
|
+
const y1 = y - 1;
|
|
37
|
+
const z1 = z - 1;
|
|
38
|
+
// Hash the Z and Y rows once; each corner then only needs one more lookup
|
|
39
|
+
const pz0 = perm[Z];
|
|
40
|
+
const pz1 = perm[Z + 1];
|
|
41
|
+
const py00 = perm[Y + pz0];
|
|
42
|
+
const py01 = perm[Y + pz1];
|
|
43
|
+
const py10 = perm[Y + 1 + pz0];
|
|
44
|
+
const py11 = perm[Y + 1 + pz1];
|
|
45
|
+
// Hashed gradient indices of the eight corners (flat xyz triples in grad3)
|
|
46
|
+
const g000 = (X + py00) * 3;
|
|
47
|
+
const g001 = (X + py01) * 3;
|
|
48
|
+
const g010 = (X + py10) * 3;
|
|
49
|
+
const g011 = (X + py11) * 3;
|
|
50
|
+
const g100 = (X + 1 + py00) * 3;
|
|
51
|
+
const g101 = (X + 1 + py01) * 3;
|
|
52
|
+
const g110 = (X + 1 + py10) * 3;
|
|
53
|
+
const g111 = (X + 1 + py11) * 3;
|
|
54
|
+
// Calculate noise contributions from each of the eight corners
|
|
55
|
+
const n000 = grad3[g000] * x + grad3[g000 + 1] * y + grad3[g000 + 2] * z;
|
|
56
|
+
const n001 = grad3[g001] * x + grad3[g001 + 1] * y + grad3[g001 + 2] * z1;
|
|
57
|
+
const n010 = grad3[g010] * x + grad3[g010 + 1] * y1 + grad3[g010 + 2] * z;
|
|
58
|
+
const n011 = grad3[g011] * x + grad3[g011 + 1] * y1 + grad3[g011 + 2] * z1;
|
|
59
|
+
const n100 = grad3[g100] * x1 + grad3[g100 + 1] * y + grad3[g100 + 2] * z;
|
|
60
|
+
const n101 = grad3[g101] * x1 + grad3[g101 + 1] * y + grad3[g101 + 2] * z1;
|
|
61
|
+
const n110 = grad3[g110] * x1 + grad3[g110 + 1] * y1 + grad3[g110 + 2] * z;
|
|
62
|
+
const n111 = grad3[g111] * x1 + grad3[g111 + 1] * y1 + grad3[g111 + 2] * z1;
|
|
63
|
+
// Compute the fade curve value for x, y, z
|
|
64
|
+
const u = fade(x);
|
|
65
|
+
const v = fade(y);
|
|
66
|
+
const w = fade(z);
|
|
67
|
+
// Interpolate
|
|
68
|
+
return lerp(lerp(lerp(n000, n100, u), lerp(n001, n101, u), w), lerp(lerp(n010, n110, u), lerp(n011, n111, u), w), v);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { create, sample };
|
|
72
|
+
//# sourceMappingURL=perlin3d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perlin3d.js","sources":["../../src/noise/perlin3d.ts"],"sourcesContent":["import { fade, lerp } from '../core/scalar';\nimport { createPermutation, type Permutation } from './permutation';\n\n/** A seeded 3D Perlin noise generator. Create one with {@link create}. */\nexport type Perlin3DGenerator = Permutation;\n\n/**\n * Creates a 3D Perlin noise generator with the given seed.\n *\n * @param seed The seed value for the noise generator\n * @returns A generator to pass to {@link sample}\n */\nexport function create(seed: number): Perlin3DGenerator {\n return createPermutation(seed);\n}\n\n/**\n * Samples 3D Perlin noise.\n *\n * @param generator A generator created with {@link create}\n * @param x X coordinate\n * @param y Y coordinate\n * @param z Z coordinate\n * @returns The noise value at (x, y, z)\n */\nexport function sample({ perm, grad3 }: Perlin3DGenerator, x: number, y: number, z: number): number {\n // Find unit grid cell containing point\n let X = Math.floor(x);\n let Y = Math.floor(y);\n let Z = Math.floor(z);\n // Get relative xyz coordinates of point within that cell\n x = x - X;\n y = y - Y;\n z = z - Z;\n // Wrap the integer cells at 255 (smaller integer period can be introduced here)\n X = X & 255;\n Y = Y & 255;\n Z = Z & 255;\n\n const x1 = x - 1;\n const y1 = y - 1;\n const z1 = z - 1;\n\n // Hash the Z and Y rows once; each corner then only needs one more lookup\n const pz0 = perm[Z];\n const pz1 = perm[Z + 1];\n const py00 = perm[Y + pz0];\n const py01 = perm[Y + pz1];\n const py10 = perm[Y + 1 + pz0];\n const py11 = perm[Y + 1 + pz1];\n\n // Hashed gradient indices of the eight corners (flat xyz triples in grad3)\n const g000 = (X + py00) * 3;\n const g001 = (X + py01) * 3;\n const g010 = (X + py10) * 3;\n const g011 = (X + py11) * 3;\n const g100 = (X + 1 + py00) * 3;\n const g101 = (X + 1 + py01) * 3;\n const g110 = (X + 1 + py10) * 3;\n const g111 = (X + 1 + py11) * 3;\n\n // Calculate noise contributions from each of the eight corners\n const n000 = grad3[g000] * x + grad3[g000 + 1] * y + grad3[g000 + 2] * z;\n const n001 = grad3[g001] * x + grad3[g001 + 1] * y + grad3[g001 + 2] * z1;\n const n010 = grad3[g010] * x + grad3[g010 + 1] * y1 + grad3[g010 + 2] * z;\n const n011 = grad3[g011] * x + grad3[g011 + 1] * y1 + grad3[g011 + 2] * z1;\n const n100 = grad3[g100] * x1 + grad3[g100 + 1] * y + grad3[g100 + 2] * z;\n const n101 = grad3[g101] * x1 + grad3[g101 + 1] * y + grad3[g101 + 2] * z1;\n const n110 = grad3[g110] * x1 + grad3[g110 + 1] * y1 + grad3[g110 + 2] * z;\n const n111 = grad3[g111] * x1 + grad3[g111 + 1] * y1 + grad3[g111 + 2] * z1;\n\n // Compute the fade curve value for x, y, z\n const u = fade(x);\n const v = fade(y);\n const w = fade(z);\n\n // Interpolate\n return lerp(lerp(lerp(n000, n100, u), lerp(n001, n101, u), w), lerp(lerp(n010, n110, u), lerp(n011, n111, u), w), v);\n}\n"],"names":[],"mappings":"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"}
|