@skenora/runtime 0.1.2
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/README.md +92 -0
- package/dist/core/built-in-runtime-capabilities.d.ts +21 -0
- package/dist/core/built-in-runtime-capabilities.d.ts.map +1 -0
- package/dist/core/built-in-runtime-capabilities.js +175 -0
- package/dist/core/built-in-runtime-capabilities.js.map +1 -0
- package/dist/core/runtime-capability-registry.d.ts +90 -0
- package/dist/core/runtime-capability-registry.d.ts.map +1 -0
- package/dist/core/runtime-capability-registry.js +42 -0
- package/dist/core/runtime-capability-registry.js.map +1 -0
- package/dist/core/runtime-document-coordinator.d.ts +28 -0
- package/dist/core/runtime-document-coordinator.d.ts.map +1 -0
- package/dist/core/runtime-document-coordinator.js +124 -0
- package/dist/core/runtime-document-coordinator.js.map +1 -0
- package/dist/core/runtime-events.d.ts +43 -0
- package/dist/core/runtime-events.d.ts.map +1 -0
- package/dist/core/runtime-events.js +2 -0
- package/dist/core/runtime-events.js.map +1 -0
- package/dist/core/runtime-session.d.ts +93 -0
- package/dist/core/runtime-session.d.ts.map +1 -0
- package/dist/core/runtime-session.js +1344 -0
- package/dist/core/runtime-session.js.map +1 -0
- package/dist/editor-tools/camera-path-editing-controller.d.ts +36 -0
- package/dist/editor-tools/camera-path-editing-controller.d.ts.map +1 -0
- package/dist/editor-tools/camera-path-editing-controller.js +212 -0
- package/dist/editor-tools/camera-path-editing-controller.js.map +1 -0
- package/dist/editor-tools/camera-path-visualizer.d.ts +28 -0
- package/dist/editor-tools/camera-path-visualizer.d.ts.map +1 -0
- package/dist/editor-tools/camera-path-visualizer.js +151 -0
- package/dist/editor-tools/camera-path-visualizer.js.map +1 -0
- package/dist/editor-tools/drop-preview-controller.d.ts +34 -0
- package/dist/editor-tools/drop-preview-controller.d.ts.map +1 -0
- package/dist/editor-tools/drop-preview-controller.js +209 -0
- package/dist/editor-tools/drop-preview-controller.js.map +1 -0
- package/dist/editor-tools/grid-helper.d.ts +18 -0
- package/dist/editor-tools/grid-helper.d.ts.map +1 -0
- package/dist/editor-tools/grid-helper.js +27 -0
- package/dist/editor-tools/grid-helper.js.map +1 -0
- package/dist/editor-tools/light-editing-controller.d.ts +25 -0
- package/dist/editor-tools/light-editing-controller.d.ts.map +1 -0
- package/dist/editor-tools/light-editing-controller.js +207 -0
- package/dist/editor-tools/light-editing-controller.js.map +1 -0
- package/dist/editor-tools/node-operations.d.ts +51 -0
- package/dist/editor-tools/node-operations.d.ts.map +1 -0
- package/dist/editor-tools/node-operations.js +182 -0
- package/dist/editor-tools/node-operations.js.map +1 -0
- package/dist/editor-tools/selection-controller.d.ts +44 -0
- package/dist/editor-tools/selection-controller.d.ts.map +1 -0
- package/dist/editor-tools/selection-controller.js +299 -0
- package/dist/editor-tools/selection-controller.js.map +1 -0
- package/dist/editor-tools/shape-drawing-controller.d.ts +45 -0
- package/dist/editor-tools/shape-drawing-controller.d.ts.map +1 -0
- package/dist/editor-tools/shape-drawing-controller.js +205 -0
- package/dist/editor-tools/shape-drawing-controller.js.map +1 -0
- package/dist/editor-tools/shape-editing-controller.d.ts +40 -0
- package/dist/editor-tools/shape-editing-controller.d.ts.map +1 -0
- package/dist/editor-tools/shape-editing-controller.js +340 -0
- package/dist/editor-tools/shape-editing-controller.js.map +1 -0
- package/dist/editor.d.ts +12 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +12 -0
- package/dist/editor.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/inspection/node-tools.d.ts +51 -0
- package/dist/inspection/node-tools.d.ts.map +1 -0
- package/dist/inspection/node-tools.js +282 -0
- package/dist/inspection/node-tools.js.map +1 -0
- package/dist/interaction/runtime-third-person-controller.d.ts +24 -0
- package/dist/interaction/runtime-third-person-controller.d.ts.map +1 -0
- package/dist/interaction/runtime-third-person-controller.js +71 -0
- package/dist/interaction/runtime-third-person-controller.js.map +1 -0
- package/dist/interaction/third-person-controller.d.ts +61 -0
- package/dist/interaction/third-person-controller.d.ts.map +1 -0
- package/dist/interaction/third-person-controller.js +400 -0
- package/dist/interaction/third-person-controller.js.map +1 -0
- package/dist/interaction.d.ts +3 -0
- package/dist/interaction.d.ts.map +1 -0
- package/dist/interaction.js +3 -0
- package/dist/interaction.js.map +1 -0
- package/dist/presentation/scene-renderer.d.ts +75 -0
- package/dist/presentation/scene-renderer.d.ts.map +1 -0
- package/dist/presentation/scene-renderer.js +324 -0
- package/dist/presentation/scene-renderer.js.map +1 -0
- package/dist/presentation/viewport-controller.d.ts +13 -0
- package/dist/presentation/viewport-controller.d.ts.map +1 -0
- package/dist/presentation/viewport-controller.js +186 -0
- package/dist/presentation/viewport-controller.js.map +1 -0
- package/dist/projection/annotation-projector.d.ts +28 -0
- package/dist/projection/annotation-projector.d.ts.map +1 -0
- package/dist/projection/annotation-projector.js +98 -0
- package/dist/projection/annotation-projector.js.map +1 -0
- package/dist/projection/built-in-entity-projectors.d.ts +7 -0
- package/dist/projection/built-in-entity-projectors.d.ts.map +1 -0
- package/dist/projection/built-in-entity-projectors.js +75 -0
- package/dist/projection/built-in-entity-projectors.js.map +1 -0
- package/dist/projection/camera-entity-factory.d.ts +9 -0
- package/dist/projection/camera-entity-factory.d.ts.map +1 -0
- package/dist/projection/camera-entity-factory.js +93 -0
- package/dist/projection/camera-entity-factory.js.map +1 -0
- package/dist/projection/document-applier.d.ts +38 -0
- package/dist/projection/document-applier.d.ts.map +1 -0
- package/dist/projection/document-applier.js +219 -0
- package/dist/projection/document-applier.js.map +1 -0
- package/dist/projection/entity-projection-registry.d.ts +56 -0
- package/dist/projection/entity-projection-registry.d.ts.map +1 -0
- package/dist/projection/entity-projection-registry.js +121 -0
- package/dist/projection/entity-projection-registry.js.map +1 -0
- package/dist/projection/model-importer.d.ts +41 -0
- package/dist/projection/model-importer.d.ts.map +1 -0
- package/dist/projection/model-importer.js +469 -0
- package/dist/projection/model-importer.js.map +1 -0
- package/dist/projection/particle-capability.d.ts +5 -0
- package/dist/projection/particle-capability.d.ts.map +1 -0
- package/dist/projection/particle-capability.js +2 -0
- package/dist/projection/particle-capability.js.map +1 -0
- package/dist/projection/particle-factory.d.ts +18 -0
- package/dist/projection/particle-factory.d.ts.map +1 -0
- package/dist/projection/particle-factory.js +313 -0
- package/dist/projection/particle-factory.js.map +1 -0
- package/dist/projection/primitive-factory.d.ts +5 -0
- package/dist/projection/primitive-factory.d.ts.map +1 -0
- package/dist/projection/primitive-factory.js +55 -0
- package/dist/projection/primitive-factory.js.map +1 -0
- package/dist/projection/procedural-factory.d.ts +6 -0
- package/dist/projection/procedural-factory.d.ts.map +1 -0
- package/dist/projection/procedural-factory.js +34 -0
- package/dist/projection/procedural-factory.js.map +1 -0
- package/dist/projection/runtime-projection-state.d.ts +19 -0
- package/dist/projection/runtime-projection-state.d.ts.map +1 -0
- package/dist/projection/runtime-projection-state.js +58 -0
- package/dist/projection/runtime-projection-state.js.map +1 -0
- package/dist/projection/shape-factory.d.ts +5 -0
- package/dist/projection/shape-factory.d.ts.map +1 -0
- package/dist/projection/shape-factory.js +101 -0
- package/dist/projection/shape-factory.js.map +1 -0
- package/dist/projection-entry.d.ts +10 -0
- package/dist/projection-entry.d.ts.map +1 -0
- package/dist/projection-entry.js +8 -0
- package/dist/projection-entry.js.map +1 -0
- package/dist/simulation/fixed-step-scheduler.d.ts +13 -0
- package/dist/simulation/fixed-step-scheduler.d.ts.map +1 -0
- package/dist/simulation/fixed-step-scheduler.js +45 -0
- package/dist/simulation/fixed-step-scheduler.js.map +1 -0
- package/dist/simulation/simulation-runtime-model.d.ts +24 -0
- package/dist/simulation/simulation-runtime-model.d.ts.map +1 -0
- package/dist/simulation/simulation-runtime-model.js +63 -0
- package/dist/simulation/simulation-runtime-model.js.map +1 -0
- package/dist/simulation/simulation-wgsl.d.ts +3 -0
- package/dist/simulation/simulation-wgsl.d.ts.map +1 -0
- package/dist/simulation/simulation-wgsl.js +294 -0
- package/dist/simulation/simulation-wgsl.js.map +1 -0
- package/dist/simulation/webgpu-simulation-renderer.d.ts +67 -0
- package/dist/simulation/webgpu-simulation-renderer.d.ts.map +1 -0
- package/dist/simulation/webgpu-simulation-renderer.js +504 -0
- package/dist/simulation/webgpu-simulation-renderer.js.map +1 -0
- package/dist/simulation/webgpu-types.d.ts +90 -0
- package/dist/simulation/webgpu-types.d.ts.map +1 -0
- package/dist/simulation/webgpu-types.js +10 -0
- package/dist/simulation/webgpu-types.js.map +1 -0
- package/dist/simulation.d.ts +4 -0
- package/dist/simulation.d.ts.map +1 -0
- package/dist/simulation.js +4 -0
- package/dist/simulation.js.map +1 -0
- package/dist/systems/animation-controller.d.ts +52 -0
- package/dist/systems/animation-controller.d.ts.map +1 -0
- package/dist/systems/animation-controller.js +146 -0
- package/dist/systems/animation-controller.js.map +1 -0
- package/dist/systems/camera-controller.d.ts +41 -0
- package/dist/systems/camera-controller.d.ts.map +1 -0
- package/dist/systems/camera-controller.js +207 -0
- package/dist/systems/camera-controller.js.map +1 -0
- package/dist/systems/camera-path-controller.d.ts +39 -0
- package/dist/systems/camera-path-controller.d.ts.map +1 -0
- package/dist/systems/camera-path-controller.js +287 -0
- package/dist/systems/camera-path-controller.js.map +1 -0
- package/dist/systems/environment-controller.d.ts +18 -0
- package/dist/systems/environment-controller.d.ts.map +1 -0
- package/dist/systems/environment-controller.js +251 -0
- package/dist/systems/environment-controller.js.map +1 -0
- package/dist/systems/environment-texture.d.ts +7 -0
- package/dist/systems/environment-texture.d.ts.map +1 -0
- package/dist/systems/environment-texture.js +57 -0
- package/dist/systems/environment-texture.js.map +1 -0
- package/dist/systems/fog-controller.d.ts +12 -0
- package/dist/systems/fog-controller.d.ts.map +1 -0
- package/dist/systems/fog-controller.js +60 -0
- package/dist/systems/fog-controller.js.map +1 -0
- package/dist/systems/generated-texture-cache.d.ts +33 -0
- package/dist/systems/generated-texture-cache.d.ts.map +1 -0
- package/dist/systems/generated-texture-cache.js +101 -0
- package/dist/systems/generated-texture-cache.js.map +1 -0
- package/dist/systems/glass-transmission-controller.d.ts +21 -0
- package/dist/systems/glass-transmission-controller.d.ts.map +1 -0
- package/dist/systems/glass-transmission-controller.js +119 -0
- package/dist/systems/glass-transmission-controller.js.map +1 -0
- package/dist/systems/gpu-program-cache.d.ts +19 -0
- package/dist/systems/gpu-program-cache.d.ts.map +1 -0
- package/dist/systems/gpu-program-cache.js +95 -0
- package/dist/systems/gpu-program-cache.js.map +1 -0
- package/dist/systems/ground-controller.d.ts +14 -0
- package/dist/systems/ground-controller.d.ts.map +1 -0
- package/dist/systems/ground-controller.js +121 -0
- package/dist/systems/ground-controller.js.map +1 -0
- package/dist/systems/lighting-controller.d.ts +23 -0
- package/dist/systems/lighting-controller.d.ts.map +1 -0
- package/dist/systems/lighting-controller.js +204 -0
- package/dist/systems/lighting-controller.js.map +1 -0
- package/dist/systems/material-animation-controller.d.ts +26 -0
- package/dist/systems/material-animation-controller.d.ts.map +1 -0
- package/dist/systems/material-animation-controller.js +221 -0
- package/dist/systems/material-animation-controller.js.map +1 -0
- package/dist/systems/material-binding-resolver.d.ts +16 -0
- package/dist/systems/material-binding-resolver.d.ts.map +1 -0
- package/dist/systems/material-binding-resolver.js +54 -0
- package/dist/systems/material-binding-resolver.js.map +1 -0
- package/dist/systems/material-controller.d.ts +29 -0
- package/dist/systems/material-controller.d.ts.map +1 -0
- package/dist/systems/material-controller.js +233 -0
- package/dist/systems/material-controller.js.map +1 -0
- package/dist/systems/material-preparation.d.ts +9 -0
- package/dist/systems/material-preparation.d.ts.map +1 -0
- package/dist/systems/material-preparation.js +51 -0
- package/dist/systems/material-preparation.js.map +1 -0
- package/dist/systems/material-slots.d.ts +18 -0
- package/dist/systems/material-slots.d.ts.map +1 -0
- package/dist/systems/material-slots.js +78 -0
- package/dist/systems/material-slots.js.map +1 -0
- package/dist/systems/owned-material-controller.d.ts +20 -0
- package/dist/systems/owned-material-controller.d.ts.map +1 -0
- package/dist/systems/owned-material-controller.js +611 -0
- package/dist/systems/owned-material-controller.js.map +1 -0
- package/dist/systems/pbr-material.d.ts +22 -0
- package/dist/systems/pbr-material.d.ts.map +1 -0
- package/dist/systems/pbr-material.js +358 -0
- package/dist/systems/pbr-material.js.map +1 -0
- package/dist/systems/post-process-controller.d.ts +17 -0
- package/dist/systems/post-process-controller.d.ts.map +1 -0
- package/dist/systems/post-process-controller.js +246 -0
- package/dist/systems/post-process-controller.js.map +1 -0
- package/dist/systems/runtime-clock.d.ts +9 -0
- package/dist/systems/runtime-clock.d.ts.map +1 -0
- package/dist/systems/runtime-clock.js +25 -0
- package/dist/systems/runtime-clock.js.map +1 -0
- package/dist/systems/skybox-controller.d.ts +15 -0
- package/dist/systems/skybox-controller.d.ts.map +1 -0
- package/dist/systems/skybox-controller.js +282 -0
- package/dist/systems/skybox-controller.js.map +1 -0
- package/dist/systems/sprite-sheet-controller.d.ts +52 -0
- package/dist/systems/sprite-sheet-controller.d.ts.map +1 -0
- package/dist/systems/sprite-sheet-controller.js +187 -0
- package/dist/systems/sprite-sheet-controller.js.map +1 -0
- package/dist/systems/surface-effect-plugin.d.ts +26 -0
- package/dist/systems/surface-effect-plugin.d.ts.map +1 -0
- package/dist/systems/surface-effect-plugin.js +204 -0
- package/dist/systems/surface-effect-plugin.js.map +1 -0
- package/dist/systems/surface-program-plugin.d.ts +29 -0
- package/dist/systems/surface-program-plugin.d.ts.map +1 -0
- package/dist/systems/surface-program-plugin.js +139 -0
- package/dist/systems/surface-program-plugin.js.map +1 -0
- package/dist/systems/texture-animation-controller.d.ts +18 -0
- package/dist/systems/texture-animation-controller.d.ts.map +1 -0
- package/dist/systems/texture-animation-controller.js +147 -0
- package/dist/systems/texture-animation-controller.js.map +1 -0
- package/dist/systems/weather-controller.d.ts +16 -0
- package/dist/systems/weather-controller.d.ts.map +1 -0
- package/dist/systems/weather-controller.js +205 -0
- package/dist/systems/weather-controller.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** Projects serializable shapes into owned Babylon meshes. */
|
|
2
|
+
import { PBRMaterial } from "@babylonjs/core/Materials/PBR/pbrMaterial";
|
|
3
|
+
import { Color3 } from "@babylonjs/core/Maths/math.color";
|
|
4
|
+
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
|
|
5
|
+
import { Mesh } from "@babylonjs/core/Meshes/mesh";
|
|
6
|
+
import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder";
|
|
7
|
+
import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
|
|
8
|
+
import { closePolyline } from "@skenora/geometry";
|
|
9
|
+
import earcut from "earcut";
|
|
10
|
+
import { applyTransform } from "./model-importer.js";
|
|
11
|
+
export function createShapeEntity(scene, entity) {
|
|
12
|
+
const config = (entity.properties ?? {});
|
|
13
|
+
const points = validPoints(config.points);
|
|
14
|
+
const group = new TransformNode(entity.id, scene);
|
|
15
|
+
group.metadata = { skenora: { entityId: entity.id, generated: "shape" } };
|
|
16
|
+
applyTransform(group, entity.transform);
|
|
17
|
+
group.setEnabled(entity.enabled && entity.visible);
|
|
18
|
+
if (config.shape === "box") {
|
|
19
|
+
const box = MeshBuilder.CreateBox(`${entity.id}-box`, {
|
|
20
|
+
width: finite(config.width, 1),
|
|
21
|
+
height: finite(config.height, 1),
|
|
22
|
+
depth: finite(config.depth, 1),
|
|
23
|
+
}, scene);
|
|
24
|
+
box.material = createSurfaceMaterial(scene, entity.id, config);
|
|
25
|
+
box.parent = group;
|
|
26
|
+
}
|
|
27
|
+
else if (config.shape === "tube" && points.length >= 2) {
|
|
28
|
+
const tubePoints = config.closed ? closePolyline(points) : points;
|
|
29
|
+
const tube = MeshBuilder.CreateTube(`${entity.id}-tube`, {
|
|
30
|
+
path: tubePoints.map(toVector),
|
|
31
|
+
radius: finite(config.tubeRadius, 0.05),
|
|
32
|
+
tessellation: Math.max(3, Math.round(finite(config.segments, 8))),
|
|
33
|
+
cap: Mesh.CAP_ALL,
|
|
34
|
+
}, scene);
|
|
35
|
+
tube.material = createSurfaceMaterial(scene, entity.id, config);
|
|
36
|
+
tube.parent = group;
|
|
37
|
+
}
|
|
38
|
+
else if (config.shape === "wall" && points.length >= 2) {
|
|
39
|
+
const bottom = points.map(toVector);
|
|
40
|
+
const height = finite(config.wallHeight, 1);
|
|
41
|
+
const top = bottom.map((point) => point.add(new Vector3(0, height, 0)));
|
|
42
|
+
const wall = MeshBuilder.CreateRibbon(`${entity.id}-wall`, {
|
|
43
|
+
pathArray: [bottom, top],
|
|
44
|
+
closePath: config.closed ?? false,
|
|
45
|
+
sideOrientation: Mesh.DOUBLESIDE,
|
|
46
|
+
}, scene);
|
|
47
|
+
wall.material = createSurfaceMaterial(scene, entity.id, config);
|
|
48
|
+
wall.parent = group;
|
|
49
|
+
}
|
|
50
|
+
else if (config.shape !== "polyline" && points.length >= 3) {
|
|
51
|
+
const fill = MeshBuilder.CreatePolygon(`${entity.id}-fill`, { shape: points.map(toVector) }, scene, earcut);
|
|
52
|
+
fill.material = createSurfaceMaterial(scene, entity.id, config);
|
|
53
|
+
fill.parent = group;
|
|
54
|
+
}
|
|
55
|
+
const showStroke = config.shape !== "box" &&
|
|
56
|
+
config.shape !== "tube" &&
|
|
57
|
+
config.shape !== "wall";
|
|
58
|
+
const linePoints = config.closed === false ? points : closePolyline(points);
|
|
59
|
+
if (showStroke && linePoints.length >= 2) {
|
|
60
|
+
const line = MeshBuilder.CreateLines(`${entity.id}-stroke`, { points: linePoints.map(toVector), updatable: false }, scene);
|
|
61
|
+
line.color = toColor(config.strokeColor, { r: 0.3, g: 0.7, b: 1 });
|
|
62
|
+
line.parent = group;
|
|
63
|
+
}
|
|
64
|
+
return group;
|
|
65
|
+
}
|
|
66
|
+
function createSurfaceMaterial(scene, entityId, config) {
|
|
67
|
+
const material = new PBRMaterial(`${entityId}-surface-material`, scene);
|
|
68
|
+
material.albedoColor = toColor(config.fillColor, {
|
|
69
|
+
r: 0.2,
|
|
70
|
+
g: 0.55,
|
|
71
|
+
b: 1,
|
|
72
|
+
});
|
|
73
|
+
material.alpha = finite(config.fillAlpha, 0.35);
|
|
74
|
+
material.metallic = 0;
|
|
75
|
+
material.roughness = 0.8;
|
|
76
|
+
material.backFaceCulling = false;
|
|
77
|
+
return material;
|
|
78
|
+
}
|
|
79
|
+
function validPoints(value) {
|
|
80
|
+
if (!Array.isArray(value))
|
|
81
|
+
return [];
|
|
82
|
+
return value.flatMap((point) => {
|
|
83
|
+
if (!point || typeof point !== "object")
|
|
84
|
+
return [];
|
|
85
|
+
const item = point;
|
|
86
|
+
if (![item.x, item.y, item.z].every(Number.isFinite))
|
|
87
|
+
return [];
|
|
88
|
+
return [{ x: item.x, y: item.y, z: item.z }];
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function toVector(value) {
|
|
92
|
+
return new Vector3(value.x, value.y, value.z);
|
|
93
|
+
}
|
|
94
|
+
function toColor(value, fallback) {
|
|
95
|
+
const color = (value ?? fallback);
|
|
96
|
+
return new Color3(finite(color.r, fallback.r), finite(color.g, fallback.g), finite(color.b, fallback.b));
|
|
97
|
+
}
|
|
98
|
+
function finite(value, fallback) {
|
|
99
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=shape-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shape-factory.js","sourceRoot":"","sources":["../../src/projection/shape-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./core/runtime-session.js";
|
|
2
|
+
export * from "./core/runtime-capability-registry.js";
|
|
3
|
+
export { RuntimeDocumentCoordinator, type RuntimeDocumentProjectionContext, type RuntimeDocumentProjector, } from "./core/runtime-document-coordinator.js";
|
|
4
|
+
export * from "./projection/entity-projection-registry.js";
|
|
5
|
+
export { MaterialProjectionError } from "./systems/material-slots.js";
|
|
6
|
+
export type { AnnotationProjection } from "./projection/annotation-projector.js";
|
|
7
|
+
export { PARTICLE_PLAYBACK_CAPABILITY, type ParticlePlaybackCapability, } from "./projection/particle-capability.js";
|
|
8
|
+
export type { CameraPathPlaybackOptions, CameraPathPlaybackState, } from "./systems/camera-path-controller.js";
|
|
9
|
+
export { SkyboxController } from "./systems/skybox-controller.js";
|
|
10
|
+
//# sourceMappingURL=projection-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projection-entry.d.ts","sourceRoot":"","sources":["../src/projection-entry.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC;AACnD,OAAO,EACL,0BAA0B,EAC1B,KAAK,gCAAgC,EACrC,KAAK,wBAAwB,GAC9B,MAAM,qCAAqC,CAAC;AAC7C,cAAc,yCAAyC,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EACL,4BAA4B,EAC5B,KAAK,0BAA0B,GAChC,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EACV,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./core/runtime-session.js";
|
|
2
|
+
export * from "./core/runtime-capability-registry.js";
|
|
3
|
+
export { RuntimeDocumentCoordinator, } from "./core/runtime-document-coordinator.js";
|
|
4
|
+
export * from "./projection/entity-projection-registry.js";
|
|
5
|
+
export { MaterialProjectionError } from "./systems/material-slots.js";
|
|
6
|
+
export { PARTICLE_PLAYBACK_CAPABILITY, } from "./projection/particle-capability.js";
|
|
7
|
+
export { SkyboxController } from "./systems/skybox-controller.js";
|
|
8
|
+
//# sourceMappingURL=projection-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projection-entry.js","sourceRoot":"","sources":["../src/projection-entry.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC;AACnD,OAAO,EACL,0BAA0B,GAG3B,MAAM,qCAAqC,CAAC;AAC7C,cAAc,yCAAyC,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EACL,4BAA4B,GAE7B,MAAM,kCAAkC,CAAC;AAK1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface FixedStepAdvance {
|
|
2
|
+
readonly steps: number;
|
|
3
|
+
readonly interpolation: number;
|
|
4
|
+
readonly droppedMilliseconds: number;
|
|
5
|
+
}
|
|
6
|
+
/** Deterministic bounded scheduler shared by the physical backend and mock tests. */
|
|
7
|
+
export declare class FixedStepScheduler {
|
|
8
|
+
#private;
|
|
9
|
+
constructor(stepMilliseconds: number, maxSubsteps: number);
|
|
10
|
+
advance(timestamp: number): FixedStepAdvance;
|
|
11
|
+
reset(timestamp?: number): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=fixed-step-scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixed-step-scheduler.d.ts","sourceRoot":"","sources":["../../src/simulation/fixed-step-scheduler.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,qFAAqF;AACrF,qBAAa,kBAAkB;;gBAMjB,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IASzD,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;IA6B5C,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;CAIhC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** Deterministic bounded scheduler shared by the physical backend and mock tests. */
|
|
2
|
+
export class FixedStepScheduler {
|
|
3
|
+
#stepMilliseconds;
|
|
4
|
+
#maxSubsteps;
|
|
5
|
+
#lastTimestamp;
|
|
6
|
+
#accumulator = 0;
|
|
7
|
+
constructor(stepMilliseconds, maxSubsteps) {
|
|
8
|
+
if (!Number.isFinite(stepMilliseconds) || stepMilliseconds <= 0)
|
|
9
|
+
throw new Error("Fixed step must be positive");
|
|
10
|
+
if (!Number.isInteger(maxSubsteps) || maxSubsteps < 1)
|
|
11
|
+
throw new Error("maxSubsteps must be a positive integer");
|
|
12
|
+
this.#stepMilliseconds = stepMilliseconds;
|
|
13
|
+
this.#maxSubsteps = maxSubsteps;
|
|
14
|
+
}
|
|
15
|
+
advance(timestamp) {
|
|
16
|
+
if (!Number.isFinite(timestamp))
|
|
17
|
+
throw new Error("Timestamp must be finite");
|
|
18
|
+
if (this.#lastTimestamp === undefined) {
|
|
19
|
+
this.#lastTimestamp = timestamp;
|
|
20
|
+
return Object.freeze({
|
|
21
|
+
steps: 0,
|
|
22
|
+
interpolation: 0,
|
|
23
|
+
droppedMilliseconds: 0,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const elapsed = Math.max(0, timestamp - this.#lastTimestamp);
|
|
27
|
+
this.#lastTimestamp = timestamp;
|
|
28
|
+
const maximum = this.#stepMilliseconds * this.#maxSubsteps;
|
|
29
|
+
const accepted = Math.min(elapsed, maximum);
|
|
30
|
+
const droppedMilliseconds = elapsed - accepted;
|
|
31
|
+
this.#accumulator += accepted;
|
|
32
|
+
const steps = Math.min(Math.floor(this.#accumulator / this.#stepMilliseconds), this.#maxSubsteps);
|
|
33
|
+
this.#accumulator -= steps * this.#stepMilliseconds;
|
|
34
|
+
return Object.freeze({
|
|
35
|
+
steps,
|
|
36
|
+
interpolation: this.#accumulator / this.#stepMilliseconds,
|
|
37
|
+
droppedMilliseconds,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
reset(timestamp) {
|
|
41
|
+
this.#lastTimestamp = timestamp;
|
|
42
|
+
this.#accumulator = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=fixed-step-scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixed-step-scheduler.js","sourceRoot":"","sources":["../../src/simulation/fixed-step-scheduler.ts"],"names":[],"mappings":"AAMA,qFAAqF;AACrF,MAAM,OAAO,kBAAkB;IACpB,iBAAiB,CAAS;IAC1B,YAAY,CAAS;IAC9B,cAAc,CAAqB;IACnC,YAAY,GAAG,CAAC,CAAC;IAEjB,YAAY,gBAAwB,EAAE,WAAmB;QACvD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,IAAI,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,IAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QAC1C,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED,OAAO,CAAC,SAAiB;QACvB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;YAChC,OAAO,MAAM,CAAC,MAAM,CAAC;gBACnB,KAAK,EAAE,CAAC;gBACR,aAAa,EAAE,CAAC;gBAChB,mBAAmB,EAAE,CAAC;aACvB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7D,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,mBAAmB,GAAG,OAAO,GAAG,QAAQ,CAAC;QAC/C,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,EACtD,IAAI,CAAC,YAAY,CAClB,CAAC;QACF,IAAI,CAAC,YAAY,IAAI,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACpD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,KAAK;YACL,aAAa,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,iBAAiB;YACzD,mBAAmB;SACpB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,SAAkB;QACtB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CompiledSimulationProgram } from "@skenora/procedural";
|
|
2
|
+
export type SimulationRuntimeStatus = "initializing" | "running" | "paused" | "lost" | "disposed";
|
|
3
|
+
/** Device-free ownership model used by WebGPU execution and deterministic tests. */
|
|
4
|
+
export declare class SimulationRuntimeModel {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(program: CompiledSimulationProgram);
|
|
7
|
+
get status(): SimulationRuntimeStatus;
|
|
8
|
+
get currentIndex(): 0 | 1;
|
|
9
|
+
start(): void;
|
|
10
|
+
pause(): void;
|
|
11
|
+
completePass(): void;
|
|
12
|
+
completeFixedStep(): void;
|
|
13
|
+
reset(): void;
|
|
14
|
+
markDeviceLost(): void;
|
|
15
|
+
dispose(): void;
|
|
16
|
+
snapshot(): Readonly<{
|
|
17
|
+
status: SimulationRuntimeStatus;
|
|
18
|
+
resourceIds: readonly [string, string];
|
|
19
|
+
currentResourceId: string;
|
|
20
|
+
swaps: number;
|
|
21
|
+
fixedSteps: number;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=simulation-runtime-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulation-runtime-model.d.ts","sourceRoot":"","sources":["../../src/simulation/simulation-runtime-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAErE,MAAM,MAAM,uBAAuB,GACjC,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAE9D,oFAAoF;AACpF,qBAAa,sBAAsB;;gBAOrB,OAAO,EAAE,yBAAyB;IAI9C,IAAI,MAAM,IAAI,uBAAuB,CAEpC;IAED,IAAI,YAAY,IAAI,CAAC,GAAG,CAAC,CAExB;IAED,KAAK,IAAI,IAAI;IAKb,KAAK,IAAI,IAAI;IAKb,YAAY,IAAI,IAAI;IAMpB,iBAAiB,IAAI,IAAI;IAKzB,KAAK,IAAI,IAAI;IAOb,cAAc,IAAI,IAAI;IAItB,OAAO,IAAI,IAAI;IAIf,QAAQ,IAAI,QAAQ,CAAC;QACnB,MAAM,EAAE,uBAAuB,CAAC;QAChC,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CAcH"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Device-free ownership model used by WebGPU execution and deterministic tests. */
|
|
2
|
+
export class SimulationRuntimeModel {
|
|
3
|
+
#program;
|
|
4
|
+
#status = "initializing";
|
|
5
|
+
#currentIndex = 0;
|
|
6
|
+
#swaps = 0;
|
|
7
|
+
#fixedSteps = 0;
|
|
8
|
+
constructor(program) {
|
|
9
|
+
this.#program = program;
|
|
10
|
+
}
|
|
11
|
+
get status() {
|
|
12
|
+
return this.#status;
|
|
13
|
+
}
|
|
14
|
+
get currentIndex() {
|
|
15
|
+
return this.#currentIndex;
|
|
16
|
+
}
|
|
17
|
+
start() {
|
|
18
|
+
this.#assertAvailable();
|
|
19
|
+
this.#status = "running";
|
|
20
|
+
}
|
|
21
|
+
pause() {
|
|
22
|
+
this.#assertAvailable();
|
|
23
|
+
this.#status = "paused";
|
|
24
|
+
}
|
|
25
|
+
completePass() {
|
|
26
|
+
this.#assertAvailable();
|
|
27
|
+
this.#currentIndex = this.#currentIndex === 0 ? 1 : 0;
|
|
28
|
+
this.#swaps += 1;
|
|
29
|
+
}
|
|
30
|
+
completeFixedStep() {
|
|
31
|
+
this.#assertAvailable();
|
|
32
|
+
this.#fixedSteps += 1;
|
|
33
|
+
}
|
|
34
|
+
reset() {
|
|
35
|
+
this.#assertAvailable();
|
|
36
|
+
this.#currentIndex = 0;
|
|
37
|
+
this.#swaps = 0;
|
|
38
|
+
this.#fixedSteps = 0;
|
|
39
|
+
}
|
|
40
|
+
markDeviceLost() {
|
|
41
|
+
if (this.#status !== "disposed")
|
|
42
|
+
this.#status = "lost";
|
|
43
|
+
}
|
|
44
|
+
dispose() {
|
|
45
|
+
this.#status = "disposed";
|
|
46
|
+
}
|
|
47
|
+
snapshot() {
|
|
48
|
+
return Object.freeze({
|
|
49
|
+
status: this.#status,
|
|
50
|
+
resourceIds: this.#program.resourceIds,
|
|
51
|
+
currentResourceId: this.#program.resourceIds[this.#currentIndex],
|
|
52
|
+
swaps: this.#swaps,
|
|
53
|
+
fixedSteps: this.#fixedSteps,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
#assertAvailable() {
|
|
57
|
+
if (this.#status === "lost")
|
|
58
|
+
throw new Error("Simulation device is lost");
|
|
59
|
+
if (this.#status === "disposed")
|
|
60
|
+
throw new Error("Simulation is disposed");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=simulation-runtime-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulation-runtime-model.js","sourceRoot":"","sources":["../../src/simulation/simulation-runtime-model.ts"],"names":[],"mappings":"AAKA,oFAAoF;AACpF,MAAM,OAAO,sBAAsB;IACxB,QAAQ,CAA4B;IAC7C,OAAO,GAA4B,cAAc,CAAC;IAClD,aAAa,GAAU,CAAC,CAAC;IACzB,MAAM,GAAG,CAAC,CAAC;IACX,WAAW,GAAG,CAAC,CAAC;IAEhB,YAAY,OAAkC;QAC5C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC1B,CAAC;IAED,YAAY;QACV,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,cAAc;QACZ,IAAI,IAAI,CAAC,OAAO,KAAK,UAAU;YAAE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACzD,CAAC;IAED,OAAO;QACL,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;IAC5B,CAAC;IAED,QAAQ;QAON,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW;YACtC,iBAAiB,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC;YAChE,KAAK,EAAE,IAAI,CAAC,MAAM;YAClB,UAAU,EAAE,IAAI,CAAC,WAAW;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB;QACd,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC1E,IAAI,IAAI,CAAC,OAAO,KAAK,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC7E,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulation-wgsl.d.ts","sourceRoot":"","sources":["../../src/simulation/simulation-wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,gBAAgB,EACxB,aAAa,EAAE,CAAC,GAAG,EAAE,GACpB,MAAM,CAER"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
export function createSimulationWgsl(kernel, workgroupSize) {
|
|
2
|
+
return `${header(workgroupSize)}\n${kernel === "fluid-2d" ? fluid() : kernel === "fft-ocean" ? ocean() : radiance()}\n${renderer(kernel)}`;
|
|
3
|
+
}
|
|
4
|
+
function header(workgroupSize) {
|
|
5
|
+
return `
|
|
6
|
+
struct Params {
|
|
7
|
+
width: u32,
|
|
8
|
+
height: u32,
|
|
9
|
+
passKind: u32,
|
|
10
|
+
iteration: u32,
|
|
11
|
+
dt: f32,
|
|
12
|
+
time: f32,
|
|
13
|
+
pointerX: f32,
|
|
14
|
+
pointerY: f32,
|
|
15
|
+
strength: f32,
|
|
16
|
+
param0: f32,
|
|
17
|
+
param1: f32,
|
|
18
|
+
param2: f32,
|
|
19
|
+
span: u32,
|
|
20
|
+
kernel: u32,
|
|
21
|
+
pad0: u32,
|
|
22
|
+
pad1: u32,
|
|
23
|
+
};
|
|
24
|
+
@group(0) @binding(0) var<uniform> p: Params;
|
|
25
|
+
@group(0) @binding(1) var<storage, read> source: array<vec4<f32>>;
|
|
26
|
+
@group(0) @binding(2) var<storage, read_write> outputState: array<vec4<f32>>;
|
|
27
|
+
|
|
28
|
+
fn indexOf(x: u32, y: u32) -> u32 { return y * p.width + x; }
|
|
29
|
+
fn clampX(x: i32) -> u32 { return u32(clamp(x, 0, i32(p.width) - 1)); }
|
|
30
|
+
fn clampY(y: i32) -> u32 { return u32(clamp(y, 0, i32(p.height) - 1)); }
|
|
31
|
+
fn readAt(x: i32, y: i32) -> vec4<f32> {
|
|
32
|
+
return source[indexOf(clampX(x), clampY(y))];
|
|
33
|
+
}
|
|
34
|
+
fn hash21(value: vec2<f32>) -> f32 {
|
|
35
|
+
let mixed = fract(value * vec2<f32>(123.34, 456.21));
|
|
36
|
+
return fract((mixed.x + mixed.y) * (mixed.x + mixed.y + 45.32));
|
|
37
|
+
}
|
|
38
|
+
@compute @workgroup_size(${workgroupSize}, ${workgroupSize}, 1)
|
|
39
|
+
fn computeMain(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
40
|
+
if (gid.x >= p.width || gid.y >= p.height) { return; }
|
|
41
|
+
computeCell(gid.xy);
|
|
42
|
+
}`;
|
|
43
|
+
}
|
|
44
|
+
function fluid() {
|
|
45
|
+
return `
|
|
46
|
+
fn sampleNearest(uv: vec2<f32>) -> vec4<f32> {
|
|
47
|
+
let xy = vec2<i32>(clamp(uv, vec2<f32>(0.0), vec2<f32>(0.99999)) * vec2<f32>(f32(p.width), f32(p.height)));
|
|
48
|
+
return readAt(xy.x, xy.y);
|
|
49
|
+
}
|
|
50
|
+
fn computeCell(cell: vec2<u32>) {
|
|
51
|
+
let at = indexOf(cell.x, cell.y);
|
|
52
|
+
let xy = vec2<i32>(cell);
|
|
53
|
+
let uv = (vec2<f32>(cell) + 0.5) / vec2<f32>(f32(p.width), f32(p.height));
|
|
54
|
+
let current = source[at];
|
|
55
|
+
if (p.passKind == 0u) {
|
|
56
|
+
let delta = uv - vec2<f32>(p.pointerX, p.pointerY);
|
|
57
|
+
let pulse = exp(-dot(delta, delta) * 180.0);
|
|
58
|
+
let tangent = normalize(vec2<f32>(-delta.y, delta.x) + vec2<f32>(0.0001));
|
|
59
|
+
outputState[at] = vec4<f32>(
|
|
60
|
+
current.xy + tangent * pulse * p.strength * p.dt * 0.18,
|
|
61
|
+
min(4.0, current.z + pulse * p.strength * p.dt),
|
|
62
|
+
current.w
|
|
63
|
+
);
|
|
64
|
+
} else if (p.passKind == 1u) {
|
|
65
|
+
let previousUv = uv - current.xy * p.dt * 0.12;
|
|
66
|
+
let advected = sampleNearest(previousUv);
|
|
67
|
+
let laplacian = readAt(xy.x - 1, xy.y).xy + readAt(xy.x + 1, xy.y).xy +
|
|
68
|
+
readAt(xy.x, xy.y - 1).xy + readAt(xy.x, xy.y + 1).xy - 4.0 * advected.xy;
|
|
69
|
+
outputState[at] = vec4<f32>(
|
|
70
|
+
advected.xy + laplacian * p.param0 * p.dt,
|
|
71
|
+
advected.z * pow(p.param1, p.dt * 60.0),
|
|
72
|
+
advected.w
|
|
73
|
+
);
|
|
74
|
+
} else {
|
|
75
|
+
let left = readAt(xy.x - 1, xy.y);
|
|
76
|
+
let right = readAt(xy.x + 1, xy.y);
|
|
77
|
+
let down = readAt(xy.x, xy.y - 1);
|
|
78
|
+
let up = readAt(xy.x, xy.y + 1);
|
|
79
|
+
let divergence = 0.5 * ((right.x - left.x) + (up.y - down.y));
|
|
80
|
+
let pressure = (left.w + right.w + down.w + up.w - divergence) * 0.25;
|
|
81
|
+
let velocity = current.xy - 0.5 * vec2<f32>(right.w - left.w, up.w - down.w);
|
|
82
|
+
outputState[at] = vec4<f32>(velocity, current.z, pressure);
|
|
83
|
+
}
|
|
84
|
+
}`;
|
|
85
|
+
}
|
|
86
|
+
function ocean() {
|
|
87
|
+
return `
|
|
88
|
+
fn reverseBits(value: u32, size: u32) -> u32 {
|
|
89
|
+
var input = value;
|
|
90
|
+
var output = 0u;
|
|
91
|
+
var count = size;
|
|
92
|
+
loop {
|
|
93
|
+
if (count <= 1u) { break; }
|
|
94
|
+
output = (output << 1u) | (input & 1u);
|
|
95
|
+
input = input >> 1u;
|
|
96
|
+
count = count >> 1u;
|
|
97
|
+
}
|
|
98
|
+
return output;
|
|
99
|
+
}
|
|
100
|
+
fn complexMul(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> {
|
|
101
|
+
return vec2<f32>(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
|
|
102
|
+
}
|
|
103
|
+
fn butterfly(a: vec2<f32>, b: vec2<f32>, index: u32, span: u32, upper: bool) -> vec2<f32> {
|
|
104
|
+
let angle = 6.28318530718 * f32(index) / f32(span);
|
|
105
|
+
let rotated = complexMul(b, vec2<f32>(cos(angle), sin(angle)));
|
|
106
|
+
return select(a - rotated, a + rotated, upper);
|
|
107
|
+
}
|
|
108
|
+
fn computeCell(cell: vec2<u32>) {
|
|
109
|
+
let at = indexOf(cell.x, cell.y);
|
|
110
|
+
if (p.passKind == 10u) {
|
|
111
|
+
let centered = vec2<f32>(cell) - vec2<f32>(f32(p.width), f32(p.height)) * 0.5;
|
|
112
|
+
let centeredLength = length(centered);
|
|
113
|
+
let wave = max(centeredLength, 1.0);
|
|
114
|
+
let direction = dot(centered / wave, normalize(vec2<f32>(0.85, 0.35)));
|
|
115
|
+
let phillips = 400.0 * p.param1 * exp(-1.0 / max(0.001, wave * wave * p.param0 * 0.015)) *
|
|
116
|
+
direction * direction / max(1.0, wave * wave);
|
|
117
|
+
let randomPhase = hash21(vec2<f32>(cell)) * 6.28318530718;
|
|
118
|
+
let omega = sqrt(9.81 * wave * 0.08);
|
|
119
|
+
let phase = randomPhase + omega * p.time;
|
|
120
|
+
outputState[at] = vec4<f32>(cos(phase), sin(phase), 0.0, 0.0) * phillips;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (p.passKind == 11u) {
|
|
124
|
+
outputState[at] = source[indexOf(reverseBits(cell.x, p.width), cell.y)];
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (p.passKind == 13u) {
|
|
128
|
+
outputState[at] = source[indexOf(cell.x, reverseBits(cell.y, p.height))];
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
let span = p.span;
|
|
132
|
+
let half = span / 2u;
|
|
133
|
+
let coordinate = select(cell.y, cell.x, p.passKind == 12u);
|
|
134
|
+
let block = (coordinate / span) * span;
|
|
135
|
+
let local = coordinate % span;
|
|
136
|
+
let pair = local % half;
|
|
137
|
+
var firstIndex: u32;
|
|
138
|
+
var secondIndex: u32;
|
|
139
|
+
if (p.passKind == 12u) {
|
|
140
|
+
firstIndex = indexOf(block + pair, cell.y);
|
|
141
|
+
secondIndex = indexOf(block + pair + half, cell.y);
|
|
142
|
+
} else {
|
|
143
|
+
firstIndex = indexOf(cell.x, block + pair);
|
|
144
|
+
secondIndex = indexOf(cell.x, block + pair + half);
|
|
145
|
+
}
|
|
146
|
+
var value = butterfly(source[firstIndex].xy, source[secondIndex].xy, pair, span, local < half);
|
|
147
|
+
if (p.passKind == 14u && span == p.height) {
|
|
148
|
+
value = value / f32(p.width * p.height);
|
|
149
|
+
}
|
|
150
|
+
outputState[at] = vec4<f32>(value, length(value) * p.param2, 1.0);
|
|
151
|
+
}`;
|
|
152
|
+
}
|
|
153
|
+
function radiance() {
|
|
154
|
+
return `
|
|
155
|
+
fn featureSeed(uv: vec2<f32>) -> vec4<f32> {
|
|
156
|
+
var best = vec4<f32>(-1.0, -1.0, 0.0, 0.0);
|
|
157
|
+
for (var index = 0u; index < 8u; index = index + 1u) {
|
|
158
|
+
if (f32(index) >= p.param0) { break; }
|
|
159
|
+
let fi = f32(index);
|
|
160
|
+
let center = vec2<f32>(0.5 + 0.31 * sin(p.time * (0.37 + fi * 0.04) + fi * 2.1),
|
|
161
|
+
0.5 + 0.31 * cos(p.time * (0.29 + fi * 0.03) + fi * 1.7));
|
|
162
|
+
if (distance(uv, center) < 0.018) { best = vec4<f32>(uv, 2.0, 1.0 + fi); }
|
|
163
|
+
}
|
|
164
|
+
let wallA = abs(uv.x - 0.34 - 0.07 * sin(uv.y * 12.0 + p.time * 0.3));
|
|
165
|
+
let wallB = abs(uv.x - 0.68 + 0.06 * cos(uv.y * 10.0 - p.time * 0.25));
|
|
166
|
+
let ring = abs(distance(uv, vec2<f32>(0.5)) - 0.24);
|
|
167
|
+
if (min(min(wallA, wallB), ring) < 0.008) { best = vec4<f32>(uv, 1.0, 0.0); }
|
|
168
|
+
return best;
|
|
169
|
+
}
|
|
170
|
+
fn computeCell(cell: vec2<u32>) {
|
|
171
|
+
let at = indexOf(cell.x, cell.y);
|
|
172
|
+
let uv = (vec2<f32>(cell) + 0.5) / vec2<f32>(f32(p.width), f32(p.height));
|
|
173
|
+
if (p.passKind == 20u) { outputState[at] = featureSeed(uv); return; }
|
|
174
|
+
if (p.passKind == 21u) {
|
|
175
|
+
var best = source[at];
|
|
176
|
+
var bestDistance = select(1e9, distance(uv, best.xy), best.x >= 0.0);
|
|
177
|
+
let jump = i32(p.span);
|
|
178
|
+
for (var oy = -1; oy <= 1; oy = oy + 1) {
|
|
179
|
+
for (var ox = -1; ox <= 1; ox = ox + 1) {
|
|
180
|
+
let candidate = readAt(i32(cell.x) + ox * jump, i32(cell.y) + oy * jump);
|
|
181
|
+
if (candidate.x >= 0.0) {
|
|
182
|
+
let candidateDistance = distance(uv, candidate.xy);
|
|
183
|
+
if (candidateDistance < bestDistance) {
|
|
184
|
+
best = candidate;
|
|
185
|
+
bestDistance = candidateDistance;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
outputState[at] = best;
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (p.passKind == 22u && p.iteration == 0u) {
|
|
194
|
+
let distanceToFeature = distance(uv, source[at].xy);
|
|
195
|
+
let hue = fract(source[at].w * 0.37 + p.time * 0.03);
|
|
196
|
+
let emitterColor = 0.55 + 0.45 * cos(6.28318530718 * (hue + vec3<f32>(0.0, 0.33, 0.67)));
|
|
197
|
+
let light = emitterColor * exp(-distanceToFeature * 8.0) * select(0.04, 2.2, source[at].z > 1.5);
|
|
198
|
+
outputState[at] = vec4<f32>(light, select(1.0, 0.0, source[at].z == 1.0));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (p.passKind == 22u) {
|
|
202
|
+
let jump = i32(p.span);
|
|
203
|
+
var light = source[at].rgb * 2.0;
|
|
204
|
+
light = light + readAt(i32(cell.x) - jump, i32(cell.y)).rgb;
|
|
205
|
+
light = light + readAt(i32(cell.x) + jump, i32(cell.y)).rgb;
|
|
206
|
+
light = light + readAt(i32(cell.x), i32(cell.y) - jump).rgb;
|
|
207
|
+
light = light + readAt(i32(cell.x), i32(cell.y) + jump).rgb;
|
|
208
|
+
light = light / 6.0;
|
|
209
|
+
outputState[at] = vec4<f32>(light * (0.94 + 0.02 * f32(p.iteration)), source[at].w);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
let mapped = source[at].rgb / (vec3<f32>(1.0) + source[at].rgb);
|
|
213
|
+
outputState[at] = vec4<f32>(pow(mapped, vec3<f32>(0.72)), source[at].w);
|
|
214
|
+
}`;
|
|
215
|
+
}
|
|
216
|
+
function renderer(kernel) {
|
|
217
|
+
const sampling = kernel === "fft-ocean"
|
|
218
|
+
? `
|
|
219
|
+
let screenUv = clamp(vec2<f32>(input.uv.x, 1.0 - input.uv.y), vec2<f32>(0.0), vec2<f32>(0.99999));
|
|
220
|
+
if (screenUv.y < 0.32) {
|
|
221
|
+
let horizon = screenUv.y / 0.32;
|
|
222
|
+
let sky = mix(vec3<f32>(0.015, 0.035, 0.12), vec3<f32>(0.18, 0.55, 0.72), horizon);
|
|
223
|
+
return vec4<f32>(sky, 1.0);
|
|
224
|
+
}
|
|
225
|
+
let depth = max(0.045, screenUv.y - 0.28);
|
|
226
|
+
let uv = vec2<f32>(
|
|
227
|
+
fract((screenUv.x - 0.5) / (depth * 2.1) + 0.5),
|
|
228
|
+
fract(0.14 / depth + p.time * 0.035)
|
|
229
|
+
);
|
|
230
|
+
let cell = vec2<u32>(uv * vec2<f32>(f32(p.width), f32(p.height)));
|
|
231
|
+
let value = source[indexOf(cell.x, cell.y)];`
|
|
232
|
+
: `
|
|
233
|
+
let uv = clamp(vec2<f32>(input.uv.x, 1.0 - input.uv.y), vec2<f32>(0.0), vec2<f32>(0.99999));
|
|
234
|
+
let cell = vec2<u32>(uv * vec2<f32>(f32(p.width), f32(p.height)));
|
|
235
|
+
let value = source[indexOf(cell.x, cell.y)];`;
|
|
236
|
+
const color = kernel === "fluid-2d"
|
|
237
|
+
? `
|
|
238
|
+
let density = max(0.0, value.z);
|
|
239
|
+
let speed = length(value.xy);
|
|
240
|
+
let cold = vec3<f32>(0.01, 0.08, 0.22);
|
|
241
|
+
let cyan = vec3<f32>(0.0, 0.85, 1.2);
|
|
242
|
+
let magenta = vec3<f32>(1.1, 0.04, 0.65);
|
|
243
|
+
let color = cold + density * mix(cyan, magenta, clamp(speed * 4.0, 0.0, 1.0));
|
|
244
|
+
return vec4<f32>(color / (vec3<f32>(1.0) + color), 1.0);`
|
|
245
|
+
: kernel === "fft-ocean"
|
|
246
|
+
? `
|
|
247
|
+
let left = source[indexOf(u32(max(i32(cell.x) - 1, 0)), cell.y)].x;
|
|
248
|
+
let up = source[indexOf(cell.x, u32(max(i32(cell.y) - 1, 0)))].x;
|
|
249
|
+
let normal = normalize(vec3<f32>((left - value.x) * 45.0, (up - value.x) * 45.0, 1.0));
|
|
250
|
+
let fresnel = pow(1.0 - max(normal.z, 0.0), 3.0);
|
|
251
|
+
let foam = smoothstep(0.015, 0.08, value.z);
|
|
252
|
+
var color = mix(vec3<f32>(0.0, 0.08, 0.19), vec3<f32>(0.0, 0.55, 0.78), normal.z);
|
|
253
|
+
color = mix(color, vec3<f32>(0.75, 0.95, 1.0), foam * 0.7 + fresnel * 0.35);
|
|
254
|
+
return vec4<f32>(color, 1.0);`
|
|
255
|
+
: `
|
|
256
|
+
var color = value.rgb;
|
|
257
|
+
for (var index = 0u; index < 8u; index = index + 1u) {
|
|
258
|
+
if (f32(index) >= p.param0) { break; }
|
|
259
|
+
let fi = f32(index);
|
|
260
|
+
let center = vec2<f32>(0.5 + 0.31 * sin(p.time * (0.37 + fi * 0.04) + fi * 2.1),
|
|
261
|
+
0.5 + 0.31 * cos(p.time * (0.29 + fi * 0.03) + fi * 1.7));
|
|
262
|
+
let glow = exp(-distance(uv, center) * 42.0);
|
|
263
|
+
let emitterColor = 0.55 + 0.45 * cos(6.28318530718 * (fi * 0.37 + vec3<f32>(0.0, 0.33, 0.67)));
|
|
264
|
+
color = color + emitterColor * glow * 2.4;
|
|
265
|
+
}
|
|
266
|
+
let wallA = abs(uv.x - 0.34 - 0.07 * sin(uv.y * 12.0 + p.time * 0.3));
|
|
267
|
+
let wallB = abs(uv.x - 0.68 + 0.06 * cos(uv.y * 10.0 - p.time * 0.25));
|
|
268
|
+
let ring = abs(distance(uv, vec2<f32>(0.5)) - 0.24);
|
|
269
|
+
let occlusion = smoothstep(0.002, 0.012, min(min(wallA, wallB), ring));
|
|
270
|
+
color = color * mix(0.08, 1.0, occlusion);
|
|
271
|
+
color = color / (vec3<f32>(1.0) + color);
|
|
272
|
+
return vec4<f32>(pow(color, vec3<f32>(0.78)), 1.0);`;
|
|
273
|
+
return `
|
|
274
|
+
struct VertexOutput {
|
|
275
|
+
@builtin(position) position: vec4<f32>,
|
|
276
|
+
@location(0) uv: vec2<f32>,
|
|
277
|
+
};
|
|
278
|
+
@vertex
|
|
279
|
+
fn vertexMain(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
280
|
+
var positions = array<vec2<f32>, 3>(
|
|
281
|
+
vec2<f32>(-1.0, -1.0), vec2<f32>(3.0, -1.0), vec2<f32>(-1.0, 3.0)
|
|
282
|
+
);
|
|
283
|
+
var output: VertexOutput;
|
|
284
|
+
output.position = vec4<f32>(positions[vertexIndex], 0.0, 1.0);
|
|
285
|
+
output.uv = positions[vertexIndex] * 0.5 + 0.5;
|
|
286
|
+
return output;
|
|
287
|
+
}
|
|
288
|
+
@fragment
|
|
289
|
+
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
290
|
+
${sampling}
|
|
291
|
+
${color}
|
|
292
|
+
}`;
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=simulation-wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulation-wgsl.js","sourceRoot":"","sources":["../../src/simulation/simulation-wgsl.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAClC,MAAwB,EACxB,aAAqB;IAErB,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;AAC7I,CAAC;AAED,SAAS,MAAM,CAAC,aAAqB;IACnC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAiCkB,aAAa,KAAK,aAAa;;;;EAIxD,CAAC;AACH,CAAC;AAED,SAAS,KAAK;IACZ,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCP,CAAC;AACH,CAAC;AAED,SAAS,KAAK;IACZ,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgEP,CAAC;AACH,CAAC;AAED,SAAS,QAAQ;IACf,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DP,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,MAAwB;IACxC,MAAM,QAAQ,GACZ,MAAM,KAAK,WAAW;QACpB,CAAC,CAAC;;;;;;;;;;;;;+CAauC;QACzC,CAAC,CAAC;;;+CAGuC,CAAC;IAC9C,MAAM,KAAK,GACT,MAAM,KAAK,UAAU;QACnB,CAAC,CAAC;;;;;;;2DAOmD;QACrD,CAAC,CAAC,MAAM,KAAK,WAAW;YACtB,CAAC,CAAC;;;;;;;;gCAQsB;YACxB,CAAC,CAAC;;;;;;;;;;;;;;;;;sDAiB4C,CAAC;IACrD,OAAO;;;;;;;;;;;;;;;;;IAiBL,QAAQ;IACR,KAAK;EACP,CAAC;AACH,CAAC"}
|