@woosh/meep-engine 3.14.4 → 3.14.5
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/package.json +1 -1
- package/src/core/geom/3d/mat4/m4_rigidity_defect.d.ts +30 -0
- package/src/core/geom/3d/mat4/m4_rigidity_defect.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_rigidity_defect.js +71 -0
- package/src/engine/network/orchestrator/NetworkPeer.d.ts +56 -8
- package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +263 -67
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +6 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +6 -0
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +13 -7
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +103 -138
- package/src/engine/network/replication/Replicator.d.ts +29 -6
- package/src/engine/network/replication/Replicator.d.ts.map +1 -1
- package/src/engine/network/replication/Replicator.js +265 -108
- package/src/engine/network/sim/ActionLog.d.ts +2 -0
- package/src/engine/network/sim/ActionLog.d.ts.map +1 -1
- package/src/engine/network/sim/ActionLog.js +2 -0
- package/src/engine/network/sim/ActionRecordCursor.d.ts +82 -0
- package/src/engine/network/sim/ActionRecordCursor.d.ts.map +1 -0
- package/src/engine/network/sim/ActionRecordCursor.js +120 -0
- package/src/engine/network/sim/RewindEngine.d.ts.map +1 -1
- package/src/engine/network/sim/RewindEngine.js +13 -29
- package/src/engine/network/sim/SimActionExecutor.d.ts +2 -3
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +10 -11
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_scene.js +38 -37
- package/src/shade/playground/skinned_mesh_soup/README.md +39 -18
- package/src/shade/playground/skinned_mesh_soup/index.html +9 -6
- package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/main.js +16 -13
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts +8 -2
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +23 -4
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +1958 -1796
- package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +357 -0
- package/src/shade/renderer/animation/skin_bind_transform.d.ts +25 -0
- package/src/shade/renderer/animation/skin_bind_transform.d.ts.map +1 -0
- package/src/shade/renderer/animation/skin_bind_transform.js +33 -0
- package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts +67 -0
- package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts.map +1 -0
- package/src/shade/renderer/animation/skin_clip_scale_conflicts.js +199 -0
- package/src/shade/renderer/animation/skin_frame_defect.d.ts +34 -0
- package/src/shade/renderer/animation/skin_frame_defect.d.ts.map +1 -0
- package/src/shade/renderer/animation/skin_frame_defect.js +132 -0
- package/src/shade/renderer/animation/skin_joint_matrix.d.ts +24 -0
- package/src/shade/renderer/animation/skin_joint_matrix.d.ts.map +1 -0
- package/src/shade/renderer/animation/skin_joint_matrix.js +46 -0
- package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts +70 -0
- package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts.map +1 -0
- package/src/shade/renderer/animation/skin_normalize_mesh_frame.js +216 -0
- package/src/shade/renderer/animation/skin_test_fixtures.d.ts +86 -0
- package/src/shade/renderer/animation/skin_test_fixtures.d.ts.map +1 -0
- package/src/shade/renderer/animation/skin_test_fixtures.js +250 -0
- package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.d.ts +18 -4
- package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +18 -4
- package/src/shade/renderer/particles/DESIGN.md +5 -5
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +43 -0
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +44 -0
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +33 -59
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +185 -118
- package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts +15 -10
- package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/compile_particle_graph.js +205 -170
- package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts +44 -0
- package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_graph_authoring.js +108 -0
- package/src/shade/renderer/particles/particle_prototype.d.ts.map +1 -1
- package/src/shade/renderer/particles/particle_prototype.js +181 -180
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +4 -4
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/create_particle_effect.js +19 -19
- package/src/shade/renderer/particles/vm/chunk_particle_vm.js +1 -1
- package/src/shade/renderer/scene/SkinnedMesh.d.ts +11 -0
- package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +1 -1
- package/src/shade/renderer/scene/SkinnedMesh.js +11 -0
- package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_from_m4.d.ts +33 -3
- package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_from_m4.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_from_m4.js +58 -37
- package/src/shade/renderer/particles/graph/ParticleGraph.d.ts +0 -54
- package/src/shade/renderer/particles/graph/ParticleGraph.d.ts.map +0 -1
- package/src/shade/renderer/particles/graph/ParticleGraph.js +0 -99
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A particle node type: a {@link NodeDescription} that additionally knows how to lower an instance
|
|
3
|
+
* of itself into VM instructions.
|
|
4
|
+
*
|
|
5
|
+
* Ports carry all the structure the compiler needs — input ports name the operands, the presence of
|
|
6
|
+
* an output port says whether the node produces a value — so nothing about the graph's shape is
|
|
7
|
+
* duplicated outside the description.
|
|
8
|
+
*/
|
|
9
|
+
export class ParticleNodeDescription extends NodeDescription {
|
|
10
|
+
/**
|
|
11
|
+
* Lower one instance of this node into the target instruction stream.
|
|
12
|
+
*
|
|
13
|
+
* `context` provides:
|
|
14
|
+
* - `context.in(port_name)` → the register holding that input's value (resolved by the compiler),
|
|
15
|
+
* - `context.out` → the output register (value-producing nodes only, `undefined` for sinks),
|
|
16
|
+
* - `context.parameters` → the {@link NodeInstance}'s parameters,
|
|
17
|
+
* - `context.layout` → the {@link ../layout/ParticleLayout.js} for attribute offsets,
|
|
18
|
+
* - `context.asm` → the {@link ../isa/ParticleAssembler.js} for interning constants.
|
|
19
|
+
*
|
|
20
|
+
* @type {function(InstructionStream, {in: function(string):number, out: number|undefined, parameters: object, layout: ParticleLayout, asm: ParticleAssembler}):void}
|
|
21
|
+
*/
|
|
22
|
+
emit: (arg0: InstructionStream, arg1: {
|
|
23
|
+
in: (arg0: string) => number;
|
|
24
|
+
out: number | undefined;
|
|
25
|
+
parameters: object;
|
|
26
|
+
layout: ParticleLayout;
|
|
27
|
+
asm: ParticleAssembler;
|
|
28
|
+
}) => void;
|
|
29
|
+
/**
|
|
30
|
+
* A node with no output ports produces no value, so nothing can consume it; the only reason to
|
|
31
|
+
* emit it is its side effect (an attribute write, a kill). Such nodes are the roots the compiler
|
|
32
|
+
* traverses from.
|
|
33
|
+
* @returns {boolean}
|
|
34
|
+
*/
|
|
35
|
+
get is_sink(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* @readonly
|
|
38
|
+
* @type {boolean}
|
|
39
|
+
*/
|
|
40
|
+
readonly isParticleNodeDescription: boolean;
|
|
41
|
+
}
|
|
42
|
+
import { NodeDescription } from "../../../../core/model/node-graph/node/NodeDescription.js";
|
|
43
|
+
//# sourceMappingURL=ParticleNodeDescription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ParticleNodeDescription.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/graph/ParticleNodeDescription.js"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH;IAEI;;;;;;;;;;;OAWG;IACH,sCAFsC;QAAC,EAAE,SAAW,MAAM,KAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAC,SAAS,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,iBAAiB;QAAC,GAAG,oBAAmB;KAAC,KAAE,IAAI,CAExJ;IAEZ;;;;;OAKG;IACH,uBAEC;IAGL;;;OAGG;IACH,oCAFU,OAAO,CAE0C;CAN1D;gCApC+B,2DAA2D"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { noop } from "../../../../core/function/noop.js";
|
|
2
|
+
import { NodeDescription } from "../../../../core/model/node-graph/node/NodeDescription.js";
|
|
3
|
+
import { PortDirection } from "../../../../core/model/node-graph/node/PortDirection.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A particle node type: a {@link NodeDescription} that additionally knows how to lower an instance
|
|
7
|
+
* of itself into VM instructions.
|
|
8
|
+
*
|
|
9
|
+
* Ports carry all the structure the compiler needs — input ports name the operands, the presence of
|
|
10
|
+
* an output port says whether the node produces a value — so nothing about the graph's shape is
|
|
11
|
+
* duplicated outside the description.
|
|
12
|
+
*/
|
|
13
|
+
export class ParticleNodeDescription extends NodeDescription {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Lower one instance of this node into the target instruction stream.
|
|
17
|
+
*
|
|
18
|
+
* `context` provides:
|
|
19
|
+
* - `context.in(port_name)` → the register holding that input's value (resolved by the compiler),
|
|
20
|
+
* - `context.out` → the output register (value-producing nodes only, `undefined` for sinks),
|
|
21
|
+
* - `context.parameters` → the {@link NodeInstance}'s parameters,
|
|
22
|
+
* - `context.layout` → the {@link ../layout/ParticleLayout.js} for attribute offsets,
|
|
23
|
+
* - `context.asm` → the {@link ../isa/ParticleAssembler.js} for interning constants.
|
|
24
|
+
*
|
|
25
|
+
* @type {function(InstructionStream, {in: function(string):number, out: number|undefined, parameters: object, layout: ParticleLayout, asm: ParticleAssembler}):void}
|
|
26
|
+
*/
|
|
27
|
+
emit = noop;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A node with no output ports produces no value, so nothing can consume it; the only reason to
|
|
31
|
+
* emit it is its side effect (an attribute write, a kill). Such nodes are the roots the compiler
|
|
32
|
+
* traverses from.
|
|
33
|
+
* @returns {boolean}
|
|
34
|
+
*/
|
|
35
|
+
get is_sink() {
|
|
36
|
+
return !this.hasPortsByDirection(PortDirection.Out);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @readonly
|
|
42
|
+
* @type {boolean}
|
|
43
|
+
*/
|
|
44
|
+
ParticleNodeDescription.prototype.isParticleNodeDescription = true;
|
|
@@ -1,60 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export namespace pow { }
|
|
35
|
-
export namespace step { }
|
|
36
|
-
export namespace mad { }
|
|
37
|
-
export namespace mix { }
|
|
38
|
-
export namespace clamp { }
|
|
39
|
-
export namespace smoothstep { }
|
|
40
|
-
export namespace scale { }
|
|
41
|
-
export namespace neg { }
|
|
42
|
-
export namespace abs { }
|
|
43
|
-
export namespace floor { }
|
|
44
|
-
export namespace fract { }
|
|
45
|
-
export namespace sqrt { }
|
|
46
|
-
export namespace sin { }
|
|
47
|
-
export namespace cos { }
|
|
48
|
-
export namespace exp { }
|
|
49
|
-
export namespace log { }
|
|
50
|
-
export namespace normalize { }
|
|
51
|
-
export namespace length { }
|
|
52
|
-
export namespace dot { }
|
|
53
|
-
export namespace cross { }
|
|
54
|
-
export namespace distance { }
|
|
55
|
-
export namespace swizzle { }
|
|
56
|
-
export namespace compare { }
|
|
57
|
-
export namespace select { }
|
|
58
|
-
export namespace curve { }
|
|
59
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Look up a node type by name.
|
|
3
|
+
* @param {string} name
|
|
4
|
+
* @returns {ParticleNodeDescription}
|
|
5
|
+
* @throws if no such node type exists
|
|
6
|
+
*/
|
|
7
|
+
export function get_particle_node_description(name: string): ParticleNodeDescription;
|
|
8
|
+
/**
|
|
9
|
+
* Standard particle-node library, expressed as {@link ParticleNodeDescription}s in a
|
|
10
|
+
* {@link NodeRegistry}. Nodes are value-producing operations (constants, builtins, attribute reads,
|
|
11
|
+
* math, curves, random) or sinks (attribute writes, kill).
|
|
12
|
+
*
|
|
13
|
+
* These lower to the same opcodes the JS reference + WGSL interpreter agree on, so any effect
|
|
14
|
+
* authored here is executable and testable end-to-end on the CPU before it ever hits the GPU.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Every value the particle VM computes lives in a `vec4f` register, so a single data type describes
|
|
18
|
+
* every port in the library: any output may drive any input.
|
|
19
|
+
* @type {DataType}
|
|
20
|
+
*/
|
|
21
|
+
export const PARTICLE_VALUE_TYPE: DataType;
|
|
22
|
+
/**
|
|
23
|
+
* Name of the single output port carried by every value-producing node.
|
|
24
|
+
* @type {string}
|
|
25
|
+
*/
|
|
26
|
+
export const PARTICLE_NODE_OUTPUT_PORT: string;
|
|
27
|
+
/**
|
|
28
|
+
* @type {NodeRegistry}
|
|
29
|
+
*/
|
|
30
|
+
export const PARTICLE_NODE_REGISTRY: NodeRegistry;
|
|
31
|
+
import { ParticleNodeDescription } from "./ParticleNodeDescription.js";
|
|
32
|
+
import { DataType } from "../../../../core/model/node-graph/type/DataType.js";
|
|
33
|
+
import { NodeRegistry } from "../../../../core/model/node-graph/node/NodeRegistry.js";
|
|
60
34
|
//# sourceMappingURL=ParticleNodeRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParticleNodeRegistry.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/graph/ParticleNodeRegistry.js"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"ParticleNodeRegistry.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/graph/ParticleNodeRegistry.js"],"names":[],"mappings":"AA0KA;;;;;GAKG;AACH,oDAJW,MAAM,GACJ,uBAAuB,CAWnC;AAlLD;;;;;;;GAOG;AAEH;;;;GAIG;AACH,kCAFU,QAAQ,CAE0C;AAE5D;;;GAGG;AACH,wCAFU,MAAM,CAE+B;AAE/C;;GAEG;AACH,qCAFU,YAAY,CAEmC;wCA3BjB,8BAA8B;yBAF7C,oDAAoD;6BAFhD,wDAAwD"}
|
|
@@ -1,118 +1,185 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* -
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
};
|
|
1
|
+
import { NodeRegistry } from "../../../../core/model/node-graph/node/NodeRegistry.js";
|
|
2
|
+
import { PortDirection } from "../../../../core/model/node-graph/node/PortDirection.js";
|
|
3
|
+
import { DataType } from "../../../../core/model/node-graph/type/DataType.js";
|
|
4
|
+
import { pack_swizzle, VM_OP } from "../isa/ParticleVMISA.js";
|
|
5
|
+
import { ParticleNodeDescription } from "./ParticleNodeDescription.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Standard particle-node library, expressed as {@link ParticleNodeDescription}s in a
|
|
9
|
+
* {@link NodeRegistry}. Nodes are value-producing operations (constants, builtins, attribute reads,
|
|
10
|
+
* math, curves, random) or sinks (attribute writes, kill).
|
|
11
|
+
*
|
|
12
|
+
* These lower to the same opcodes the JS reference + WGSL interpreter agree on, so any effect
|
|
13
|
+
* authored here is executable and testable end-to-end on the CPU before it ever hits the GPU.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Every value the particle VM computes lives in a `vec4f` register, so a single data type describes
|
|
18
|
+
* every port in the library: any output may drive any input.
|
|
19
|
+
* @type {DataType}
|
|
20
|
+
*/
|
|
21
|
+
export const PARTICLE_VALUE_TYPE = DataType.from(0, "vec4");
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Name of the single output port carried by every value-producing node.
|
|
25
|
+
* @type {string}
|
|
26
|
+
*/
|
|
27
|
+
export const PARTICLE_NODE_OUTPUT_PORT = "out";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @type {NodeRegistry}
|
|
31
|
+
*/
|
|
32
|
+
export const PARTICLE_NODE_REGISTRY = new NodeRegistry();
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Node descriptions are addressed by name while authoring; the registry itself is keyed by the
|
|
36
|
+
* numeric IDs assigned below.
|
|
37
|
+
*
|
|
38
|
+
* IDs are handed out in declaration order rather than by {@link NodeDescription}'s global counter,
|
|
39
|
+
* so they do not drift with unrelated node usage elsewhere in the engine. Appending new node types
|
|
40
|
+
* at the end of the library is therefore safe; reordering or removing existing ones renumbers every
|
|
41
|
+
* node that follows, which would invalidate already-serialized graphs.
|
|
42
|
+
*
|
|
43
|
+
* @type {Map<string, ParticleNodeDescription>}
|
|
44
|
+
*/
|
|
45
|
+
const descriptions_by_name = new Map();
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {string} name
|
|
49
|
+
* @param {string[]} inputs input port names, in operand order
|
|
50
|
+
* @param {function} emit see {@link ParticleNodeDescription#emit}
|
|
51
|
+
* @param {object} [options]
|
|
52
|
+
* @param {boolean} [options.produces_value] when false the node is a sink and gets no output port
|
|
53
|
+
* @returns {ParticleNodeDescription}
|
|
54
|
+
*/
|
|
55
|
+
function define(name, inputs, emit, { produces_value = true } = {}) {
|
|
56
|
+
if (descriptions_by_name.has(name)) {
|
|
57
|
+
throw new Error(`Duplicate particle node type '${name}'`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const description = new ParticleNodeDescription();
|
|
61
|
+
|
|
62
|
+
description.name = name;
|
|
63
|
+
description.id = descriptions_by_name.size;
|
|
64
|
+
|
|
65
|
+
for (const input of inputs) {
|
|
66
|
+
description.createPort(PARTICLE_VALUE_TYPE, input, PortDirection.In);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (produces_value) {
|
|
70
|
+
description.createPort(PARTICLE_VALUE_TYPE, PARTICLE_NODE_OUTPUT_PORT, PortDirection.Out);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
description.emit = emit;
|
|
74
|
+
|
|
75
|
+
PARTICLE_NODE_REGISTRY.addNode(description);
|
|
76
|
+
descriptions_by_name.set(name, description);
|
|
77
|
+
|
|
78
|
+
return description;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** side-effecting sink (no output) */
|
|
82
|
+
function sink(name, inputs, emit) {
|
|
83
|
+
return define(name, inputs, emit, { produces_value: false });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function unary(name, opcode) {
|
|
87
|
+
return define(name, ["x"], (s, c) => s.emit(opcode, c.out, c.in("x")));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function binary(name, opcode) {
|
|
91
|
+
return define(name, ["a", "b"], (s, c) => s.emit(opcode, c.out, c.in("a"), c.in("b")));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const COMPARE_OPCODES = {
|
|
95
|
+
lt: VM_OP.CMP_LT,
|
|
96
|
+
le: VM_OP.CMP_LE,
|
|
97
|
+
gt: VM_OP.CMP_GT,
|
|
98
|
+
ge: VM_OP.CMP_GE,
|
|
99
|
+
eq: VM_OP.CMP_EQ,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// --- sources ---
|
|
103
|
+
define("const", [], (s, c) => {
|
|
104
|
+
const v = c.parameters.value ?? [0, 0, 0, 0];
|
|
105
|
+
s.loadConst(c.out, c.asm.constant(v[0] ?? 0, v[1] ?? 0, v[2] ?? 0, v[3] ?? 0));
|
|
106
|
+
});
|
|
107
|
+
define("builtin", [], (s, c) => s.loadBuiltin(c.out, c.parameters.id));
|
|
108
|
+
define("attribute", [], (s, c) => {
|
|
109
|
+
const a = c.layout.get(c.parameters.name);
|
|
110
|
+
s.loadAttr(c.out, a.offset, a.components);
|
|
111
|
+
});
|
|
112
|
+
define("random", [], (s, c) => s.random(c.out, c.parameters.mode));
|
|
113
|
+
|
|
114
|
+
// --- sinks ---
|
|
115
|
+
sink("setAttribute", ["value"], (s, c) => {
|
|
116
|
+
const a = c.layout.get(c.parameters.name);
|
|
117
|
+
s.storeAttr(c.in("value"), a.offset, a.components);
|
|
118
|
+
});
|
|
119
|
+
sink("kill", ["condition"], (s, c) => s.kill(c.in("condition")));
|
|
120
|
+
|
|
121
|
+
// --- arithmetic (component-wise) ---
|
|
122
|
+
binary("add", VM_OP.ADD);
|
|
123
|
+
binary("sub", VM_OP.SUB);
|
|
124
|
+
binary("mul", VM_OP.MUL);
|
|
125
|
+
binary("div", VM_OP.DIV);
|
|
126
|
+
binary("min", VM_OP.MIN);
|
|
127
|
+
binary("max", VM_OP.MAX);
|
|
128
|
+
binary("pow", VM_OP.POW);
|
|
129
|
+
binary("step", VM_OP.STEP);
|
|
130
|
+
define("mad", ["a", "b", "c"], (s, c) => s.emit(VM_OP.MAD, c.out, c.in("a"), c.in("b"), c.in("c")));
|
|
131
|
+
define("mix", ["a", "b", "t"], (s, c) => s.emit(VM_OP.MIX, c.out, c.in("a"), c.in("b"), c.in("t")));
|
|
132
|
+
define("clamp", ["x", "lo", "hi"], (s, c) => s.emit(VM_OP.CLAMP, c.out, c.in("x"), c.in("lo"), c.in("hi")));
|
|
133
|
+
define("smoothstep", ["e0", "e1", "x"], (s, c) => s.emit(VM_OP.SMOOTHSTEP, c.out, c.in("e0"), c.in("e1"), c.in("x")));
|
|
134
|
+
define("scale", ["v", "s"], (s, c) => s.emit(VM_OP.SCALE, c.out, c.in("v"), c.in("s")));
|
|
135
|
+
|
|
136
|
+
// --- unary math ---
|
|
137
|
+
unary("neg", VM_OP.NEG);
|
|
138
|
+
unary("abs", VM_OP.ABS);
|
|
139
|
+
unary("floor", VM_OP.FLOOR);
|
|
140
|
+
unary("fract", VM_OP.FRACT);
|
|
141
|
+
unary("sqrt", VM_OP.SQRT);
|
|
142
|
+
unary("sin", VM_OP.SIN);
|
|
143
|
+
unary("cos", VM_OP.COS);
|
|
144
|
+
unary("exp", VM_OP.EXP);
|
|
145
|
+
unary("log", VM_OP.LOG);
|
|
146
|
+
unary("normalize", VM_OP.NORMALIZE);
|
|
147
|
+
unary("length", VM_OP.LENGTH);
|
|
148
|
+
|
|
149
|
+
// --- vector ---
|
|
150
|
+
binary("dot", VM_OP.DOT);
|
|
151
|
+
binary("cross", VM_OP.CROSS);
|
|
152
|
+
binary("distance", VM_OP.DISTANCE);
|
|
153
|
+
define("swizzle", ["x"], (s, c) => {
|
|
154
|
+
const p = c.parameters.pattern ?? [0, 1, 2, 3];
|
|
155
|
+
s.emit(VM_OP.SWIZZLE, c.out, c.in("x"), pack_swizzle(p[0], p[1], p[2], p[3]));
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// --- logic ---
|
|
159
|
+
define("compare", ["a", "b"], (s, c) => {
|
|
160
|
+
const opcode = COMPARE_OPCODES[c.parameters.op];
|
|
161
|
+
if (opcode === undefined) {
|
|
162
|
+
throw new Error(`Unknown compare op '${c.parameters.op}'`);
|
|
163
|
+
}
|
|
164
|
+
s.emit(opcode, c.out, c.in("a"), c.in("b"));
|
|
165
|
+
});
|
|
166
|
+
define("select", ["a", "b", "condition"], (s, c) => s.emit(VM_OP.SELECT, c.out, c.in("a"), c.in("b"), c.in("condition")));
|
|
167
|
+
|
|
168
|
+
// --- curves ---
|
|
169
|
+
define("curve", ["t"], (s, c) => s.curve(c.out, c.parameters.handle, c.in("t")));
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Look up a node type by name.
|
|
173
|
+
* @param {string} name
|
|
174
|
+
* @returns {ParticleNodeDescription}
|
|
175
|
+
* @throws if no such node type exists
|
|
176
|
+
*/
|
|
177
|
+
export function get_particle_node_description(name) {
|
|
178
|
+
const description = descriptions_by_name.get(name);
|
|
179
|
+
|
|
180
|
+
if (description === undefined) {
|
|
181
|
+
throw new Error(`Unknown particle node type '${name}'`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return description;
|
|
185
|
+
}
|
|
@@ -1,33 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lower a single-phase {@link
|
|
2
|
+
* Lower a single-phase particle {@link ../../../../core/model/node-graph/NodeGraph.js NodeGraph}
|
|
3
|
+
* into a VM instruction stream.
|
|
4
|
+
*
|
|
5
|
+
* The graph describes one lifecycle phase (SPAWN or UPDATE) of a particle effect: nodes are
|
|
6
|
+
* {@link ParticleNodeDescription} instances, and every connection wires a producing node's `out`
|
|
7
|
+
* port to a consuming node's named input port.
|
|
3
8
|
*
|
|
4
9
|
* The pipeline:
|
|
5
10
|
* 1. Walk the graph from its sinks (attribute writes / kill), flattening it into an SSA-style value
|
|
6
|
-
* list in dependency order.
|
|
7
|
-
*
|
|
11
|
+
* list in dependency order. Shared sub-expressions are evaluated once (DAG sharing via
|
|
12
|
+
* memoisation).
|
|
8
13
|
* 2. Compute each value's last use.
|
|
9
14
|
* 3. Linear-scan register allocation: registers are returned to the pool at a value's last use, so a
|
|
10
15
|
* result can reuse a just-consumed input register (VM ops read all sources before writing dst).
|
|
11
|
-
* 4. Emit each value's opcode via its node
|
|
16
|
+
* 4. Emit each value's opcode via its node description.
|
|
12
17
|
*
|
|
13
|
-
* @param {
|
|
18
|
+
* @param {NodeGraph} graph
|
|
14
19
|
* @param {import("../isa/ParticleAssembler.js").InstructionStream} stream target section
|
|
15
20
|
* @param {ParticleAssembler} asm assembler owning the shared constant pool
|
|
16
21
|
* @param {import("../layout/ParticleLayout.js").ParticleLayout} layout attribute schema
|
|
17
22
|
*/
|
|
18
|
-
export function compile_particle_graph(graph:
|
|
23
|
+
export function compile_particle_graph(graph: NodeGraph, stream: any, asm: ParticleAssembler, layout: import("../layout/ParticleLayout.js").ParticleLayout): void;
|
|
19
24
|
/**
|
|
20
25
|
* Compile a full effect (SPAWN + UPDATE) into a {@link ../isa/ParticleProgram.js}.
|
|
21
26
|
*
|
|
22
27
|
* @param {object} params
|
|
23
|
-
* @param {
|
|
24
|
-
* @param {
|
|
28
|
+
* @param {NodeGraph} [params.spawn]
|
|
29
|
+
* @param {NodeGraph} [params.update]
|
|
25
30
|
* @param {import("../layout/ParticleLayout.js").ParticleLayout} params.layout
|
|
26
31
|
* @returns {import("../isa/ParticleProgram.js").ParticleProgram}
|
|
27
32
|
*/
|
|
28
33
|
export function compile_particle_effect({ spawn, update, layout }: {
|
|
29
|
-
spawn?:
|
|
30
|
-
update?:
|
|
34
|
+
spawn?: NodeGraph;
|
|
35
|
+
update?: NodeGraph;
|
|
31
36
|
layout: import("../layout/ParticleLayout.js").ParticleLayout;
|
|
32
37
|
}): import("../isa/ParticleProgram.js").ParticleProgram;
|
|
33
38
|
import { ParticleAssembler } from "../isa/ParticleAssembler.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile_particle_graph.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/graph/compile_particle_graph.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compile_particle_graph.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/graph/compile_particle_graph.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,2EAHW,iBAAiB,UACjB,OAAO,6BAA6B,EAAE,cAAc,QAqD9D;AAED;;;;;;;;GAQG;AACH;IAL8B,KAAK;IACL,MAAM;IACoC,MAAM,EAAnE,OAAO,6BAA6B,EAAE,cAAc;IAClD,OAAO,2BAA2B,EAAE,eAAe,CAa/D;kCAjGiC,6BAA6B"}
|