@woosh/meep-engine 3.68.0 → 3.69.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/CHANGELOG.md +45 -0
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts +2 -17
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts.map +1 -1
- package/editor/ecs/component/editors/ecs/Trail3DEditor.js +3 -18
- package/package.json +1 -1
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +33 -65
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail3d/Trail3D.js +37 -245
- package/src/engine/graphics/ecs/trail3d/Trail3DFlags.d.ts +0 -4
- package/src/engine/graphics/ecs/trail3d/Trail3DFlags.js +4 -10
- package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.d.ts +13 -10
- package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.js +28 -37
- package/src/engine/graphics/ecs/trail3d/trail_knot_count.d.ts +10 -0
- package/src/engine/graphics/ecs/trail3d/trail_knot_count.d.ts.map +1 -0
- package/src/engine/graphics/ecs/trail3d/trail_knot_count.js +27 -0
- package/src/engine/graphics/trail/TrailKnots.d.ts +62 -0
- package/src/engine/graphics/trail/TrailKnots.d.ts.map +1 -0
- package/src/engine/graphics/trail/TrailKnots.js +137 -0
- package/src/engine/graphics/trail/tube/TubeXMaterialSpec.d.ts +1 -1
- package/src/engine/graphics/trail/tube/TubeXMaterialSpec.js +1 -1
- package/src/engine/graphics3/EntityRowHold.d.ts +48 -0
- package/src/engine/graphics3/EntityRowHold.d.ts.map +1 -0
- package/src/engine/graphics3/EntityRowHold.js +128 -0
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +6 -2
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/GPUParticleEmitterSystem.js +11 -44
- package/src/engine/graphics3/Trail3DSystem.d.ts +69 -35
- package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
- package/src/engine/graphics3/Trail3DSystem.js +380 -81
- package/src/engine/physics/fluid/ecs/FluidObstacle.d.ts +17 -0
- package/src/engine/physics/fluid/ecs/FluidObstacle.d.ts.map +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacle.js +22 -2
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +6 -5
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +14 -3
- package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts +9 -1
- package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.js +11 -1
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts +5 -0
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.js +2 -0
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts +4 -3
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.js +11 -3
- package/src/shade/playground/trails/index.html +50 -0
- package/src/shade/playground/trails/main.d.ts +2 -0
- package/src/shade/playground/trails/main.d.ts.map +1 -0
- package/src/shade/playground/trails/main.js +258 -0
- package/src/shade/renderer/animation/animation_curve_write_keys.d.ts +18 -0
- package/src/shade/renderer/animation/animation_curve_write_keys.d.ts.map +1 -0
- package/src/shade/renderer/animation/animation_curve_write_keys.js +34 -0
- package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/ColorGrade.js +13 -36
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +2 -2
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts +2 -13
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.js +6 -21
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts +17 -6
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.js +38 -178
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts +7 -9
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.js +17 -106
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts +7 -17
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.js +18 -118
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts +14 -0
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING.js +18 -0
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts +3 -1
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.js +4 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +9 -0
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +20 -4
- package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts +11 -2
- package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.js +59 -2
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts +4 -1
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.js +367 -341
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts +6 -2
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +339 -282
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +3 -2
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -1
- package/src/shade/renderer/grass/press/shader_grass_press_mark.js +5 -3
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.d.ts +49 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.js +144 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.d.ts +71 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.js +152 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.d.ts +21 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.js +30 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.d.ts +101 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.js +306 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +11 -4
- package/src/shade/renderer/trails/GPUTrailAVBOITChannel.d.ts +69 -0
- package/src/shade/renderer/trails/GPUTrailAVBOITChannel.d.ts.map +1 -0
- package/src/shade/renderer/trails/GPUTrailAVBOITChannel.js +129 -0
- package/src/shade/renderer/trails/GPUTrailSystem.d.ts +164 -0
- package/src/shade/renderer/trails/GPUTrailSystem.d.ts.map +1 -0
- package/src/shade/renderer/trails/GPUTrailSystem.js +725 -0
- package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.d.ts +14 -0
- package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.d.ts.map +1 -0
- package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.js +38 -0
- package/src/shade/renderer/trails/data/TRAIL_KNOT.d.ts +66 -0
- package/src/shade/renderer/trails/data/TRAIL_KNOT.d.ts.map +1 -0
- package/src/shade/renderer/trails/data/TRAIL_KNOT.js +154 -0
- package/src/shade/renderer/trails/data/TRAIL_RECORD.d.ts +19 -0
- package/src/shade/renderer/trails/data/TRAIL_RECORD.d.ts.map +1 -0
- package/src/shade/renderer/trails/data/TRAIL_RECORD.js +68 -0
- package/src/shade/renderer/trails/data/TRAIL_STATE.d.ts +18 -0
- package/src/shade/renderer/trails/data/TRAIL_STATE.d.ts.map +1 -0
- package/src/shade/renderer/trails/data/TRAIL_STATE.js +43 -0
- package/src/shade/renderer/trails/graph_trails.d.ts +58 -0
- package/src/shade/renderer/trails/graph_trails.d.ts.map +1 -0
- package/src/shade/renderer/trails/graph_trails.js +155 -0
- package/src/shade/renderer/trails/graph_trails_avboit.d.ts +126 -0
- package/src/shade/renderer/trails/graph_trails_avboit.d.ts.map +1 -0
- package/src/shade/renderer/trails/graph_trails_avboit.js +300 -0
- package/src/shade/renderer/trails/runtime/TrailFadeCurves.d.ts +56 -0
- package/src/shade/renderer/trails/runtime/TrailFadeCurves.d.ts.map +1 -0
- package/src/shade/renderer/trails/runtime/TrailFadeCurves.js +220 -0
- package/src/shade/renderer/trails/runtime/TrailKnotPool.d.ts +49 -0
- package/src/shade/renderer/trails/runtime/TrailKnotPool.d.ts.map +1 -0
- package/src/shade/renderer/trails/runtime/TrailKnotPool.js +162 -0
- package/src/shade/renderer/trails/runtime/TrailParameters.d.ts +52 -0
- package/src/shade/renderer/trails/runtime/TrailParameters.d.ts.map +1 -0
- package/src/shade/renderer/trails/runtime/TrailParameters.js +126 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.d.ts +23 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.js +57 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.d.ts +14 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.js +40 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_seed.d.ts +18 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_seed.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_seed.js +64 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_segment.d.ts +14 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_segment.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_segment.js +51 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_update.d.ts +48 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_update.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_update.js +197 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_vertex.d.ts +34 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_vertex.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_vertex.js +111 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit.d.ts +24 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit.js +78 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.d.ts +23 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.js +130 -0
- package/src/shade/renderer/trails/shaders/shader_trail_draw_args.d.ts +29 -0
- package/src/shade/renderer/trails/shaders/shader_trail_draw_args.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_draw_args.js +78 -0
- package/src/shade/renderer/trails/shaders/shader_trail_seed.d.ts +18 -0
- package/src/shade/renderer/trails/shaders/shader_trail_seed.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_seed.js +79 -0
- package/src/shade/renderer/trails/shaders/shader_trail_update.d.ts +20 -0
- package/src/shade/renderer/trails/shaders/shader_trail_update.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_update.js +101 -0
- package/src/engine/graphics/ecs/trail3d/advance_trail.d.ts +0 -18
- package/src/engine/graphics/ecs/trail3d/advance_trail.d.ts.map +0 -1
- package/src/engine/graphics/ecs/trail3d/advance_trail.js +0 -42
- package/src/engine/graphics/ecs/trail3d/seed_trail_tube.d.ts +0 -14
- package/src/engine/graphics/ecs/trail3d/seed_trail_tube.d.ts.map +0 -1
- package/src/engine/graphics/ecs/trail3d/seed_trail_tube.js +0 -75
- package/src/engine/graphics/ecs/trail3d/trail_head_position.d.ts +0 -17
- package/src/engine/graphics/ecs/trail3d/trail_head_position.d.ts.map +0 -1
- package/src/engine/graphics/ecs/trail3d/trail_head_position.js +0 -19
- package/src/engine/graphics/trail/tube/TubeX.d.ts +0 -186
- package/src/engine/graphics/trail/tube/TubeX.d.ts.map +0 -1
- package/src/engine/graphics/trail/tube/TubeX.js +0 -575
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts +0 -16
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts.map +0 -1
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +0 -34
- package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts +0 -27
- package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts.map +0 -1
- package/src/engine/graphics/trail/tube/tube_attributes_spec.js +0 -70
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts +0 -38
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts.map +0 -1
- package/src/engine/graphics3/trail/trail_tube_write_geometry.js +0 -119
|
@@ -1,118 +1,250 @@
|
|
|
1
1
|
import { assert } from "../../core/assert.js";
|
|
2
|
-
import { DynamicMeshAVBOITChannel } from "../../shade/renderer/dynamic/DynamicMeshAVBOITChannel.js";
|
|
3
2
|
import { FramePhase } from "../../shade/renderer/extension/FramePhase.js";
|
|
4
3
|
import { RenderExtension } from "../../shade/renderer/extension/RenderExtension.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { row_of_entity } from "../../shade/renderer/scene/rows/GPUSceneRows.js";
|
|
5
|
+
import { graph_import_buffer } from "../../shade/renderer/shader/graph/graph_import_buffer.js";
|
|
6
|
+
import { GPUTrailAVBOITChannel } from "../../shade/renderer/trails/GPUTrailAVBOITChannel.js";
|
|
7
|
+
import { GPUTrailSystem } from "../../shade/renderer/trails/GPUTrailSystem.js";
|
|
8
|
+
import { TrailParameters } from "../../shade/renderer/trails/runtime/TrailParameters.js";
|
|
8
9
|
import { System } from "../ecs/System.js";
|
|
9
10
|
import { Transform64 } from "../ecs/transform/Transform64.js";
|
|
10
|
-
import {
|
|
11
|
-
import { seed_trail_tube } from "../graphics/ecs/trail3d/seed_trail_tube.js";
|
|
11
|
+
import { trail_knot_count } from "../graphics/ecs/trail3d/trail_knot_count.js";
|
|
12
12
|
import Trail3D from "../graphics/ecs/trail3d/Trail3D.js";
|
|
13
13
|
import { Trail3DFlags } from "../graphics/ecs/trail3d/Trail3DFlags.js";
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
} from "../graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js";
|
|
17
|
-
import { trail_tube_write_geometry } from "./trail/trail_tube_write_geometry.js";
|
|
14
|
+
import { TrailSpawnMode } from "../graphics/trail/TrailSpawnMode.js";
|
|
15
|
+
import { EntityRowHold } from "./EntityRowHold.js";
|
|
18
16
|
|
|
19
17
|
/**
|
|
20
|
-
*
|
|
18
|
+
* @typedef {Object} Trail3DEntry
|
|
19
|
+
* @property {number} entity
|
|
20
|
+
* @property {Trail3D} trail
|
|
21
|
+
* @property {EntityRowHold} hold the entity's row, kept current as it moves
|
|
22
|
+
* @property {import("../../shade/renderer/trails/GPUTrailSystem.js").GPUTrailContext|null} context the
|
|
23
|
+
* trail in the runtime, or null while it is not registered
|
|
24
|
+
* @property {number} knot_count knots of the trail's ring, fixed when it is built
|
|
25
|
+
* @property {number} radial radial segments, fixed when it is built
|
|
26
|
+
* @property {number} clears the component's `clearCount` as last seen
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Knots a trail is built with: its authored layout's, or as many as its maxAge lays down.
|
|
21
31
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
|
|
32
|
+
* @param {Trail3D} trail
|
|
33
|
+
* @returns {number}
|
|
34
|
+
*/
|
|
35
|
+
function knot_count_of(trail) {
|
|
36
|
+
return trail.knots !== null ? trail.knots.count : trail_knot_count(trail.maxAge);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Copy a component onto runtime parameters.
|
|
25
41
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
* @param {TrailParameters} parameters
|
|
43
|
+
* @param {Trail3D} trail
|
|
44
|
+
* @param {Trail3DEntry} entry
|
|
45
|
+
*/
|
|
46
|
+
export function apply_trail3d(parameters, trail, entry) {
|
|
47
|
+
const knots = trail.knots;
|
|
48
|
+
|
|
49
|
+
parameters.knot_count = entry.knot_count;
|
|
50
|
+
parameters.radial = entry.radial;
|
|
51
|
+
parameters.max_age = trail.maxAge;
|
|
52
|
+
parameters.width = trail.width;
|
|
53
|
+
parameters.distance_mode = trail.spawnMode === TrailSpawnMode.Distance;
|
|
54
|
+
parameters.spawn_distance = trail.spawnDistance;
|
|
55
|
+
parameters.spawning = trail.getFlag(Trail3DFlags.Spawning);
|
|
56
|
+
parameters.warmup = trail.warmup;
|
|
57
|
+
|
|
58
|
+
const color = trail.color;
|
|
59
|
+
|
|
60
|
+
parameters.color[0] = color.x;
|
|
61
|
+
parameters.color[1] = color.y;
|
|
62
|
+
parameters.color[2] = color.z;
|
|
63
|
+
parameters.color[3] = color.w;
|
|
64
|
+
|
|
65
|
+
const offset = trail.offset;
|
|
66
|
+
|
|
67
|
+
parameters.offset[0] = offset.x;
|
|
68
|
+
parameters.offset[1] = offset.y;
|
|
69
|
+
parameters.offset[2] = offset.z;
|
|
70
|
+
|
|
71
|
+
parameters.fade = trail.fade;
|
|
72
|
+
parameters.authored = knots;
|
|
73
|
+
parameters.authored_version = knots === null ? -1 : knots.version;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Records the trails' simulation into the frame, once the hierarchy has composed this frame's matrices
|
|
78
|
+
* and before the transparency pipeline draws.
|
|
79
|
+
*/
|
|
80
|
+
class Trail3DFrameExtension extends RenderExtension {
|
|
81
|
+
name = "trails";
|
|
82
|
+
|
|
83
|
+
phase = FramePhase.AfterLighting;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @type {Trail3DSystem}
|
|
87
|
+
*/
|
|
88
|
+
#system;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @param {Trail3DSystem} system
|
|
92
|
+
*/
|
|
93
|
+
constructor(system) {
|
|
94
|
+
super();
|
|
95
|
+
|
|
96
|
+
this.#system = system;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
record(frame) {
|
|
100
|
+
this.#system.record(frame);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Draws every {@link Trail3D}: simulated on the GPU, its head following the entity's `transforms` row,
|
|
106
|
+
* its knots seeded and committed in compute and its tube extruded in the vertex stage, drawn inside the
|
|
107
|
+
* transparency pipeline (AVBOIT), so a trail behind glass or smoke composites with them by depth.
|
|
108
|
+
* Nothing per knot happens on the CPU.
|
|
34
109
|
*
|
|
35
|
-
* **
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
110
|
+
* **What is the CPU's:** registering a trail with the scene context's {@link GPUTrailSystem} — a row, a
|
|
111
|
+
* knot run, the entity's transform row held through {@link EntityRowHold} — comparing each component's
|
|
112
|
+
* fields once a tick with what was staged and restaging what differs, and moving the clock by the
|
|
113
|
+
* simulation time it is given. A game writes `trail.color` or `trail.maxAge` from code that never heard
|
|
114
|
+
* of this system; there is no change signal to send.
|
|
40
115
|
*
|
|
41
|
-
* **
|
|
42
|
-
*
|
|
43
|
-
*
|
|
116
|
+
* **The head follows announced transforms.** A trail reads where its entity is from the GPU row, which a
|
|
117
|
+
* transform write reaches when it is announced (`TRANSFORM64_EVENT_CHANGE`), as meshes and particle
|
|
118
|
+
* emitters do.
|
|
44
119
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* unlit straight alpha, depth tested against the opaque scene and never written, which is what a
|
|
48
|
-
* trail wants and what the game's trails are authored as. `Trail3D.textureURL` therefore draws
|
|
49
|
-
* untinted here; nothing in the game's own effects sets it to anything a flat colour does not
|
|
50
|
-
* carry.
|
|
120
|
+
* A trail's knot count (from its `maxAge`, or its authored layout's) and its `radialSegments` are fixed
|
|
121
|
+
* when it registers; a replaced authored layout brings its own count.
|
|
51
122
|
*/
|
|
52
123
|
export class Trail3DSystem extends System {
|
|
53
124
|
dependencies = [Trail3D, Transform64];
|
|
54
125
|
|
|
55
126
|
/**
|
|
56
|
-
* @type {GraphicsEngine}
|
|
127
|
+
* @type {import("./GraphicsEngine.js").GraphicsEngine}
|
|
57
128
|
*/
|
|
58
129
|
#graphics;
|
|
59
130
|
|
|
60
131
|
/**
|
|
61
|
-
* @type {
|
|
132
|
+
* @type {import("../../shade/renderer/scene/Scene.js").Scene}
|
|
62
133
|
*/
|
|
63
|
-
#
|
|
134
|
+
#scene;
|
|
64
135
|
|
|
65
136
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* @type {DynamicMeshAVBOITChannel}
|
|
137
|
+
* @type {import("../ecs/EntityComponentDataset.js").EntityComponentDataset|null}
|
|
69
138
|
*/
|
|
70
|
-
#
|
|
139
|
+
#dataset = null;
|
|
71
140
|
|
|
72
141
|
/**
|
|
73
|
-
* @type {Map<number,
|
|
142
|
+
* @type {Map<number, Trail3DEntry>}
|
|
74
143
|
*/
|
|
75
144
|
#entries = new Map();
|
|
76
145
|
|
|
77
146
|
/**
|
|
78
|
-
* @type {
|
|
147
|
+
* @type {GPUTrailSystem|null}
|
|
79
148
|
*/
|
|
80
|
-
#
|
|
149
|
+
#runtime = null;
|
|
81
150
|
|
|
82
151
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* @returns {DynamicMeshBatch}
|
|
152
|
+
* The scene context {@link #runtime} was made for.
|
|
153
|
+
* @type {import("../../shade/renderer/scene/GPUSceneContext.js").GPUSceneContext|null}
|
|
86
154
|
*/
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
155
|
+
#runtime_context = null;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @type {Trail3DFrameExtension|null}
|
|
159
|
+
*/
|
|
160
|
+
#extension = null;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @type {TrailParameters}
|
|
164
|
+
*/
|
|
165
|
+
#scratch = new TrailParameters();
|
|
90
166
|
|
|
91
167
|
/**
|
|
92
|
-
*
|
|
168
|
+
* What draws the trails, inside the transparency pipeline.
|
|
169
|
+
* @type {GPUTrailAVBOITChannel}
|
|
93
170
|
*/
|
|
94
|
-
|
|
171
|
+
#channel = new GPUTrailAVBOITChannel();
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @type {function(): (import("../../shade/renderer/scene/GPUSceneContext.js").GPUSceneContext|null)}
|
|
175
|
+
*/
|
|
176
|
+
#current_context = () => this.#graphics.scene_context(this.#scene);
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @param {import("./GraphicsEngine.js").GraphicsEngine} graphics
|
|
180
|
+
* @param {import("../../shade/renderer/scene/Scene.js").Scene} scene the scene the trails' entities are in
|
|
181
|
+
*/
|
|
182
|
+
constructor(graphics, scene) {
|
|
95
183
|
super();
|
|
96
184
|
|
|
97
185
|
assert.defined(graphics, 'graphics');
|
|
186
|
+
assert.defined(scene, 'scene');
|
|
187
|
+
assert.equal(scene.isScene, true, 'scene.isScene !== true');
|
|
98
188
|
|
|
99
189
|
this.#graphics = graphics;
|
|
190
|
+
this.#scene = scene;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* The runtime the scene's trails are registered with, or null while there is no scene context.
|
|
195
|
+
*
|
|
196
|
+
* @returns {GPUTrailSystem|null}
|
|
197
|
+
*/
|
|
198
|
+
get runtime() {
|
|
199
|
+
return this.#runtime;
|
|
100
200
|
}
|
|
101
201
|
|
|
102
202
|
async startup(entityManager) {
|
|
103
203
|
this.entityManager = entityManager;
|
|
104
204
|
|
|
205
|
+
this.#extension = new Trail3DFrameExtension(this);
|
|
206
|
+
|
|
207
|
+
this.#graphics.add_extension(this.#extension);
|
|
105
208
|
this.#graphics.add_transparency_channel(this.#channel);
|
|
106
209
|
}
|
|
107
210
|
|
|
108
211
|
async shutdown(entityManager) {
|
|
109
|
-
|
|
212
|
+
if (this.#extension !== null) {
|
|
213
|
+
this.#graphics.remove_extension(this.#extension);
|
|
214
|
+
this.#extension = null;
|
|
215
|
+
}
|
|
216
|
+
|
|
110
217
|
this.#graphics.remove_transparency_channel(this.#channel);
|
|
218
|
+
this.#channel.end_frame();
|
|
219
|
+
|
|
220
|
+
this.#detach_dataset();
|
|
221
|
+
this.#destroy_runtime();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @param {import("../ecs/EntityComponentDataset.js").EntityComponentDataset} dataset
|
|
226
|
+
*/
|
|
227
|
+
handleDatasetAttached(dataset) {
|
|
228
|
+
this.#detach_dataset();
|
|
111
229
|
|
|
112
|
-
this
|
|
230
|
+
// the scene's rows are this dataset's entities; the first system to place one says so
|
|
231
|
+
const scene = this.#scene;
|
|
113
232
|
|
|
114
|
-
|
|
115
|
-
|
|
233
|
+
assert.ok(
|
|
234
|
+
scene.dataset === null || scene.dataset === undefined || scene.dataset === dataset,
|
|
235
|
+
'the scene is bound to another dataset'
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
scene.dataset = dataset;
|
|
239
|
+
|
|
240
|
+
this.#dataset = dataset;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @param {import("../ecs/EntityComponentDataset.js").EntityComponentDataset} dataset
|
|
245
|
+
*/
|
|
246
|
+
handleDatasetDetached(dataset) {
|
|
247
|
+
this.#detach_dataset();
|
|
116
248
|
}
|
|
117
249
|
|
|
118
250
|
/**
|
|
@@ -121,56 +253,223 @@ export class Trail3DSystem extends System {
|
|
|
121
253
|
* @param {number} entity
|
|
122
254
|
*/
|
|
123
255
|
link(trail, transform, entity) {
|
|
124
|
-
|
|
125
|
-
|
|
256
|
+
/** @type {Trail3DEntry} */
|
|
257
|
+
const entry = {
|
|
258
|
+
entity,
|
|
259
|
+
trail,
|
|
260
|
+
hold: new EntityRowHold(this.#dataset, entity, this.#current_context),
|
|
261
|
+
context: null,
|
|
262
|
+
knot_count: 0,
|
|
263
|
+
radial: 0,
|
|
264
|
+
clears: trail.clearCount,
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
this.#entries.set(entity, entry);
|
|
268
|
+
|
|
269
|
+
// registered now when there is a context, so a trail added mid-level is seeded where its entity
|
|
270
|
+
// stands from its first frame
|
|
271
|
+
if (this.#ensure_runtime() !== null) {
|
|
272
|
+
this.#register(entry);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @param {Trail3D} trail
|
|
278
|
+
* @param {Transform64} transform
|
|
279
|
+
* @param {number} entity
|
|
280
|
+
*/
|
|
281
|
+
unlink(trail, transform, entity) {
|
|
282
|
+
this.#drop(entity);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Move the clock by the simulation time given, register what is waiting, and restage every trail
|
|
287
|
+
* whose component changed.
|
|
288
|
+
*
|
|
289
|
+
* @param {number} [time_delta_seconds]
|
|
290
|
+
*/
|
|
291
|
+
update(time_delta_seconds = 0) {
|
|
292
|
+
const runtime = this.#ensure_runtime();
|
|
293
|
+
|
|
294
|
+
if (runtime === null) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
runtime.advance(time_delta_seconds);
|
|
299
|
+
|
|
300
|
+
for (const entry of this.#entries.values()) {
|
|
301
|
+
this.#sync(runtime, entry);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Record the frame's trail work — called by the frame extension.
|
|
307
|
+
*
|
|
308
|
+
* @param {import("../../shade/renderer/extension/FrameContext.js").FrameContext} frame
|
|
309
|
+
*/
|
|
310
|
+
record(frame) {
|
|
311
|
+
// whatever the last frame left is not this frame's: a frame that records nothing draws nothing
|
|
312
|
+
this.#channel.end_frame();
|
|
313
|
+
|
|
314
|
+
if (frame.view.scene.scene !== this.#scene) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const runtime = this.#ensure_runtime();
|
|
319
|
+
|
|
320
|
+
if (runtime === null) {
|
|
321
|
+
return;
|
|
126
322
|
}
|
|
127
323
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
324
|
+
for (const entry of this.#entries.values()) {
|
|
325
|
+
this.#sync(runtime, entry);
|
|
326
|
+
}
|
|
131
327
|
|
|
132
|
-
|
|
328
|
+
// Read the way the velocity pass and the particles read it: the hierarchy is encoded ahead of
|
|
329
|
+
// the frame's graph, so the matrices in it are this frame's.
|
|
330
|
+
const scene_database = graph_import_buffer(frame.graph, frame.view.scene.scene_database_buffer, "scene_database/trails");
|
|
133
331
|
|
|
134
|
-
|
|
332
|
+
const simulation = runtime.record_simulation(frame.graph, scene_database);
|
|
135
333
|
|
|
136
|
-
this.#
|
|
334
|
+
this.#channel.begin_frame(frame.graph, frame.view, runtime, simulation);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* @param {GPUTrailSystem} runtime
|
|
339
|
+
* @param {Trail3DEntry} entry
|
|
340
|
+
*/
|
|
341
|
+
#sync(runtime, entry) {
|
|
342
|
+
const context = entry.context;
|
|
343
|
+
|
|
344
|
+
if (context === null) {
|
|
345
|
+
this.#register(entry);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const trail = entry.trail;
|
|
350
|
+
|
|
351
|
+
// a build-time change: an authored layout replaced, or one added or taken away
|
|
352
|
+
const knots = trail.knots;
|
|
353
|
+
|
|
354
|
+
if (knots !== context.staged.authored
|
|
355
|
+
|| (knots !== null && knots.version !== context.staged.authored_version)) {
|
|
356
|
+
entry.knot_count = knot_count_of(trail);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const scratch = this.#scratch;
|
|
360
|
+
|
|
361
|
+
apply_trail3d(scratch, trail, entry);
|
|
362
|
+
|
|
363
|
+
if (!scratch.equals(context.staged)) {
|
|
364
|
+
runtime.stage(context, scratch);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (entry.clears !== trail.clearCount) {
|
|
368
|
+
entry.clears = trail.clearCount;
|
|
369
|
+
runtime.clear(context);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* @param {Trail3DEntry} entry
|
|
375
|
+
*/
|
|
376
|
+
#register(entry) {
|
|
377
|
+
const runtime = this.#runtime;
|
|
378
|
+
const trail = entry.trail;
|
|
379
|
+
|
|
380
|
+
entry.knot_count = knot_count_of(trail);
|
|
381
|
+
entry.radial = trail.radialSegments;
|
|
382
|
+
entry.clears = trail.clearCount;
|
|
383
|
+
|
|
384
|
+
entry.hold.acquire(this.#runtime_context);
|
|
385
|
+
|
|
386
|
+
const scratch = this.#scratch;
|
|
387
|
+
|
|
388
|
+
apply_trail3d(scratch, trail, entry);
|
|
389
|
+
|
|
390
|
+
const context = runtime.add(scratch, row_of_entity(entry.entity));
|
|
391
|
+
|
|
392
|
+
if (context === null) {
|
|
393
|
+
// the knot pool cannot grow to house it on this device
|
|
394
|
+
entry.hold.release();
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
entry.context = context;
|
|
137
399
|
}
|
|
138
400
|
|
|
139
401
|
/**
|
|
140
|
-
* @param {Trail3D} trail
|
|
141
|
-
* @param {Transform64} transform
|
|
142
402
|
* @param {number} entity
|
|
143
403
|
*/
|
|
144
|
-
|
|
404
|
+
#drop(entity) {
|
|
145
405
|
const entry = this.#entries.get(entity);
|
|
146
406
|
|
|
147
407
|
if (entry === undefined) {
|
|
148
408
|
return;
|
|
149
409
|
}
|
|
150
410
|
|
|
151
|
-
|
|
411
|
+
if (entry.context !== null && this.#runtime !== null) {
|
|
412
|
+
this.#runtime.remove(entry.context);
|
|
413
|
+
}
|
|
152
414
|
|
|
153
|
-
|
|
154
|
-
|
|
415
|
+
entry.context = null;
|
|
416
|
+
entry.hold.dispose();
|
|
155
417
|
|
|
156
418
|
this.#entries.delete(entity);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* The runtime for the scene context the scene renders through now, made fresh when that context is
|
|
423
|
+
* new: a device restart builds a new one, and every trail registers again and is seeded anew.
|
|
424
|
+
*
|
|
425
|
+
* @returns {GPUTrailSystem|null}
|
|
426
|
+
*/
|
|
427
|
+
#ensure_runtime() {
|
|
428
|
+
const context = this.#current_context();
|
|
429
|
+
|
|
430
|
+
if (context === this.#runtime_context) {
|
|
431
|
+
return this.#runtime;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
this.#destroy_runtime();
|
|
435
|
+
|
|
436
|
+
if (context === null) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
this.#runtime = new GPUTrailSystem(context.graphics);
|
|
441
|
+
this.#runtime_context = context;
|
|
157
442
|
|
|
158
|
-
|
|
443
|
+
return this.#runtime;
|
|
159
444
|
}
|
|
160
445
|
|
|
161
|
-
|
|
446
|
+
#destroy_runtime() {
|
|
162
447
|
for (const entry of this.#entries.values()) {
|
|
163
|
-
|
|
448
|
+
// the trails and rows went with the context that held them
|
|
449
|
+
entry.context = null;
|
|
450
|
+
entry.hold.release();
|
|
451
|
+
}
|
|
164
452
|
|
|
165
|
-
|
|
453
|
+
if (this.#runtime !== null) {
|
|
454
|
+
this.#runtime.destroy();
|
|
455
|
+
}
|
|
166
456
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
trail.clearFlag(Trail3DFlags.BoundsNeedUpdate);
|
|
457
|
+
this.#runtime = null;
|
|
458
|
+
this.#runtime_context = null;
|
|
459
|
+
}
|
|
171
460
|
|
|
172
|
-
|
|
461
|
+
#detach_dataset() {
|
|
462
|
+
for (const entity of Array.from(this.#entries.keys())) {
|
|
463
|
+
this.#drop(entity);
|
|
173
464
|
}
|
|
465
|
+
|
|
466
|
+
const dataset = this.#dataset;
|
|
467
|
+
|
|
468
|
+
if (dataset !== null && this.#scene.dataset === dataset) {
|
|
469
|
+
this.#scene.dataset = null;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
this.#dataset = null;
|
|
174
473
|
}
|
|
175
474
|
}
|
|
176
475
|
|
|
@@ -38,6 +38,22 @@ export class FluidObstacle {
|
|
|
38
38
|
* @type {number}
|
|
39
39
|
*/
|
|
40
40
|
inflation: number;
|
|
41
|
+
/**
|
|
42
|
+
* How the obstacle stops the wind, 1/m. `0` (default): it is **solid**, and the air takes its
|
|
43
|
+
* velocity wherever it is. Above `0`: it is **porous**, the air passes through it and is slowed
|
|
44
|
+
* toward its velocity by `drag · |u − v| · (u − v)` each second, `u` the air's velocity and `v`
|
|
45
|
+
* the obstacle's.
|
|
46
|
+
*
|
|
47
|
+
* For something made of leaves or blades it is their drag coefficient times their one-sided area
|
|
48
|
+
* per cubic metre of the volume: a canopy of grass, a crop, the crown of a tree, a hedge. Their drag
|
|
49
|
+
* is spread through the volume, which is what makes the wind slow inside and fast above, and the
|
|
50
|
+
* shear at its top roll up into the gusts that run over a field.
|
|
51
|
+
*
|
|
52
|
+
* Only the GPU fluid has porous obstacles; the CPU fluid leaves them out.
|
|
53
|
+
*
|
|
54
|
+
* @type {number}
|
|
55
|
+
*/
|
|
56
|
+
drag: number;
|
|
41
57
|
/**
|
|
42
58
|
* True when the previous tick stamped a non-zero wall velocity. A body
|
|
43
59
|
* that stops (or sleeps — the solver zeroes velocities on sleep) must
|
|
@@ -58,6 +74,7 @@ export class FluidObstacle {
|
|
|
58
74
|
hash(): number;
|
|
59
75
|
toJSON(): {
|
|
60
76
|
inflation: number;
|
|
77
|
+
drag: number;
|
|
61
78
|
};
|
|
62
79
|
fromJSON(json: any): void;
|
|
63
80
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FluidObstacle.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/ecs/FluidObstacle.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FluidObstacle.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/ecs/FluidObstacle.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH;IAEI;;;;;;;;;;;;OAYG;IACH,WAFU,MAAM,CAEF;IAEd;;;;;;;;;;;;;;OAcG;IACH,MAFU,MAAM,CAEP;IAET;;;;;;;OAOG;IACH,aAFU,OAAO,CAEG;IAEpB;;;OAGG;IACH,cAHW,aAAa,GACZ,OAAO,CAUlB;IAED;;OAEG;IACH,QAFY,MAAM,CAIjB;IAED;;;MAKC;IAED,0BAGC;IASL;;;OAGG;IACH,0BAFU,OAAO,CAEsB;CAZtC;;kBAIS,MAAM"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { hash_mix2 } from "../../../../core/math/hash/hash_mix2.js";
|
|
1
2
|
import { computeHashFloat } from "../../../../core/primitives/numbers/computeHashFloat.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -42,6 +43,23 @@ export class FluidObstacle {
|
|
|
42
43
|
*/
|
|
43
44
|
inflation = 0;
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* How the obstacle stops the wind, 1/m. `0` (default): it is **solid**, and the air takes its
|
|
48
|
+
* velocity wherever it is. Above `0`: it is **porous**, the air passes through it and is slowed
|
|
49
|
+
* toward its velocity by `drag · |u − v| · (u − v)` each second, `u` the air's velocity and `v`
|
|
50
|
+
* the obstacle's.
|
|
51
|
+
*
|
|
52
|
+
* For something made of leaves or blades it is their drag coefficient times their one-sided area
|
|
53
|
+
* per cubic metre of the volume: a canopy of grass, a crop, the crown of a tree, a hedge. Their drag
|
|
54
|
+
* is spread through the volume, which is what makes the wind slow inside and fast above, and the
|
|
55
|
+
* shear at its top roll up into the gusts that run over a field.
|
|
56
|
+
*
|
|
57
|
+
* Only the GPU fluid has porous obstacles; the CPU fluid leaves them out.
|
|
58
|
+
*
|
|
59
|
+
* @type {number}
|
|
60
|
+
*/
|
|
61
|
+
drag = 0;
|
|
62
|
+
|
|
45
63
|
/**
|
|
46
64
|
* True when the previous tick stamped a non-zero wall velocity. A body
|
|
47
65
|
* that stops (or sleeps — the solver zeroes velocities on sleep) must
|
|
@@ -63,24 +81,26 @@ export class FluidObstacle {
|
|
|
63
81
|
if (other === null || other === undefined || other.isFluidObstacle !== true) {
|
|
64
82
|
return false;
|
|
65
83
|
}
|
|
66
|
-
return this.inflation === other.inflation;
|
|
84
|
+
return this.inflation === other.inflation && this.drag === other.drag;
|
|
67
85
|
}
|
|
68
86
|
|
|
69
87
|
/**
|
|
70
88
|
* @return {number}
|
|
71
89
|
*/
|
|
72
90
|
hash() {
|
|
73
|
-
return computeHashFloat(this.inflation);
|
|
91
|
+
return hash_mix2(computeHashFloat(this.inflation), computeHashFloat(this.drag));
|
|
74
92
|
}
|
|
75
93
|
|
|
76
94
|
toJSON() {
|
|
77
95
|
return {
|
|
78
96
|
inflation: this.inflation,
|
|
97
|
+
drag: this.drag,
|
|
79
98
|
};
|
|
80
99
|
}
|
|
81
100
|
|
|
82
101
|
fromJSON(json) {
|
|
83
102
|
if (json.inflation !== undefined) this.inflation = json.inflation;
|
|
103
|
+
this.drag = json.drag ?? 0;
|
|
84
104
|
}
|
|
85
105
|
}
|
|
86
106
|
|