@triforge/modifier-core 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/dist/core/BaseModifier.d.ts +29 -0
- package/dist/core/BaseModifier.d.ts.map +1 -0
- package/dist/core/BaseModifier.js +16 -0
- package/dist/core/BaseModifier.js.map +1 -0
- package/dist/core/ModifierStack.d.ts +40 -0
- package/dist/core/ModifierStack.d.ts.map +1 -0
- package/dist/core/ModifierStack.js +71 -0
- package/dist/core/ModifierStack.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/modifiers/deform/BendModifier.d.ts +25 -0
- package/dist/modifiers/deform/BendModifier.d.ts.map +1 -0
- package/dist/modifiers/deform/BendModifier.js +83 -0
- package/dist/modifiers/deform/BendModifier.js.map +1 -0
- package/dist/modifiers/deform/DisplacementModifier.d.ts +38 -0
- package/dist/modifiers/deform/DisplacementModifier.d.ts.map +1 -0
- package/dist/modifiers/deform/DisplacementModifier.js +58 -0
- package/dist/modifiers/deform/DisplacementModifier.js.map +1 -0
- package/dist/modifiers/deform/ShrinkwrapModifier.d.ts +24 -0
- package/dist/modifiers/deform/ShrinkwrapModifier.d.ts.map +1 -0
- package/dist/modifiers/deform/ShrinkwrapModifier.js +122 -0
- package/dist/modifiers/deform/ShrinkwrapModifier.js.map +1 -0
- package/dist/modifiers/deform/TwistModifier.d.ts +24 -0
- package/dist/modifiers/deform/TwistModifier.d.ts.map +1 -0
- package/dist/modifiers/deform/TwistModifier.js +76 -0
- package/dist/modifiers/deform/TwistModifier.js.map +1 -0
- package/dist/modifiers/deform/WarpModifier.d.ts +33 -0
- package/dist/modifiers/deform/WarpModifier.d.ts.map +1 -0
- package/dist/modifiers/deform/WarpModifier.js +61 -0
- package/dist/modifiers/deform/WarpModifier.js.map +1 -0
- package/dist/modifiers/generate/ArrayModifier.d.ts +22 -0
- package/dist/modifiers/generate/ArrayModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/ArrayModifier.js +65 -0
- package/dist/modifiers/generate/ArrayModifier.js.map +1 -0
- package/dist/modifiers/generate/BevelModifier.d.ts +31 -0
- package/dist/modifiers/generate/BevelModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/BevelModifier.js +234 -0
- package/dist/modifiers/generate/BevelModifier.js.map +1 -0
- package/dist/modifiers/generate/BooleanModifier.d.ts +37 -0
- package/dist/modifiers/generate/BooleanModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/BooleanModifier.js +71 -0
- package/dist/modifiers/generate/BooleanModifier.js.map +1 -0
- package/dist/modifiers/generate/ExtrudeModifier.d.ts +25 -0
- package/dist/modifiers/generate/ExtrudeModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/ExtrudeModifier.js +96 -0
- package/dist/modifiers/generate/ExtrudeModifier.js.map +1 -0
- package/dist/modifiers/generate/MirrorModifier.d.ts +35 -0
- package/dist/modifiers/generate/MirrorModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/MirrorModifier.js +122 -0
- package/dist/modifiers/generate/MirrorModifier.js.map +1 -0
- package/dist/modifiers/generate/OceanModifier.d.ts +64 -0
- package/dist/modifiers/generate/OceanModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/OceanModifier.js +279 -0
- package/dist/modifiers/generate/OceanModifier.js.map +1 -0
- package/dist/modifiers/generate/SolidifyModifier.d.ts +21 -0
- package/dist/modifiers/generate/SolidifyModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/SolidifyModifier.js +92 -0
- package/dist/modifiers/generate/SolidifyModifier.js.map +1 -0
- package/dist/modifiers/generate/SubdivisionModifier.d.ts +27 -0
- package/dist/modifiers/generate/SubdivisionModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/SubdivisionModifier.js +181 -0
- package/dist/modifiers/generate/SubdivisionModifier.js.map +1 -0
- package/dist/modifiers/generate/WireframeModifier.d.ts +21 -0
- package/dist/modifiers/generate/WireframeModifier.d.ts.map +1 -0
- package/dist/modifiers/generate/WireframeModifier.js +139 -0
- package/dist/modifiers/generate/WireframeModifier.js.map +1 -0
- package/dist/modifiers/transform/NormalRecalculateModifier.d.ts +18 -0
- package/dist/modifiers/transform/NormalRecalculateModifier.d.ts.map +1 -0
- package/dist/modifiers/transform/NormalRecalculateModifier.js +24 -0
- package/dist/modifiers/transform/NormalRecalculateModifier.js.map +1 -0
- package/dist/modifiers/transform/UVProjectionModifier.d.ts +35 -0
- package/dist/modifiers/transform/UVProjectionModifier.d.ts.map +1 -0
- package/dist/modifiers/transform/UVProjectionModifier.js +88 -0
- package/dist/modifiers/transform/UVProjectionModifier.js.map +1 -0
- package/dist/utils/noise.d.ts +3 -0
- package/dist/utils/noise.d.ts.map +1 -0
- package/dist/utils/noise.js +17 -0
- package/dist/utils/noise.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
export type BooleanOperation = 'union' | 'difference' | 'intersection';
|
|
4
|
+
export interface BooleanModifierOptions {
|
|
5
|
+
operand: BufferGeometry;
|
|
6
|
+
operation?: BooleanOperation;
|
|
7
|
+
operandMatrix?: number[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* BooleanModifier — Blender "Boolean" modifier equivalent.
|
|
11
|
+
*
|
|
12
|
+
* three-bvh-csg is loaded lazily (dynamic import) when a BooleanModifier is first
|
|
13
|
+
* instantiated. This means @st-modifier-core can be imported without three-bvh-csg
|
|
14
|
+
* in the importmap — the dependency is only required when you actually use this modifier.
|
|
15
|
+
*
|
|
16
|
+
* Await `modifier.ready()` before calling `stack.apply()` to ensure the library is loaded.
|
|
17
|
+
*
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const mod = new BooleanModifier({ operand: sphere, operation: 'difference' })
|
|
20
|
+
* await mod.ready()
|
|
21
|
+
* mesh.geometry = stack.apply()
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class BooleanModifier extends BaseModifier {
|
|
25
|
+
get name(): string;
|
|
26
|
+
parameters: Record<string, number>;
|
|
27
|
+
private readonly _operand;
|
|
28
|
+
private readonly _operandMatrix;
|
|
29
|
+
private _evaluator;
|
|
30
|
+
private _csg;
|
|
31
|
+
private readonly _ready;
|
|
32
|
+
constructor(opts: BooleanModifierOptions);
|
|
33
|
+
/** Resolves when three-bvh-csg has loaded. Await before calling stack.apply(). */
|
|
34
|
+
ready(): Promise<void>;
|
|
35
|
+
apply(geometry: BufferGeometry): BufferGeometry;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=BooleanModifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BooleanModifier.d.ts","sourceRoot":"","sources":["../../../src/modifiers/generate/BooleanModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAqB,MAAM,OAAO,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,YAAY,GAAG,cAAc,CAAA;AAEtE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,cAAc,CAAA;IACvB,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,IAAI,IAAI,WAAuB;IAE/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAElC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAU,UAAU,CAAoB;IAC/C,OAAO,CAAU,IAAI,CAAiD;IACtE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,IAAI,EAAE,sBAAsB;IAqBxC,kFAAkF;IAClF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAEtB,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc;CAsChD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MeshBasicMaterial } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* BooleanModifier — Blender "Boolean" modifier equivalent.
|
|
5
|
+
*
|
|
6
|
+
* three-bvh-csg is loaded lazily (dynamic import) when a BooleanModifier is first
|
|
7
|
+
* instantiated. This means @st-modifier-core can be imported without three-bvh-csg
|
|
8
|
+
* in the importmap — the dependency is only required when you actually use this modifier.
|
|
9
|
+
*
|
|
10
|
+
* Await `modifier.ready()` before calling `stack.apply()` to ensure the library is loaded.
|
|
11
|
+
*
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const mod = new BooleanModifier({ operand: sphere, operation: 'difference' })
|
|
14
|
+
* await mod.ready()
|
|
15
|
+
* mesh.geometry = stack.apply()
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export class BooleanModifier extends BaseModifier {
|
|
19
|
+
get name() { return 'Boolean'; }
|
|
20
|
+
constructor(opts) {
|
|
21
|
+
super();
|
|
22
|
+
this._evaluator = null;
|
|
23
|
+
this._csg = null;
|
|
24
|
+
this._operand = opts.operand;
|
|
25
|
+
this._operandMatrix = opts.operandMatrix ?? null;
|
|
26
|
+
const opIndex = opts.operation === 'union' ? 0
|
|
27
|
+
: opts.operation === 'intersection' ? 2
|
|
28
|
+
: 1;
|
|
29
|
+
this.parameters = { operation: opIndex };
|
|
30
|
+
// Lazy-load three-bvh-csg — only fetched when this modifier is instantiated,
|
|
31
|
+
// not when @st-modifier-core is imported. Keeps the package importable without
|
|
32
|
+
// three-bvh-csg in the importmap.
|
|
33
|
+
this._ready = import('three-bvh-csg').then(m => {
|
|
34
|
+
this._csg = m;
|
|
35
|
+
const Evaluator = m['Evaluator'];
|
|
36
|
+
this._evaluator = new Evaluator();
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Resolves when three-bvh-csg has loaded. Await before calling stack.apply(). */
|
|
40
|
+
ready() { return this._ready; }
|
|
41
|
+
apply(geometry) {
|
|
42
|
+
if (!this._csg || !this._evaluator) {
|
|
43
|
+
throw new Error('@st-modifier-core BooleanModifier: three-bvh-csg is still loading.\n' +
|
|
44
|
+
'Await `await modifier.ready()` before calling stack.apply().\n' +
|
|
45
|
+
'Also add "three-bvh-csg" to your importmap:\n' +
|
|
46
|
+
' "three-bvh-csg": "https://unpkg.com/three-bvh-csg@0.0.18/build/index.module.js"');
|
|
47
|
+
}
|
|
48
|
+
const { Brush, ADDITION, SUBTRACTION, INTERSECTION } = this._csg;
|
|
49
|
+
const opMap = { union: ADDITION, difference: SUBTRACTION, intersection: INTERSECTION };
|
|
50
|
+
const opIndex = Math.round(this.parameters.operation);
|
|
51
|
+
const opKey = opIndex === 0 ? 'union' : opIndex === 2 ? 'intersection' : 'difference';
|
|
52
|
+
const csgOp = opMap[opKey];
|
|
53
|
+
const BrushCls = Brush;
|
|
54
|
+
const EvalCls = this._evaluator;
|
|
55
|
+
const mat = new MeshBasicMaterial();
|
|
56
|
+
const brushA = new BrushCls(geometry, mat);
|
|
57
|
+
const brushB = new BrushCls(this._operand, mat);
|
|
58
|
+
if (this._operandMatrix) {
|
|
59
|
+
brushB.matrix.fromArray(this._operandMatrix);
|
|
60
|
+
brushB.matrixAutoUpdate = false;
|
|
61
|
+
brushB.updateMatrixWorld(true);
|
|
62
|
+
}
|
|
63
|
+
brushA.updateMatrixWorld(true);
|
|
64
|
+
brushB.updateMatrixWorld(true);
|
|
65
|
+
const result = EvalCls.evaluate(brushA, brushB, csgOp);
|
|
66
|
+
const out = result.geometry.clone();
|
|
67
|
+
mat.dispose();
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=BooleanModifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BooleanModifier.js","sourceRoot":"","sources":["../../../src/modifiers/generate/BooleanModifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
export interface ExtrudeModifierOptions {
|
|
4
|
+
amount?: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Face Extrude Modifier — procedurally extrudes every face along its normal.
|
|
8
|
+
* Produces a mesh where each triangle becomes a raised column with side walls.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: This is NOT Blender's Extrude modifier. Blender does not have a
|
|
11
|
+
* non-destructive extrude modifier — extrusion is an edit mode operation on
|
|
12
|
+
* selected faces. This modifier is a procedural equivalent useful for
|
|
13
|
+
* stylized effects (crystalline surfaces, low-poly spiky geometry).
|
|
14
|
+
*
|
|
15
|
+
* For Blender-equivalent face extrusion, use edit mode or geometry nodes.
|
|
16
|
+
*
|
|
17
|
+
* parameters.amount: extrusion distance along face normal
|
|
18
|
+
*/
|
|
19
|
+
export declare class ExtrudeModifier extends BaseModifier {
|
|
20
|
+
get name(): string;
|
|
21
|
+
parameters: Record<string, number>;
|
|
22
|
+
constructor(options?: ExtrudeModifierOptions);
|
|
23
|
+
apply(geometry: BufferGeometry): BufferGeometry;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=ExtrudeModifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExtrudeModifier.d.ts","sourceRoot":"","sources":["../../../src/modifiers/generate/ExtrudeModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,IAAI,IAAI,WAA2B;IAEnC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;gBAEtB,OAAO,GAAE,sBAA2B;IAKhD,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc;CAmEhD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { BufferGeometry, BufferAttribute } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Face Extrude Modifier — procedurally extrudes every face along its normal.
|
|
5
|
+
* Produces a mesh where each triangle becomes a raised column with side walls.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: This is NOT Blender's Extrude modifier. Blender does not have a
|
|
8
|
+
* non-destructive extrude modifier — extrusion is an edit mode operation on
|
|
9
|
+
* selected faces. This modifier is a procedural equivalent useful for
|
|
10
|
+
* stylized effects (crystalline surfaces, low-poly spiky geometry).
|
|
11
|
+
*
|
|
12
|
+
* For Blender-equivalent face extrusion, use edit mode or geometry nodes.
|
|
13
|
+
*
|
|
14
|
+
* parameters.amount: extrusion distance along face normal
|
|
15
|
+
*/
|
|
16
|
+
export class ExtrudeModifier extends BaseModifier {
|
|
17
|
+
get name() { return 'FaceExtrude'; }
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
super();
|
|
20
|
+
this.parameters = { amount: options.amount ?? 0.1 };
|
|
21
|
+
}
|
|
22
|
+
apply(geometry) {
|
|
23
|
+
const amount = this.parameters.amount;
|
|
24
|
+
const srcPos = geometry.getAttribute('position');
|
|
25
|
+
const srcUv = geometry.getAttribute('uv');
|
|
26
|
+
const srcIdx = geometry.getIndex();
|
|
27
|
+
const vCount = srcPos.count;
|
|
28
|
+
const outPos = [];
|
|
29
|
+
const outNorm = [];
|
|
30
|
+
const outUv = [];
|
|
31
|
+
const outIdx = [];
|
|
32
|
+
const tris = buildTriList(srcIdx, vCount);
|
|
33
|
+
for (const [a, b, c] of tris) {
|
|
34
|
+
// Face normal
|
|
35
|
+
const ax = srcPos.getX(a), ay = srcPos.getY(a), az = srcPos.getZ(a);
|
|
36
|
+
const bx = srcPos.getX(b), by = srcPos.getY(b), bz = srcPos.getZ(b);
|
|
37
|
+
const cx = srcPos.getX(c), cy = srcPos.getY(c), cz = srcPos.getZ(c);
|
|
38
|
+
const ux = bx - ax, uy = by - ay, uz = bz - az;
|
|
39
|
+
const vx = cx - ax, vy = cy - ay, vz = cz - az;
|
|
40
|
+
let nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx;
|
|
41
|
+
const len = Math.sqrt(nx * nx + ny * ny + nz * nz) || 1;
|
|
42
|
+
nx /= len;
|
|
43
|
+
ny /= len;
|
|
44
|
+
nz /= len;
|
|
45
|
+
const base = outPos.length / 3;
|
|
46
|
+
// Bottom (original) face
|
|
47
|
+
const positions = [[ax, ay, az], [bx, by, bz], [cx, cy, cz]];
|
|
48
|
+
const uvs = srcUv ? [
|
|
49
|
+
[srcUv.getX(a), srcUv.getY(a)],
|
|
50
|
+
[srcUv.getX(b), srcUv.getY(b)],
|
|
51
|
+
[srcUv.getX(c), srcUv.getY(c)],
|
|
52
|
+
] : [[0, 0], [1, 0], [0, 1]];
|
|
53
|
+
for (let i = 0; i < 3; i++) {
|
|
54
|
+
outPos.push(...positions[i]);
|
|
55
|
+
outNorm.push(-nx, -ny, -nz);
|
|
56
|
+
outUv.push(...uvs[i]);
|
|
57
|
+
}
|
|
58
|
+
// Top (extruded) face
|
|
59
|
+
for (let i = 0; i < 3; i++) {
|
|
60
|
+
outPos.push(positions[i][0] + nx * amount, positions[i][1] + ny * amount, positions[i][2] + nz * amount);
|
|
61
|
+
outNorm.push(nx, ny, nz);
|
|
62
|
+
outUv.push(...uvs[i]);
|
|
63
|
+
}
|
|
64
|
+
// Bottom winding reversed
|
|
65
|
+
outIdx.push(base, base + 2, base + 1);
|
|
66
|
+
// Top winding
|
|
67
|
+
outIdx.push(base + 3, base + 4, base + 5);
|
|
68
|
+
// Side walls
|
|
69
|
+
const pairs = [[0, 1, 4, 3], [1, 2, 5, 4], [2, 0, 3, 5]];
|
|
70
|
+
for (const [p0, p1, p2, p3] of pairs) {
|
|
71
|
+
outIdx.push(base + p0, base + p1, base + p2);
|
|
72
|
+
outIdx.push(base + p0, base + p2, base + p3);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const result = new BufferGeometry();
|
|
76
|
+
result.setAttribute('position', new BufferAttribute(new Float32Array(outPos), 3));
|
|
77
|
+
result.setAttribute('normal', new BufferAttribute(new Float32Array(outNorm), 3));
|
|
78
|
+
result.setAttribute('uv', new BufferAttribute(new Float32Array(outUv), 2));
|
|
79
|
+
result.setIndex(new BufferAttribute(new Uint32Array(outIdx), 1));
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function buildTriList(idx, vCount) {
|
|
84
|
+
const tris = [];
|
|
85
|
+
if (idx) {
|
|
86
|
+
const ia = idx.array;
|
|
87
|
+
for (let i = 0; i < ia.length; i += 3)
|
|
88
|
+
tris.push([ia[i], ia[i + 1], ia[i + 2]]);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
for (let i = 0; i < vCount; i += 3)
|
|
92
|
+
tris.push([i, i + 1, i + 2]);
|
|
93
|
+
}
|
|
94
|
+
return tris;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=ExtrudeModifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExtrudeModifier.js","sourceRoot":"","sources":["../../../src/modifiers/generate/ExtrudeModifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
export interface MirrorModifierOptions {
|
|
4
|
+
x?: boolean;
|
|
5
|
+
y?: boolean;
|
|
6
|
+
z?: boolean;
|
|
7
|
+
/** Vertices within this distance of the mirror plane are welded (merged). Default 0.001 */
|
|
8
|
+
mergeThreshold?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Mirror Modifier — Blender "Mirror" modifier equivalent.
|
|
12
|
+
*
|
|
13
|
+
* Mirrors geometry across one or more world axes, one axis at a time.
|
|
14
|
+
* Vertices within mergeThreshold of the mirror plane are welded — exactly
|
|
15
|
+
* as Blender does to prevent seams at the mirror boundary.
|
|
16
|
+
*
|
|
17
|
+
* Each active axis is applied sequentially (same as Blender's axis checkboxes):
|
|
18
|
+
* X active → mirrors across the YZ plane (negates X)
|
|
19
|
+
* Y active → mirrors across the XZ plane (negates Y)
|
|
20
|
+
* Z active → mirrors across the XY plane (negates Z)
|
|
21
|
+
*
|
|
22
|
+
* parameters.x/y/z: 1 = mirror across that axis, 0 = skip
|
|
23
|
+
* parameters.mergeThreshold: weld distance at mirror plane
|
|
24
|
+
*/
|
|
25
|
+
export declare class MirrorModifier extends BaseModifier {
|
|
26
|
+
get name(): string;
|
|
27
|
+
parameters: Record<string, number>;
|
|
28
|
+
constructor(options?: MirrorModifierOptions);
|
|
29
|
+
apply(geometry: BufferGeometry): BufferGeometry;
|
|
30
|
+
/**
|
|
31
|
+
* Mirror across one axis (0=X, 1=Y, 2=Z) and weld vertices at the mirror plane.
|
|
32
|
+
*/
|
|
33
|
+
private _mirrorAxis;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=MirrorModifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MirrorModifier.d.ts","sourceRoot":"","sources":["../../../src/modifiers/generate/MirrorModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,WAAW,qBAAqB;IACpC,CAAC,CAAC,EAAU,OAAO,CAAA;IACnB,CAAC,CAAC,EAAU,OAAO,CAAA;IACnB,CAAC,CAAC,EAAU,OAAO,CAAA;IACnB,2FAA2F;IAC3F,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,IAAI,IAAI,WAAsB;IAE9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;gBAEtB,OAAO,GAAE,qBAA0B;IAU/C,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc;IAW/C;;OAEG;IACH,OAAO,CAAC,WAAW;CAyEpB"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { BufferGeometry, BufferAttribute } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Mirror Modifier — Blender "Mirror" modifier equivalent.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors geometry across one or more world axes, one axis at a time.
|
|
7
|
+
* Vertices within mergeThreshold of the mirror plane are welded — exactly
|
|
8
|
+
* as Blender does to prevent seams at the mirror boundary.
|
|
9
|
+
*
|
|
10
|
+
* Each active axis is applied sequentially (same as Blender's axis checkboxes):
|
|
11
|
+
* X active → mirrors across the YZ plane (negates X)
|
|
12
|
+
* Y active → mirrors across the XZ plane (negates Y)
|
|
13
|
+
* Z active → mirrors across the XY plane (negates Z)
|
|
14
|
+
*
|
|
15
|
+
* parameters.x/y/z: 1 = mirror across that axis, 0 = skip
|
|
16
|
+
* parameters.mergeThreshold: weld distance at mirror plane
|
|
17
|
+
*/
|
|
18
|
+
export class MirrorModifier extends BaseModifier {
|
|
19
|
+
get name() { return 'Mirror'; }
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
super();
|
|
22
|
+
this.parameters = {
|
|
23
|
+
x: options.x !== false ? 1 : 0,
|
|
24
|
+
y: options.y ? 1 : 0,
|
|
25
|
+
z: options.z ? 1 : 0,
|
|
26
|
+
mergeThreshold: options.mergeThreshold ?? 0.001,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
apply(geometry) {
|
|
30
|
+
let geo = geometry;
|
|
31
|
+
// Apply each active axis sequentially — same as Blender
|
|
32
|
+
if (this.parameters.x > 0.5)
|
|
33
|
+
geo = this._mirrorAxis(geo, 0);
|
|
34
|
+
if (this.parameters.y > 0.5)
|
|
35
|
+
geo = this._mirrorAxis(geo, 1);
|
|
36
|
+
if (this.parameters.z > 0.5)
|
|
37
|
+
geo = this._mirrorAxis(geo, 2);
|
|
38
|
+
return geo;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Mirror across one axis (0=X, 1=Y, 2=Z) and weld vertices at the mirror plane.
|
|
42
|
+
*/
|
|
43
|
+
_mirrorAxis(geometry, axis) {
|
|
44
|
+
const srcPos = geometry.getAttribute('position');
|
|
45
|
+
const srcNorm = geometry.getAttribute('normal');
|
|
46
|
+
const srcUv = geometry.getAttribute('uv');
|
|
47
|
+
const srcIdx = geometry.getIndex();
|
|
48
|
+
const vCount = srcPos.count;
|
|
49
|
+
const thresh = this.parameters.mergeThreshold;
|
|
50
|
+
const tris = buildTriList(srcIdx, vCount);
|
|
51
|
+
const outPos = [];
|
|
52
|
+
const outNorm = [];
|
|
53
|
+
const outUv = [];
|
|
54
|
+
const outIdx = [];
|
|
55
|
+
// Copy original vertices
|
|
56
|
+
for (let v = 0; v < vCount; v++) {
|
|
57
|
+
outPos.push(srcPos.getX(v), srcPos.getY(v), srcPos.getZ(v));
|
|
58
|
+
if (srcNorm)
|
|
59
|
+
outNorm.push(srcNorm.getX(v), srcNorm.getY(v), srcNorm.getZ(v));
|
|
60
|
+
if (srcUv)
|
|
61
|
+
outUv.push(srcUv.getX(v), srcUv.getY(v));
|
|
62
|
+
}
|
|
63
|
+
// Map from original vertex index → mirrored vertex index
|
|
64
|
+
// Vertices ON the mirror plane (within threshold) reuse the original vertex (welded)
|
|
65
|
+
const mirrorMap = new Array(vCount);
|
|
66
|
+
for (let v = 0; v < vCount; v++) {
|
|
67
|
+
const coords = [srcPos.getX(v), srcPos.getY(v), srcPos.getZ(v)];
|
|
68
|
+
const axVal = coords[axis];
|
|
69
|
+
if (Math.abs(axVal) <= thresh) {
|
|
70
|
+
// On the mirror plane — weld: mirrored copy reuses original vertex
|
|
71
|
+
// Clamp the original to exactly 0 on the mirror axis
|
|
72
|
+
outPos[v * 3 + axis] = 0;
|
|
73
|
+
mirrorMap[v] = v;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Off-plane — create a new mirrored vertex
|
|
77
|
+
const mi = outPos.length / 3;
|
|
78
|
+
const mx = axis === 0 ? -coords[0] : coords[0];
|
|
79
|
+
const my = axis === 1 ? -coords[1] : coords[1];
|
|
80
|
+
const mz = axis === 2 ? -coords[2] : coords[2];
|
|
81
|
+
outPos.push(mx, my, mz);
|
|
82
|
+
if (srcNorm) {
|
|
83
|
+
const nx = srcNorm.getX(v), ny = srcNorm.getY(v), nz = srcNorm.getZ(v);
|
|
84
|
+
outNorm.push(axis === 0 ? -nx : nx, axis === 1 ? -ny : ny, axis === 2 ? -nz : nz);
|
|
85
|
+
}
|
|
86
|
+
if (srcUv)
|
|
87
|
+
outUv.push(srcUv.getX(v), srcUv.getY(v));
|
|
88
|
+
mirrorMap[v] = mi;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Original triangles
|
|
92
|
+
for (const [a, b, c] of tris)
|
|
93
|
+
outIdx.push(a, b, c);
|
|
94
|
+
// Mirrored triangles — reverse winding to preserve front-face direction
|
|
95
|
+
for (const [a, b, c] of tris) {
|
|
96
|
+
outIdx.push(mirrorMap[a], mirrorMap[c], mirrorMap[b]);
|
|
97
|
+
}
|
|
98
|
+
const result = new BufferGeometry();
|
|
99
|
+
result.setAttribute('position', new BufferAttribute(new Float32Array(outPos), 3));
|
|
100
|
+
if (outNorm.length)
|
|
101
|
+
result.setAttribute('normal', new BufferAttribute(new Float32Array(outNorm), 3));
|
|
102
|
+
if (outUv.length)
|
|
103
|
+
result.setAttribute('uv', new BufferAttribute(new Float32Array(outUv), 2));
|
|
104
|
+
result.setIndex(new BufferAttribute(new Uint32Array(outIdx), 1));
|
|
105
|
+
result.computeVertexNormals();
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function buildTriList(idx, vCount) {
|
|
110
|
+
const tris = [];
|
|
111
|
+
if (idx) {
|
|
112
|
+
const ia = idx.array;
|
|
113
|
+
for (let i = 0; i < ia.length; i += 3)
|
|
114
|
+
tris.push([ia[i], ia[i + 1], ia[i + 2]]);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
for (let i = 0; i < vCount; i += 3)
|
|
118
|
+
tris.push([i, i + 1, i + 2]);
|
|
119
|
+
}
|
|
120
|
+
return tris;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=MirrorModifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MirrorModifier.js","sourceRoot":"","sources":["../../../src/modifiers/generate/MirrorModifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
export interface OceanModifierOptions {
|
|
4
|
+
/** Animation time in seconds. Increment each frame for animated ocean. */
|
|
5
|
+
time?: number;
|
|
6
|
+
/** Dominant wave wavelength in Three.js units. Scale=3 → waves 3 units long. */
|
|
7
|
+
scale?: number;
|
|
8
|
+
/** Gerstner horizontal displacement. 0 = pure sine, 1 = choppy, >1.5 = folding. */
|
|
9
|
+
choppiness?: number;
|
|
10
|
+
/** Wind speed — scales wave amplitude. Higher = bigger waves. */
|
|
11
|
+
windSpeed?: number;
|
|
12
|
+
/** Wind direction in degrees. 0 = along +X axis. */
|
|
13
|
+
windAngle?: number;
|
|
14
|
+
/** Grid vertices per side. Default: 32. Higher = more detail but slower. */
|
|
15
|
+
resolution?: number;
|
|
16
|
+
/** World-space grid size in Three.js units. */
|
|
17
|
+
size?: number;
|
|
18
|
+
/** Water depth — shallower values slow short waves (tanh dispersion). Default: 200. */
|
|
19
|
+
depth?: number;
|
|
20
|
+
/** Foam coverage — how aggressively crests produce foam [0-1]. Default: 0.2. */
|
|
21
|
+
foamCoverage?: number;
|
|
22
|
+
/** Random seed — same seed always produces the same wave pattern. */
|
|
23
|
+
seed?: number;
|
|
24
|
+
/** Wave direction spreading [0-1]. 0 = all waves aligned with wind. */
|
|
25
|
+
damping?: number;
|
|
26
|
+
/** Number of Gerstner wave components. More = richer surface. Default: 24. */
|
|
27
|
+
waveCount?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Turbulence — adds value-noise perturbation on top of Gerstner waves.
|
|
30
|
+
* Breaks up the repeating sine pattern, especially visible when scale changes.
|
|
31
|
+
* 0 = disabled (pure Gerstner), 0.3 = moderate, 1.0 = heavy chaos.
|
|
32
|
+
*/
|
|
33
|
+
turbulence?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Ocean Modifier — Blender "Ocean" modifier equivalent.
|
|
37
|
+
*
|
|
38
|
+
* Generates a flat grid displaced by physically-based Gerstner wave simulation
|
|
39
|
+
* with a Phillips-inspired spectral distribution.
|
|
40
|
+
* Ignores the input geometry — always generates its own grid.
|
|
41
|
+
*
|
|
42
|
+
* Two-pass foam computation:
|
|
43
|
+
* Pass 1: evaluate all Gerstner displacements, record height range
|
|
44
|
+
* Pass 2: foam = crest fraction × steepness — produces thin streaks at
|
|
45
|
+
* wave tips rather than broad blobs from the Jacobian alone.
|
|
46
|
+
*
|
|
47
|
+
* Turbulence parameter adds seeded value-noise on top of Gerstner waves,
|
|
48
|
+
* breaking up the regular periodic pattern at any scale setting.
|
|
49
|
+
*
|
|
50
|
+
* Writes a `foam` Float32BufferAttribute. Use OceanAttribute node to read it.
|
|
51
|
+
*/
|
|
52
|
+
export declare class OceanModifier extends BaseModifier {
|
|
53
|
+
get name(): string;
|
|
54
|
+
parameters: Record<string, number>;
|
|
55
|
+
private _waves;
|
|
56
|
+
private _waveHash;
|
|
57
|
+
constructor(options?: OceanModifierOptions);
|
|
58
|
+
apply(_geometry: BufferGeometry): BufferGeometry;
|
|
59
|
+
private _ensureWaves;
|
|
60
|
+
private _buildWaves;
|
|
61
|
+
private _tiledNoise;
|
|
62
|
+
private _evaluate;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=OceanModifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OceanModifier.d.ts","sourceRoot":"","sources":["../../../src/modifiers/generate/OceanModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAoBzD,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,IAAI,CAAC,EAAU,MAAM,CAAA;IACrB,gFAAgF;IAChF,KAAK,CAAC,EAAS,MAAM,CAAA;IACrB,mFAAmF;IACnF,UAAU,CAAC,EAAI,MAAM,CAAA;IACrB,iEAAiE;IACjE,SAAS,CAAC,EAAK,MAAM,CAAA;IACrB,oDAAoD;IACpD,SAAS,CAAC,EAAK,MAAM,CAAA;IACrB,4EAA4E;IAC5E,UAAU,CAAC,EAAI,MAAM,CAAA;IACrB,+CAA+C;IAC/C,IAAI,CAAC,EAAU,MAAM,CAAA;IACrB,uFAAuF;IACvF,KAAK,CAAC,EAAS,MAAM,CAAA;IACrB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qEAAqE;IACrE,IAAI,CAAC,EAAU,MAAM,CAAA;IACrB,uEAAuE;IACvE,OAAO,CAAC,EAAO,MAAM,CAAA;IACrB,8EAA8E;IAC9E,SAAS,CAAC,EAAK,MAAM,CAAA;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAI,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,IAAI,IAAI,WAAqB;IAE7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAElC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,SAAS,CAAuB;gBAE5B,OAAO,GAAE,oBAAyB;IAmB9C,KAAK,CAAC,SAAS,EAAE,cAAc,GAAG,cAAc;IAkFhD,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,WAAW;IAkFnB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,SAAS;CA0DlB"}
|