@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,29 @@
|
|
|
1
|
+
import type { BufferGeometry } from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base for all modifiers.
|
|
4
|
+
* Mirrors Blender's modifier pattern: non-destructive, stackable, parameterized.
|
|
5
|
+
*
|
|
6
|
+
* Every modifier:
|
|
7
|
+
* - Takes a BufferGeometry in, returns a new BufferGeometry out (never mutates input)
|
|
8
|
+
* - Exposes a plain `parameters` object for GSAP/keyframe compatibility
|
|
9
|
+
* - Can be toggled with `enabled`
|
|
10
|
+
*/
|
|
11
|
+
export declare abstract class BaseModifier {
|
|
12
|
+
/** When false the modifier is skipped in the stack — geometry passes through unchanged. */
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Live scalar parameters. All numeric inputs live here.
|
|
16
|
+
* After construction, writing to parameters[name] affects the next apply() call.
|
|
17
|
+
* GSAP-compatible: gsap.to(modifier.parameters, { strength: 1.0, duration: 2 })
|
|
18
|
+
*/
|
|
19
|
+
abstract parameters: Record<string, number>;
|
|
20
|
+
/** Human-readable name matching Blender's modifier name. */
|
|
21
|
+
abstract get name(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Apply this modifier to the input geometry.
|
|
24
|
+
* NEVER mutates the input — always returns a new BufferGeometry.
|
|
25
|
+
* The caller is responsible for disposing the old geometry when no longer needed.
|
|
26
|
+
*/
|
|
27
|
+
abstract apply(geometry: BufferGeometry): BufferGeometry;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=BaseModifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseModifier.d.ts","sourceRoot":"","sources":["../../src/core/BaseModifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAE3C;;;;;;;;GAQG;AACH,8BAAsB,YAAY;IAChC,2FAA2F;IAC3F,OAAO,EAAE,OAAO,CAAO;IAEvB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE3C,4DAA4D;IAC5D,QAAQ,KAAK,IAAI,IAAI,MAAM,CAAA;IAE3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc;CACzD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base for all modifiers.
|
|
3
|
+
* Mirrors Blender's modifier pattern: non-destructive, stackable, parameterized.
|
|
4
|
+
*
|
|
5
|
+
* Every modifier:
|
|
6
|
+
* - Takes a BufferGeometry in, returns a new BufferGeometry out (never mutates input)
|
|
7
|
+
* - Exposes a plain `parameters` object for GSAP/keyframe compatibility
|
|
8
|
+
* - Can be toggled with `enabled`
|
|
9
|
+
*/
|
|
10
|
+
export class BaseModifier {
|
|
11
|
+
constructor() {
|
|
12
|
+
/** When false the modifier is skipped in the stack — geometry passes through unchanged. */
|
|
13
|
+
this.enabled = true;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=BaseModifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseModifier.js","sourceRoot":"","sources":["../../src/core/BaseModifier.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,OAAgB,YAAY;IAAlC;QACE,2FAA2F;QAC3F,YAAO,GAAY,IAAI,CAAA;IAkBzB,CAAC;CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import type { BaseModifier } from './BaseModifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Non-destructive modifier stack — mirrors Blender's modifier stack.
|
|
5
|
+
* Modifiers run in order: first added = first applied (top of stack).
|
|
6
|
+
* Disabled modifiers are skipped transparently.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const stack = new ModifierStack(baseGeometry)
|
|
10
|
+
* stack.add(new SubdivisionModifier({ levels: 2 }))
|
|
11
|
+
* stack.add(new DisplacementModifier({ strength: 0.3, noiseFunction: (x,y,z) => noise(x,y,z) }))
|
|
12
|
+
* const finalGeo = stack.apply()
|
|
13
|
+
*/
|
|
14
|
+
export declare class ModifierStack {
|
|
15
|
+
private _modifiers;
|
|
16
|
+
private _source;
|
|
17
|
+
constructor(source: BufferGeometry);
|
|
18
|
+
/** Add a modifier to the end of the stack. */
|
|
19
|
+
add(modifier: BaseModifier): this;
|
|
20
|
+
/** Remove a modifier from the stack by reference. */
|
|
21
|
+
remove(modifier: BaseModifier): this;
|
|
22
|
+
/** Read-only view of the current modifier list. */
|
|
23
|
+
get modifiers(): readonly BaseModifier[];
|
|
24
|
+
/** Replace the source geometry (e.g. after an animation tick that regenerates geometry). */
|
|
25
|
+
setSource(geometry: BufferGeometry): this;
|
|
26
|
+
/**
|
|
27
|
+
* Run all enabled modifiers in order and return the final geometry.
|
|
28
|
+
* Each modifier receives the output of the previous one.
|
|
29
|
+
* Intermediate geometries are disposed automatically.
|
|
30
|
+
* The original source geometry is never disposed or mutated.
|
|
31
|
+
*/
|
|
32
|
+
apply(): BufferGeometry;
|
|
33
|
+
/**
|
|
34
|
+
* Bake the stack — apply all modifiers and return the result as a standalone geometry.
|
|
35
|
+
* Equivalent to Blender's "Apply" button on all modifiers.
|
|
36
|
+
* Does NOT dispose the source geometry.
|
|
37
|
+
*/
|
|
38
|
+
bake(): BufferGeometry;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=ModifierStack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModifierStack.d.ts","sourceRoot":"","sources":["../../src/core/ModifierStack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,OAAO,CAAmB;gBAEtB,MAAM,EAAE,cAAc;IAIlC,8CAA8C;IAC9C,GAAG,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAKjC,qDAAqD;IACrD,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAMpC,mDAAmD;IACnD,IAAI,SAAS,IAAI,SAAS,YAAY,EAAE,CAEvC;IAED,4FAA4F;IAC5F,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAKzC;;;;;OAKG;IACH,KAAK,IAAI,cAAc;IAmBvB;;;;OAIG;IACH,IAAI,IAAI,cAAc;CAGvB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-destructive modifier stack — mirrors Blender's modifier stack.
|
|
3
|
+
* Modifiers run in order: first added = first applied (top of stack).
|
|
4
|
+
* Disabled modifiers are skipped transparently.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const stack = new ModifierStack(baseGeometry)
|
|
8
|
+
* stack.add(new SubdivisionModifier({ levels: 2 }))
|
|
9
|
+
* stack.add(new DisplacementModifier({ strength: 0.3, noiseFunction: (x,y,z) => noise(x,y,z) }))
|
|
10
|
+
* const finalGeo = stack.apply()
|
|
11
|
+
*/
|
|
12
|
+
export class ModifierStack {
|
|
13
|
+
constructor(source) {
|
|
14
|
+
this._modifiers = [];
|
|
15
|
+
this._source = source;
|
|
16
|
+
}
|
|
17
|
+
/** Add a modifier to the end of the stack. */
|
|
18
|
+
add(modifier) {
|
|
19
|
+
this._modifiers.push(modifier);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
/** Remove a modifier from the stack by reference. */
|
|
23
|
+
remove(modifier) {
|
|
24
|
+
const i = this._modifiers.indexOf(modifier);
|
|
25
|
+
if (i !== -1)
|
|
26
|
+
this._modifiers.splice(i, 1);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
/** Read-only view of the current modifier list. */
|
|
30
|
+
get modifiers() {
|
|
31
|
+
return this._modifiers;
|
|
32
|
+
}
|
|
33
|
+
/** Replace the source geometry (e.g. after an animation tick that regenerates geometry). */
|
|
34
|
+
setSource(geometry) {
|
|
35
|
+
this._source = geometry;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Run all enabled modifiers in order and return the final geometry.
|
|
40
|
+
* Each modifier receives the output of the previous one.
|
|
41
|
+
* Intermediate geometries are disposed automatically.
|
|
42
|
+
* The original source geometry is never disposed or mutated.
|
|
43
|
+
*/
|
|
44
|
+
apply() {
|
|
45
|
+
let current = this._source;
|
|
46
|
+
const intermediates = [];
|
|
47
|
+
for (const modifier of this._modifiers) {
|
|
48
|
+
if (!modifier.enabled)
|
|
49
|
+
continue;
|
|
50
|
+
const next = modifier.apply(current);
|
|
51
|
+
if (current !== this._source)
|
|
52
|
+
intermediates.push(current);
|
|
53
|
+
current = next;
|
|
54
|
+
}
|
|
55
|
+
// Dispose all intermediates except the final result
|
|
56
|
+
for (const geo of intermediates) {
|
|
57
|
+
if (geo !== current)
|
|
58
|
+
geo.dispose();
|
|
59
|
+
}
|
|
60
|
+
return current;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Bake the stack — apply all modifiers and return the result as a standalone geometry.
|
|
64
|
+
* Equivalent to Blender's "Apply" button on all modifiers.
|
|
65
|
+
* Does NOT dispose the source geometry.
|
|
66
|
+
*/
|
|
67
|
+
bake() {
|
|
68
|
+
return this.apply();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=ModifierStack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModifierStack.js","sourceRoot":"","sources":["../../src/core/ModifierStack.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,aAAa;IAIxB,YAAY,MAAsB;QAH1B,eAAU,GAAmB,EAAE,CAAA;QAIrC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAED,8CAA8C;IAC9C,GAAG,CAAC,QAAsB;QACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,qDAAqD;IACrD,MAAM,CAAC,QAAsB;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QAC3C,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC1C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,mDAAmD;IACnD,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED,4FAA4F;IAC5F,SAAS,CAAC,QAAwB;QAChC,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAA;QACvB,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;OAKG;IACH,KAAK;QACH,IAAI,OAAO,GAAmB,IAAI,CAAC,OAAO,CAAA;QAC1C,MAAM,aAAa,GAAqB,EAAE,CAAA;QAE1C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,OAAO;gBAAE,SAAQ;YAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACpC,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO;gBAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACzD,OAAO,GAAG,IAAI,CAAA;QAChB,CAAC;QAED,oDAAoD;QACpD,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;YAChC,IAAI,GAAG,KAAK,OAAO;gBAAE,GAAG,CAAC,OAAO,EAAE,CAAA;QACpC,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAED;;;;OAIG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export { BaseModifier } from './core/BaseModifier.js';
|
|
2
|
+
export { ModifierStack } from './core/ModifierStack.js';
|
|
3
|
+
export { SubdivisionModifier } from './modifiers/generate/SubdivisionModifier.js';
|
|
4
|
+
export { ArrayModifier } from './modifiers/generate/ArrayModifier.js';
|
|
5
|
+
export { ExtrudeModifier } from './modifiers/generate/ExtrudeModifier.js';
|
|
6
|
+
export { SolidifyModifier } from './modifiers/generate/SolidifyModifier.js';
|
|
7
|
+
export { MirrorModifier } from './modifiers/generate/MirrorModifier.js';
|
|
8
|
+
export { OceanModifier } from './modifiers/generate/OceanModifier.js';
|
|
9
|
+
export { BooleanModifier } from './modifiers/generate/BooleanModifier.js';
|
|
10
|
+
export { WireframeModifier } from './modifiers/generate/WireframeModifier.js';
|
|
11
|
+
export { BevelModifier } from './modifiers/generate/BevelModifier.js';
|
|
12
|
+
export { DisplacementModifier } from './modifiers/deform/DisplacementModifier.js';
|
|
13
|
+
export { WarpModifier } from './modifiers/deform/WarpModifier.js';
|
|
14
|
+
export { TwistModifier } from './modifiers/deform/TwistModifier.js';
|
|
15
|
+
export { BendModifier } from './modifiers/deform/BendModifier.js';
|
|
16
|
+
export { ShrinkwrapModifier } from './modifiers/deform/ShrinkwrapModifier.js';
|
|
17
|
+
export { UVProjectionModifier } from './modifiers/transform/UVProjectionModifier.js';
|
|
18
|
+
export { NormalRecalculateModifier } from './modifiers/transform/NormalRecalculateModifier.js';
|
|
19
|
+
export type { SubdivisionModifierOptions } from './modifiers/generate/SubdivisionModifier.js';
|
|
20
|
+
export type { ArrayModifierOptions } from './modifiers/generate/ArrayModifier.js';
|
|
21
|
+
export type { ExtrudeModifierOptions } from './modifiers/generate/ExtrudeModifier.js';
|
|
22
|
+
export type { SolidifyModifierOptions } from './modifiers/generate/SolidifyModifier.js';
|
|
23
|
+
export type { MirrorModifierOptions } from './modifiers/generate/MirrorModifier.js';
|
|
24
|
+
export type { OceanModifierOptions } from './modifiers/generate/OceanModifier.js';
|
|
25
|
+
export type { BooleanModifierOptions, BooleanOperation } from './modifiers/generate/BooleanModifier.js';
|
|
26
|
+
export type { DisplacementModifierOptions, NoiseFunction } from './modifiers/deform/DisplacementModifier.js';
|
|
27
|
+
export type { WarpModifierOptions } from './modifiers/deform/WarpModifier.js';
|
|
28
|
+
export type { TwistModifierOptions, TwistAxis } from './modifiers/deform/TwistModifier.js';
|
|
29
|
+
export type { BendModifierOptions, BendAxis } from './modifiers/deform/BendModifier.js';
|
|
30
|
+
export type { UVProjectionModifierOptions, UVProjectionType } from './modifiers/transform/UVProjectionModifier.js';
|
|
31
|
+
export type { WireframeModifierOptions } from './modifiers/generate/WireframeModifier.js';
|
|
32
|
+
export type { BevelModifierOptions } from './modifiers/generate/BevelModifier.js';
|
|
33
|
+
export type { ShrinkwrapModifierOptions } from './modifiers/deform/ShrinkwrapModifier.js';
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAS,wBAAwB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAQ,yBAAyB,CAAA;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAA;AACjF,OAAO,EAAE,aAAa,EAAE,MAAY,uCAAuC,CAAA;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAU,yCAAyC,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAS,0CAA0C,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAW,wCAAwC,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAY,uCAAuC,CAAA;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAU,yCAAyC,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAQ,2CAA2C,CAAA;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAY,uCAAuC,CAAA;AAG3E,OAAO,EAAE,oBAAoB,EAAE,MAAO,4CAA4C,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,MAAe,oCAAoC,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAc,qCAAqC,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAe,oCAAoC,CAAA;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAS,0CAA0C,CAAA;AAGhF,OAAO,EAAE,oBAAoB,EAAE,MAAW,+CAA+C,CAAA;AACzF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oDAAoD,CAAA;AAG9F,YAAY,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAA;AAC7F,YAAY,EAAE,oBAAoB,EAAE,MAAY,uCAAuC,CAAA;AACvF,YAAY,EAAE,sBAAsB,EAAE,MAAU,yCAAyC,CAAA;AACzF,YAAY,EAAE,uBAAuB,EAAE,MAAS,0CAA0C,CAAA;AAC1F,YAAY,EAAE,qBAAqB,EAAE,MAAW,wCAAwC,CAAA;AACxF,YAAY,EAAE,oBAAoB,EAAE,MAAY,uCAAuC,CAAA;AACvF,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAA;AACvG,YAAY,EAAE,2BAA2B,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAA;AAC5G,YAAY,EAAE,mBAAmB,EAAE,MAAa,oCAAoC,CAAA;AACpF,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC1F,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAQ,oCAAoC,CAAA;AACzF,YAAY,EAAE,2BAA2B,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAA;AAClH,YAAY,EAAE,wBAAwB,EAAE,MAAO,2CAA2C,CAAA;AAC1F,YAAY,EAAE,oBAAoB,EAAE,MAAW,uCAAuC,CAAA;AACtF,YAAY,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// ── Core ──────────────────────────────────────────────────────────────────────
|
|
2
|
+
export { BaseModifier } from './core/BaseModifier.js';
|
|
3
|
+
export { ModifierStack } from './core/ModifierStack.js';
|
|
4
|
+
// ── Generate modifiers ────────────────────────────────────────────────────────
|
|
5
|
+
export { SubdivisionModifier } from './modifiers/generate/SubdivisionModifier.js';
|
|
6
|
+
export { ArrayModifier } from './modifiers/generate/ArrayModifier.js';
|
|
7
|
+
export { ExtrudeModifier } from './modifiers/generate/ExtrudeModifier.js';
|
|
8
|
+
export { SolidifyModifier } from './modifiers/generate/SolidifyModifier.js';
|
|
9
|
+
export { MirrorModifier } from './modifiers/generate/MirrorModifier.js';
|
|
10
|
+
export { OceanModifier } from './modifiers/generate/OceanModifier.js';
|
|
11
|
+
export { BooleanModifier } from './modifiers/generate/BooleanModifier.js';
|
|
12
|
+
export { WireframeModifier } from './modifiers/generate/WireframeModifier.js';
|
|
13
|
+
export { BevelModifier } from './modifiers/generate/BevelModifier.js';
|
|
14
|
+
// ── Deform modifiers ──────────────────────────────────────────────────────────
|
|
15
|
+
export { DisplacementModifier } from './modifiers/deform/DisplacementModifier.js';
|
|
16
|
+
export { WarpModifier } from './modifiers/deform/WarpModifier.js';
|
|
17
|
+
export { TwistModifier } from './modifiers/deform/TwistModifier.js';
|
|
18
|
+
export { BendModifier } from './modifiers/deform/BendModifier.js';
|
|
19
|
+
export { ShrinkwrapModifier } from './modifiers/deform/ShrinkwrapModifier.js';
|
|
20
|
+
// ── Transform modifiers ───────────────────────────────────────────────────────
|
|
21
|
+
export { UVProjectionModifier } from './modifiers/transform/UVProjectionModifier.js';
|
|
22
|
+
export { NormalRecalculateModifier } from './modifiers/transform/NormalRecalculateModifier.js';
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,YAAY,EAAE,MAAS,wBAAwB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAQ,yBAAyB,CAAA;AAEzD,iFAAiF;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAA;AACjF,OAAO,EAAE,aAAa,EAAE,MAAY,uCAAuC,CAAA;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAU,yCAAyC,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAS,0CAA0C,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAW,wCAAwC,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAY,uCAAuC,CAAA;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAU,yCAAyC,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAQ,2CAA2C,CAAA;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAY,uCAAuC,CAAA;AAE3E,iFAAiF;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAO,4CAA4C,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,MAAe,oCAAoC,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAc,qCAAqC,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAe,oCAAoC,CAAA;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAS,0CAA0C,CAAA;AAEhF,iFAAiF;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAW,+CAA+C,CAAA;AACzF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oDAAoD,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
export type BendAxis = 'x' | 'y' | 'z';
|
|
4
|
+
export interface BendModifierOptions {
|
|
5
|
+
angle?: number;
|
|
6
|
+
axis?: BendAxis;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Bend Modifier — Blender "Simple Deform" (Bend mode) equivalent.
|
|
10
|
+
* Bends geometry around an axis by wrapping it along a circular arc.
|
|
11
|
+
* A 2π angle wraps the geometry into a full ring.
|
|
12
|
+
*
|
|
13
|
+
* parameters.angle: total bend angle in radians
|
|
14
|
+
*/
|
|
15
|
+
export declare class BendModifier extends BaseModifier {
|
|
16
|
+
get name(): string;
|
|
17
|
+
parameters: Record<string, number>;
|
|
18
|
+
axis: BendAxis;
|
|
19
|
+
constructor(options?: BendModifierOptions);
|
|
20
|
+
apply(geometry: BufferGeometry): BufferGeometry;
|
|
21
|
+
private _axisVal;
|
|
22
|
+
private _offsetVal;
|
|
23
|
+
private _applyBend;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=BendModifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BendModifier.d.ts","sourceRoot":"","sources":["../../../src/modifiers/deform/BendModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAEtC,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAG,QAAQ,CAAA;CACjB;AAED;;;;;;GAMG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,IAAI,IAAI,WAAoB;IAE5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,IAAI,EAAE,QAAQ,CAAA;gBAEF,OAAO,GAAE,mBAAwB;IAM7C,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc;IA8C/C,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,UAAU;CAQnB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { BufferGeometry, BufferAttribute } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Bend Modifier — Blender "Simple Deform" (Bend mode) equivalent.
|
|
5
|
+
* Bends geometry around an axis by wrapping it along a circular arc.
|
|
6
|
+
* A 2π angle wraps the geometry into a full ring.
|
|
7
|
+
*
|
|
8
|
+
* parameters.angle: total bend angle in radians
|
|
9
|
+
*/
|
|
10
|
+
export class BendModifier extends BaseModifier {
|
|
11
|
+
get name() { return 'Bend'; }
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
super();
|
|
14
|
+
this.parameters = { angle: options.angle ?? Math.PI * 0.5 };
|
|
15
|
+
this.axis = options.axis ?? 'y';
|
|
16
|
+
}
|
|
17
|
+
apply(geometry) {
|
|
18
|
+
const angle = this.parameters.angle;
|
|
19
|
+
const srcPos = geometry.getAttribute('position');
|
|
20
|
+
const srcUv = geometry.getAttribute('uv');
|
|
21
|
+
const srcIdx = geometry.getIndex();
|
|
22
|
+
const vCount = srcPos.count;
|
|
23
|
+
if (Math.abs(angle) < 1e-6)
|
|
24
|
+
return geometry;
|
|
25
|
+
// Find extent along bend axis
|
|
26
|
+
let min = Infinity, max = -Infinity;
|
|
27
|
+
for (let v = 0; v < vCount; v++) {
|
|
28
|
+
const val = this._axisVal(srcPos, v);
|
|
29
|
+
if (val < min)
|
|
30
|
+
min = val;
|
|
31
|
+
if (val > max)
|
|
32
|
+
max = val;
|
|
33
|
+
}
|
|
34
|
+
const range = max - min || 1;
|
|
35
|
+
const radius = range / angle;
|
|
36
|
+
const outPos = new Float32Array(vCount * 3);
|
|
37
|
+
const outNorm = new Float32Array(vCount * 3);
|
|
38
|
+
for (let v = 0; v < vCount; v++) {
|
|
39
|
+
const t = (this._axisVal(srcPos, v) - min) / range;
|
|
40
|
+
const a = t * angle - angle * 0.5;
|
|
41
|
+
const cos = Math.cos(a), sin = Math.sin(a);
|
|
42
|
+
const off = this._offsetVal(srcPos, v);
|
|
43
|
+
const r = radius + off;
|
|
44
|
+
const [px, py, pz] = this._applyBend(r, a, cos, sin, srcPos, v);
|
|
45
|
+
outPos[v * 3] = px;
|
|
46
|
+
outPos[v * 3 + 1] = py;
|
|
47
|
+
outPos[v * 3 + 2] = pz;
|
|
48
|
+
// Outward normal points radially
|
|
49
|
+
outNorm[v * 3] = cos;
|
|
50
|
+
outNorm[v * 3 + 1] = 0;
|
|
51
|
+
outNorm[v * 3 + 2] = sin;
|
|
52
|
+
}
|
|
53
|
+
const result = new BufferGeometry();
|
|
54
|
+
result.setAttribute('position', new BufferAttribute(outPos, 3));
|
|
55
|
+
result.setAttribute('normal', new BufferAttribute(outNorm, 3));
|
|
56
|
+
if (srcUv)
|
|
57
|
+
result.setAttribute('uv', srcUv.clone());
|
|
58
|
+
if (srcIdx)
|
|
59
|
+
result.setIndex(srcIdx.clone());
|
|
60
|
+
result.computeVertexNormals();
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
_axisVal(pos, v) {
|
|
64
|
+
if (this.axis === 'x')
|
|
65
|
+
return pos.getX(v);
|
|
66
|
+
if (this.axis === 'z')
|
|
67
|
+
return pos.getZ(v);
|
|
68
|
+
return pos.getX(v);
|
|
69
|
+
}
|
|
70
|
+
_offsetVal(pos, v) {
|
|
71
|
+
if (this.axis === 'y')
|
|
72
|
+
return pos.getZ(v);
|
|
73
|
+
return pos.getY(v);
|
|
74
|
+
}
|
|
75
|
+
_applyBend(r, _a, cos, sin, pos, v) {
|
|
76
|
+
if (this.axis === 'y')
|
|
77
|
+
return [r * sin, pos.getY(v), r * cos];
|
|
78
|
+
if (this.axis === 'x')
|
|
79
|
+
return [pos.getX(v), r * sin, r * cos];
|
|
80
|
+
return [r * cos, r * sin, pos.getZ(v)];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=BendModifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BendModifier.js","sourceRoot":"","sources":["../../../src/modifiers/deform/BendModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AASzD;;;;;;GAMG;AACH,MAAM,OAAO,YAAa,SAAQ,YAAY;IAC5C,IAAI,IAAI,KAAK,OAAO,MAAM,CAAA,CAAC,CAAC;IAK5B,YAAY,UAA+B,EAAE;QAC3C,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,UAAU,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAA;QAC3D,IAAI,CAAC,IAAI,GAAS,OAAO,CAAC,IAAI,IAAI,GAAG,CAAA;IACvC,CAAC;IAED,KAAK,CAAC,QAAwB;QAC5B,MAAM,KAAK,GAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAA;QACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;QAChD,MAAM,KAAK,GAAI,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;QAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAA;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAA;QAE3B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI;YAAE,OAAO,QAAQ,CAAA;QAE3C,8BAA8B;QAC9B,IAAI,GAAG,GAAG,QAAQ,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAA;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;YACpC,IAAI,GAAG,GAAG,GAAG;gBAAE,GAAG,GAAG,GAAG,CAAA;YACxB,IAAI,GAAG,GAAG,GAAG;gBAAE,GAAG,GAAG,GAAG,CAAA;QAC1B,CAAC;QACD,MAAM,KAAK,GAAI,GAAG,GAAG,GAAG,IAAI,CAAC,CAAA;QAC7B,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,CAAA;QAE5B,MAAM,MAAM,GAAI,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAC5C,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,CAAC,GAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAA;YACpD,MAAM,CAAC,GAAK,CAAC,GAAG,KAAK,GAAG,KAAK,GAAG,GAAG,CAAA;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YAE1C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;YACtC,MAAM,CAAC,GAAK,MAAM,GAAG,GAAG,CAAA;YAExB,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;YAC/D,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YAAC,MAAM,CAAC,CAAC,GAAC,CAAC,GAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YAAC,MAAM,CAAC,CAAC,GAAC,CAAC,GAAC,CAAC,CAAC,GAAG,EAAE,CAAA;YAExD,iCAAiC;YACjC,OAAO,CAAC,CAAC,GAAC,CAAC,CAAC,GAAG,GAAG,CAAC;YAAC,OAAO,CAAC,CAAC,GAAC,CAAC,GAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO,CAAC,CAAC,GAAC,CAAC,GAAC,CAAC,CAAC,GAAG,GAAG,CAAA;QAC9D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAA;QACnC,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;QAC/D,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAI,IAAI,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;QAChE,IAAI,KAAK;YAAG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;QACpD,IAAI,MAAM;YAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;QAC3C,MAAM,CAAC,oBAAoB,EAAE,CAAA;QAC7B,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,QAAQ,CAAC,GAA+C,EAAE,CAAS;QACzE,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzC,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzC,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACpB,CAAC;IAEO,UAAU,CAAC,GAA+C,EAAE,CAAS;QAC3E,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzC,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACpB,CAAC;IAEO,UAAU,CAChB,CAAS,EAAE,EAAU,EAAE,GAAW,EAAE,GAAW,EAC/C,GAA+C,EAAE,CAAS;QAE1D,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG;YAAE,OAAO,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAA;QAC7D,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAA;QAC7D,OAAO,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,CAAC;CACF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
/** Noise/height callback — any function that maps a 3D point to a scalar displacement value. */
|
|
4
|
+
export type NoiseFunction = (x: number, y: number, z: number) => number;
|
|
5
|
+
export interface DisplacementModifierOptions {
|
|
6
|
+
/** Displacement magnitude. */
|
|
7
|
+
strength?: number;
|
|
8
|
+
/** Midlevel: 0.5 means the surface sits at the midpoint of the noise range. */
|
|
9
|
+
midlevel?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Noise/height function: (x, y, z) => value in [0, 1].
|
|
12
|
+
* Completely decoupled — pass any noise library, st-shader-core CPU noise, or a custom function.
|
|
13
|
+
* @example (x, y, z) => (Math.sin(x * 4) * 0.5 + 0.5)
|
|
14
|
+
* @example (x, y, z) => simplexNoise.noise3D(x, y, z) * 0.5 + 0.5
|
|
15
|
+
*/
|
|
16
|
+
noiseFunction?: NoiseFunction;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Displacement Modifier — Blender "Displace" modifier equivalent.
|
|
20
|
+
* Pushes each vertex along its normal by a distance driven by a noise function.
|
|
21
|
+
*
|
|
22
|
+
* The noiseFunction callback is deliberately decoupled — it accepts any source:
|
|
23
|
+
* a math expression, simplex noise, Perlin noise, a texture sample, or a
|
|
24
|
+
* CPU-side equivalent from st-shader-core. This keeps st-modifier-core independent.
|
|
25
|
+
*
|
|
26
|
+
* parameters.strength: displacement magnitude
|
|
27
|
+
* parameters.midlevel: 0 = only positive displacement, 0.5 = centered, 1 = only negative
|
|
28
|
+
*
|
|
29
|
+
* Run SubdivisionModifier first for smooth results.
|
|
30
|
+
*/
|
|
31
|
+
export declare class DisplacementModifier extends BaseModifier {
|
|
32
|
+
get name(): string;
|
|
33
|
+
parameters: Record<string, number>;
|
|
34
|
+
noiseFunction: NoiseFunction;
|
|
35
|
+
constructor(options?: DisplacementModifierOptions);
|
|
36
|
+
apply(geometry: BufferGeometry): BufferGeometry;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=DisplacementModifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DisplacementModifier.d.ts","sourceRoot":"","sources":["../../../src/modifiers/deform/DisplacementModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAEzD,gGAAgG;AAChG,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;AAEvE,MAAM,WAAW,2BAA2B;IAC1C,8BAA8B;IAC9B,QAAQ,CAAC,EAAO,MAAM,CAAA;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,EAAO,MAAM,CAAA;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,IAAI,IAAI,WAAwB;IAEhC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,aAAa,EAAE,aAAa,CAAA;gBAEhB,OAAO,GAAE,2BAAgC;IASrD,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc;CAkChD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { BufferGeometry, BufferAttribute } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Displacement Modifier — Blender "Displace" modifier equivalent.
|
|
5
|
+
* Pushes each vertex along its normal by a distance driven by a noise function.
|
|
6
|
+
*
|
|
7
|
+
* The noiseFunction callback is deliberately decoupled — it accepts any source:
|
|
8
|
+
* a math expression, simplex noise, Perlin noise, a texture sample, or a
|
|
9
|
+
* CPU-side equivalent from st-shader-core. This keeps st-modifier-core independent.
|
|
10
|
+
*
|
|
11
|
+
* parameters.strength: displacement magnitude
|
|
12
|
+
* parameters.midlevel: 0 = only positive displacement, 0.5 = centered, 1 = only negative
|
|
13
|
+
*
|
|
14
|
+
* Run SubdivisionModifier first for smooth results.
|
|
15
|
+
*/
|
|
16
|
+
export class DisplacementModifier extends BaseModifier {
|
|
17
|
+
get name() { return 'Displace'; }
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
super();
|
|
20
|
+
this.parameters = {
|
|
21
|
+
strength: options.strength ?? 1.0,
|
|
22
|
+
midlevel: options.midlevel ?? 0.5,
|
|
23
|
+
};
|
|
24
|
+
this.noiseFunction = options.noiseFunction ?? (() => 0.5);
|
|
25
|
+
}
|
|
26
|
+
apply(geometry) {
|
|
27
|
+
const strength = this.parameters.strength;
|
|
28
|
+
const midlevel = this.parameters.midlevel;
|
|
29
|
+
const srcPos = geometry.getAttribute('position');
|
|
30
|
+
const srcNorm = geometry.getAttribute('normal');
|
|
31
|
+
const srcUv = geometry.getAttribute('uv');
|
|
32
|
+
const srcIdx = geometry.getIndex();
|
|
33
|
+
const vCount = srcPos.count;
|
|
34
|
+
const outPos = new Float32Array(vCount * 3);
|
|
35
|
+
for (let v = 0; v < vCount; v++) {
|
|
36
|
+
const px = srcPos.getX(v), py = srcPos.getY(v), pz = srcPos.getZ(v);
|
|
37
|
+
const nx = srcNorm ? srcNorm.getX(v) : 0;
|
|
38
|
+
const ny = srcNorm ? srcNorm.getY(v) : 1;
|
|
39
|
+
const nz = srcNorm ? srcNorm.getZ(v) : 0;
|
|
40
|
+
const noiseVal = Math.max(0, Math.min(1, this.noiseFunction(px, py, pz)));
|
|
41
|
+
const disp = (noiseVal - midlevel) * strength;
|
|
42
|
+
outPos[v * 3] = px + nx * disp;
|
|
43
|
+
outPos[v * 3 + 1] = py + ny * disp;
|
|
44
|
+
outPos[v * 3 + 2] = pz + nz * disp;
|
|
45
|
+
}
|
|
46
|
+
const result = new BufferGeometry();
|
|
47
|
+
result.setAttribute('position', new BufferAttribute(outPos, 3));
|
|
48
|
+
if (srcNorm)
|
|
49
|
+
result.setAttribute('normal', srcNorm.clone());
|
|
50
|
+
if (srcUv)
|
|
51
|
+
result.setAttribute('uv', srcUv.clone());
|
|
52
|
+
if (srcIdx)
|
|
53
|
+
result.setIndex(srcIdx.clone());
|
|
54
|
+
result.computeVertexNormals();
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=DisplacementModifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DisplacementModifier.js","sourceRoot":"","sources":["../../../src/modifiers/deform/DisplacementModifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
export interface ShrinkwrapModifierOptions {
|
|
4
|
+
offset?: number;
|
|
5
|
+
factor?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Shrinkwrap Modifier — Blender "Shrinkwrap" modifier equivalent.
|
|
9
|
+
* Projects each vertex of the source geometry onto the nearest point on a
|
|
10
|
+
* target surface (brute-force BVH-lite over all triangles).
|
|
11
|
+
*
|
|
12
|
+
* parameters.offset: distance above the surface after projection
|
|
13
|
+
* parameters.factor: blend [0–1] between original position and projected position
|
|
14
|
+
*
|
|
15
|
+
* Constructor: new ShrinkwrapModifier(targetGeometry, options?)
|
|
16
|
+
*/
|
|
17
|
+
export declare class ShrinkwrapModifier extends BaseModifier {
|
|
18
|
+
get name(): string;
|
|
19
|
+
parameters: Record<string, number>;
|
|
20
|
+
private readonly _target;
|
|
21
|
+
constructor(target: BufferGeometry, options?: ShrinkwrapModifierOptions);
|
|
22
|
+
apply(geometry: BufferGeometry): BufferGeometry;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=ShrinkwrapModifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShrinkwrapModifier.d.ts","sourceRoot":"","sources":["../../../src/modifiers/deform/ShrinkwrapModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAsC,MAAM,OAAO,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,IAAI,IAAI,WAA0B;IAElC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAElC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;gBAE5B,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,yBAA8B;IAS3E,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc;CAyGhD"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { BufferGeometry, BufferAttribute, Triangle, Vector3 } from 'three';
|
|
2
|
+
import { BaseModifier } from '../../core/BaseModifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Shrinkwrap Modifier — Blender "Shrinkwrap" modifier equivalent.
|
|
5
|
+
* Projects each vertex of the source geometry onto the nearest point on a
|
|
6
|
+
* target surface (brute-force BVH-lite over all triangles).
|
|
7
|
+
*
|
|
8
|
+
* parameters.offset: distance above the surface after projection
|
|
9
|
+
* parameters.factor: blend [0–1] between original position and projected position
|
|
10
|
+
*
|
|
11
|
+
* Constructor: new ShrinkwrapModifier(targetGeometry, options?)
|
|
12
|
+
*/
|
|
13
|
+
export class ShrinkwrapModifier extends BaseModifier {
|
|
14
|
+
get name() { return 'Shrinkwrap'; }
|
|
15
|
+
constructor(target, options = {}) {
|
|
16
|
+
super();
|
|
17
|
+
this._target = target;
|
|
18
|
+
this.parameters = {
|
|
19
|
+
offset: options.offset ?? 0.0,
|
|
20
|
+
factor: Math.max(0, Math.min(1, options.factor ?? 1.0)),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
apply(geometry) {
|
|
24
|
+
const factor = Math.max(0, Math.min(1, this.parameters.factor));
|
|
25
|
+
const offset = this.parameters.offset;
|
|
26
|
+
const srcPos = geometry.getAttribute('position');
|
|
27
|
+
const srcNorm = geometry.getAttribute('normal');
|
|
28
|
+
const srcUv = geometry.getAttribute('uv');
|
|
29
|
+
const vCount = srcPos.count;
|
|
30
|
+
// Pre-build target triangle list
|
|
31
|
+
const tgtPos = this._target.getAttribute('position');
|
|
32
|
+
const tgtIdx = this._target.getIndex();
|
|
33
|
+
const tgtVCount = tgtPos.count;
|
|
34
|
+
// Build flat triangle list for target
|
|
35
|
+
const tris = [];
|
|
36
|
+
if (tgtIdx) {
|
|
37
|
+
const ia = tgtIdx.array;
|
|
38
|
+
for (let i = 0; i < ia.length; i += 3)
|
|
39
|
+
tris.push([ia[i], ia[i + 1], ia[i + 2]]);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
for (let i = 0; i < tgtVCount; i += 3)
|
|
43
|
+
tris.push([i, i + 1, i + 2]);
|
|
44
|
+
}
|
|
45
|
+
const outPos = [];
|
|
46
|
+
const outNorm = [];
|
|
47
|
+
const outUv = [];
|
|
48
|
+
const tri = new Triangle();
|
|
49
|
+
const tA = new Vector3();
|
|
50
|
+
const tB = new Vector3();
|
|
51
|
+
const tC = new Vector3();
|
|
52
|
+
const closest = new Vector3();
|
|
53
|
+
const best = new Vector3();
|
|
54
|
+
const triNorm = new Vector3();
|
|
55
|
+
const origPt = new Vector3();
|
|
56
|
+
const projected = new Vector3();
|
|
57
|
+
for (let v = 0; v < vCount; v++) {
|
|
58
|
+
origPt.set(srcPos.getX(v), srcPos.getY(v), srcPos.getZ(v));
|
|
59
|
+
let bestDist = Infinity;
|
|
60
|
+
for (const [ai, bi, ci] of tris) {
|
|
61
|
+
tA.set(tgtPos.getX(ai), tgtPos.getY(ai), tgtPos.getZ(ai));
|
|
62
|
+
tB.set(tgtPos.getX(bi), tgtPos.getY(bi), tgtPos.getZ(bi));
|
|
63
|
+
tC.set(tgtPos.getX(ci), tgtPos.getY(ci), tgtPos.getZ(ci));
|
|
64
|
+
tri.set(tA, tB, tC);
|
|
65
|
+
tri.closestPointToPoint(origPt, closest);
|
|
66
|
+
const d = origPt.distanceToSquared(closest);
|
|
67
|
+
if (d < bestDist) {
|
|
68
|
+
bestDist = d;
|
|
69
|
+
best.copy(closest);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Compute surface normal at closest point (face normal of target mesh at best)
|
|
73
|
+
// Use the best-matching triangle normal
|
|
74
|
+
let bestTriNorm = null;
|
|
75
|
+
if (tris.length > 0) {
|
|
76
|
+
bestDist = Infinity;
|
|
77
|
+
for (const [ai, bi, ci] of tris) {
|
|
78
|
+
tA.set(tgtPos.getX(ai), tgtPos.getY(ai), tgtPos.getZ(ai));
|
|
79
|
+
tB.set(tgtPos.getX(bi), tgtPos.getY(bi), tgtPos.getZ(bi));
|
|
80
|
+
tC.set(tgtPos.getX(ci), tgtPos.getY(ci), tgtPos.getZ(ci));
|
|
81
|
+
tri.set(tA, tB, tC);
|
|
82
|
+
tri.closestPointToPoint(origPt, closest);
|
|
83
|
+
const d = origPt.distanceToSquared(closest);
|
|
84
|
+
if (d < bestDist) {
|
|
85
|
+
bestDist = d;
|
|
86
|
+
tri.getNormal(triNorm);
|
|
87
|
+
bestTriNorm = triNorm.clone();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Projected position = best point + normal * offset
|
|
92
|
+
if (bestTriNorm) {
|
|
93
|
+
projected.copy(best).addScaledVector(bestTriNorm, offset);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
projected.copy(best);
|
|
97
|
+
}
|
|
98
|
+
// Lerp between original and projected by factor
|
|
99
|
+
const px = origPt.x + (projected.x - origPt.x) * factor;
|
|
100
|
+
const py = origPt.y + (projected.y - origPt.y) * factor;
|
|
101
|
+
const pz = origPt.z + (projected.z - origPt.z) * factor;
|
|
102
|
+
outPos.push(px, py, pz);
|
|
103
|
+
if (srcNorm)
|
|
104
|
+
outNorm.push(srcNorm.getX(v), srcNorm.getY(v), srcNorm.getZ(v));
|
|
105
|
+
if (srcUv)
|
|
106
|
+
outUv.push(srcUv.getX(v), srcUv.getY(v));
|
|
107
|
+
}
|
|
108
|
+
// Copy index if present
|
|
109
|
+
const result = new BufferGeometry();
|
|
110
|
+
result.setAttribute('position', new BufferAttribute(new Float32Array(outPos), 3));
|
|
111
|
+
if (srcNorm)
|
|
112
|
+
result.setAttribute('normal', new BufferAttribute(new Float32Array(outNorm), 3));
|
|
113
|
+
if (srcUv)
|
|
114
|
+
result.setAttribute('uv', new BufferAttribute(new Float32Array(outUv), 2));
|
|
115
|
+
const srcIdx = geometry.getIndex();
|
|
116
|
+
if (srcIdx)
|
|
117
|
+
result.setIndex(new BufferAttribute(new Uint32Array(srcIdx.array), 1));
|
|
118
|
+
result.computeVertexNormals();
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=ShrinkwrapModifier.js.map
|