@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
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { ALLOCATOR_NO_SPACE, OffsetAllocator } from "../../../../core/binary/allocator/OffsetAllocator.js";
|
|
3
|
+
import { HashMap } from "../../../../core/collection/map/HashMap.js";
|
|
4
|
+
import {
|
|
5
|
+
ANIMATION_CURVE_KEYFRAME_FLOATS,
|
|
6
|
+
animation_curve_write_keys
|
|
7
|
+
} from "../../animation/animation_curve_write_keys.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Keys the store starts with room for.
|
|
11
|
+
* @type {number}
|
|
12
|
+
*/
|
|
13
|
+
const INITIAL_KEY_CAPACITY = 256;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A curve's place in the key buffer, shared by every trail that fades by an equal curve.
|
|
17
|
+
*/
|
|
18
|
+
export class TrailFadeCurve {
|
|
19
|
+
/** @type {number} first key in the buffer */
|
|
20
|
+
first = 0;
|
|
21
|
+
|
|
22
|
+
/** @type {number} keys */
|
|
23
|
+
count = 0;
|
|
24
|
+
|
|
25
|
+
/** @type {number} trails holding it */
|
|
26
|
+
references = 0;
|
|
27
|
+
|
|
28
|
+
/** @type {import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation|null} */
|
|
29
|
+
allocation = null;
|
|
30
|
+
|
|
31
|
+
/** @type {import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve|null} the store's own copy */
|
|
32
|
+
curve = null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The trails' fade curves on the GPU, one run of keys per distinct curve, in the layout
|
|
37
|
+
* `chunk_animation_curve_evaluate_keys` reads (`ANIMATION_CURVE_KEYFRAME_STRUCT`).
|
|
38
|
+
*
|
|
39
|
+
* A curve is the trails' class data, not theirs alone: every trail on the shared default fade, or on one
|
|
40
|
+
* curve a game hands out, reads one run. Curves are found by content — a curve that equals one held is
|
|
41
|
+
* that one — and kept by reference count, so the last trail to let go frees the run. The key is a copy,
|
|
42
|
+
* because a curve the caller holds can be edited in place.
|
|
43
|
+
*
|
|
44
|
+
* Nothing on the GPU writes the buffer, so it grows by replacement and the whole of it goes up again.
|
|
45
|
+
*/
|
|
46
|
+
export class TrailFadeCurves {
|
|
47
|
+
/**
|
|
48
|
+
* @type {GPUDevice}
|
|
49
|
+
*/
|
|
50
|
+
#device;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @type {OffsetAllocator}
|
|
54
|
+
*/
|
|
55
|
+
#allocator = new OffsetAllocator(INITIAL_KEY_CAPACITY);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @type {Float32Array}
|
|
59
|
+
*/
|
|
60
|
+
#keys = new Float32Array(INITIAL_KEY_CAPACITY * ANIMATION_CURVE_KEYFRAME_FLOATS);
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @type {HashMap<import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve, TrailFadeCurve>}
|
|
64
|
+
*/
|
|
65
|
+
#curves = new HashMap();
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @type {GPUBuffer|null}
|
|
69
|
+
*/
|
|
70
|
+
#buffer = null;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Whether the CPU keys have changed since they last went up.
|
|
74
|
+
* @type {boolean}
|
|
75
|
+
*/
|
|
76
|
+
#dirty = true;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @param {GPUDevice} device
|
|
80
|
+
*/
|
|
81
|
+
constructor(device) {
|
|
82
|
+
assert.defined(device, 'device');
|
|
83
|
+
|
|
84
|
+
this.#device = device;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @returns {number} distinct curves held
|
|
89
|
+
*/
|
|
90
|
+
get count() {
|
|
91
|
+
return this.#curves.size;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The key buffer as the GPU should see it, uploaded first if anything changed.
|
|
96
|
+
*
|
|
97
|
+
* @returns {GPUBuffer}
|
|
98
|
+
*/
|
|
99
|
+
flush() {
|
|
100
|
+
const keys = this.#keys;
|
|
101
|
+
|
|
102
|
+
if (this.#buffer !== null && this.#buffer.size !== keys.byteLength) {
|
|
103
|
+
this.#buffer.destroy();
|
|
104
|
+
this.#buffer = null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (this.#buffer === null) {
|
|
108
|
+
this.#buffer = this.#device.createBuffer({
|
|
109
|
+
label: "Trails / fade keys",
|
|
110
|
+
size: keys.byteLength,
|
|
111
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
this.#dirty = true;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (this.#dirty) {
|
|
118
|
+
this.#device.queue.writeBuffer(this.#buffer, 0, keys.buffer, keys.byteOffset, keys.byteLength);
|
|
119
|
+
this.#dirty = false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return this.#buffer;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Hold a curve equal to `curve`, placing its keys if none is held.
|
|
127
|
+
*
|
|
128
|
+
* @param {import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve} curve at least one key
|
|
129
|
+
* @returns {TrailFadeCurve}
|
|
130
|
+
*/
|
|
131
|
+
acquire(curve) {
|
|
132
|
+
assert.greaterThan(curve.keys.length, 0, 'a fade curve needs a key');
|
|
133
|
+
|
|
134
|
+
let held = this.#curves.get(curve);
|
|
135
|
+
|
|
136
|
+
if (held === undefined) {
|
|
137
|
+
held = this.#place(curve);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
held.references++;
|
|
141
|
+
|
|
142
|
+
return held;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @param {TrailFadeCurve} held from {@link acquire}
|
|
147
|
+
*/
|
|
148
|
+
release(held) {
|
|
149
|
+
assert.greaterThan(held.references, 0, 'released more often than acquired');
|
|
150
|
+
|
|
151
|
+
held.references--;
|
|
152
|
+
|
|
153
|
+
if (held.references > 0) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
this.#curves.delete(held.curve);
|
|
158
|
+
this.#allocator.free(held.allocation);
|
|
159
|
+
|
|
160
|
+
held.allocation = null;
|
|
161
|
+
held.curve = null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
destroy() {
|
|
165
|
+
this.#buffer?.destroy();
|
|
166
|
+
this.#buffer = null;
|
|
167
|
+
this.#dirty = true;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @param {import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve} curve
|
|
172
|
+
* @returns {TrailFadeCurve}
|
|
173
|
+
*/
|
|
174
|
+
#place(curve) {
|
|
175
|
+
const count = curve.keys.length;
|
|
176
|
+
|
|
177
|
+
let allocation = this.#allocator.allocate(count);
|
|
178
|
+
|
|
179
|
+
if (allocation.offset === ALLOCATOR_NO_SPACE) {
|
|
180
|
+
this.#grow(count);
|
|
181
|
+
|
|
182
|
+
allocation = this.#allocator.allocate(count);
|
|
183
|
+
|
|
184
|
+
assert.notEqual(allocation.offset, ALLOCATOR_NO_SPACE, 'the fade key store grew and still has no room');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
animation_curve_write_keys(this.#keys, allocation.offset * ANIMATION_CURVE_KEYFRAME_FLOATS, curve);
|
|
188
|
+
|
|
189
|
+
this.#dirty = true;
|
|
190
|
+
|
|
191
|
+
const held = new TrailFadeCurve();
|
|
192
|
+
|
|
193
|
+
held.first = allocation.offset;
|
|
194
|
+
held.count = count;
|
|
195
|
+
held.allocation = allocation;
|
|
196
|
+
held.curve = curve.clone();
|
|
197
|
+
|
|
198
|
+
this.#curves.set(held.curve, held);
|
|
199
|
+
|
|
200
|
+
return held;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @param {number} required keys of the curve that did not fit
|
|
205
|
+
*/
|
|
206
|
+
#grow(required) {
|
|
207
|
+
const allocator = this.#allocator;
|
|
208
|
+
|
|
209
|
+
const size = Math.max(allocator.size * 2, allocator.grow_target_for(required));
|
|
210
|
+
|
|
211
|
+
allocator.grow(size);
|
|
212
|
+
|
|
213
|
+
const keys = new Float32Array(size * ANIMATION_CURVE_KEYFRAME_FLOATS);
|
|
214
|
+
|
|
215
|
+
keys.set(this.#keys);
|
|
216
|
+
|
|
217
|
+
this.#keys = keys;
|
|
218
|
+
this.#dirty = true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every trail's knots, in one storage buffer: a run per trail, handed out by an {@link OffsetAllocator}
|
|
3
|
+
* in knots.
|
|
4
|
+
*
|
|
5
|
+
* The knots are the GPU's — seeded, committed and rewritten on the device — so the pool grows by copy:
|
|
6
|
+
* a larger buffer, the whole old one copied in at offset 0, and {@link OffsetAllocator#grow} appending
|
|
7
|
+
* the new tail as free space. No run moves, so every trail's `knot_base` stays what it was. Growth stops
|
|
8
|
+
* at the device's `maxBufferSize` and `maxStorageBufferBindingSize`; a run that cannot be housed past
|
|
9
|
+
* that is a failed {@link allocate}.
|
|
10
|
+
*
|
|
11
|
+
* Grows outside the frame: the copy is submitted on its own before the next frame records, and the old
|
|
12
|
+
* buffer is destroyed after that submission.
|
|
13
|
+
*/
|
|
14
|
+
export class TrailKnotPool {
|
|
15
|
+
/**
|
|
16
|
+
* @param {GPUDevice} device
|
|
17
|
+
*/
|
|
18
|
+
constructor(device: GPUDevice);
|
|
19
|
+
/**
|
|
20
|
+
* @returns {GPUBuffer}
|
|
21
|
+
*/
|
|
22
|
+
get buffer(): GPUBuffer;
|
|
23
|
+
/**
|
|
24
|
+
* @returns {number} knots the pool has room for
|
|
25
|
+
*/
|
|
26
|
+
get capacity(): number;
|
|
27
|
+
/**
|
|
28
|
+
* A run of `count` knots, growing the pool when it has no room.
|
|
29
|
+
*
|
|
30
|
+
* @param {number} count
|
|
31
|
+
* @returns {import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation} its offset is in
|
|
32
|
+
* knots; a failed allocation's is `ALLOCATOR_NO_SPACE`
|
|
33
|
+
*/
|
|
34
|
+
allocate(count: number): import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation;
|
|
35
|
+
/**
|
|
36
|
+
* @param {import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation} allocation from {@link allocate}
|
|
37
|
+
*/
|
|
38
|
+
free(allocation: import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation): void;
|
|
39
|
+
/**
|
|
40
|
+
* Write knots laid down on the CPU into the run starting at `knot_offset`.
|
|
41
|
+
*
|
|
42
|
+
* @param {number} knot_offset
|
|
43
|
+
* @param {Uint32Array} words whole knots, `TRAIL_KNOT_WORDS` apiece
|
|
44
|
+
*/
|
|
45
|
+
write(knot_offset: number, words: Uint32Array): void;
|
|
46
|
+
destroy(): void;
|
|
47
|
+
#private;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=TrailKnotPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrailKnotPool.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/trails/runtime/TrailKnotPool.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;GAYG;AACH;IAgBI;;OAEG;IACH,+BAUC;IAED;;OAEG;IACH,wBAEC;IAED;;OAEG;IACH,uBAEC;IAED;;;;;;OAMG;IACH,gBAJW,MAAM,GACJ,OAAO,sDAAsD,EAAE,UAAU,CAerF;IAED;;OAEG;IACH,iBAFW,OAAO,sDAAsD,EAAE,UAAU,QAInF;IAED;;;;;OAKG;IACH,mBAHW,MAAM,SACN,WAAW,QASrB;IAED,gBAEC;;CAgDJ"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { ALLOCATOR_NO_SPACE, OffsetAllocator } from "../../../../core/binary/allocator/OffsetAllocator.js";
|
|
3
|
+
import { TRAIL_KNOT_BYTES } from "../data/TRAIL_KNOT.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Knots the pool starts with room for.
|
|
7
|
+
* @type {number}
|
|
8
|
+
*/
|
|
9
|
+
const INITIAL_KNOT_CAPACITY = 4096;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Every trail's knots, in one storage buffer: a run per trail, handed out by an {@link OffsetAllocator}
|
|
13
|
+
* in knots.
|
|
14
|
+
*
|
|
15
|
+
* The knots are the GPU's — seeded, committed and rewritten on the device — so the pool grows by copy:
|
|
16
|
+
* a larger buffer, the whole old one copied in at offset 0, and {@link OffsetAllocator#grow} appending
|
|
17
|
+
* the new tail as free space. No run moves, so every trail's `knot_base` stays what it was. Growth stops
|
|
18
|
+
* at the device's `maxBufferSize` and `maxStorageBufferBindingSize`; a run that cannot be housed past
|
|
19
|
+
* that is a failed {@link allocate}.
|
|
20
|
+
*
|
|
21
|
+
* Grows outside the frame: the copy is submitted on its own before the next frame records, and the old
|
|
22
|
+
* buffer is destroyed after that submission.
|
|
23
|
+
*/
|
|
24
|
+
export class TrailKnotPool {
|
|
25
|
+
/**
|
|
26
|
+
* @type {GPUDevice}
|
|
27
|
+
*/
|
|
28
|
+
#device;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @type {OffsetAllocator}
|
|
32
|
+
*/
|
|
33
|
+
#allocator;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @type {GPUBuffer}
|
|
37
|
+
*/
|
|
38
|
+
#buffer;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {GPUDevice} device
|
|
42
|
+
*/
|
|
43
|
+
constructor(device) {
|
|
44
|
+
assert.defined(device, 'device');
|
|
45
|
+
|
|
46
|
+
this.#device = device;
|
|
47
|
+
this.#allocator = new OffsetAllocator(INITIAL_KNOT_CAPACITY);
|
|
48
|
+
this.#buffer = device.createBuffer({
|
|
49
|
+
label: "Trails / knots",
|
|
50
|
+
size: INITIAL_KNOT_CAPACITY * TRAIL_KNOT_BYTES,
|
|
51
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @returns {GPUBuffer}
|
|
57
|
+
*/
|
|
58
|
+
get buffer() {
|
|
59
|
+
return this.#buffer;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @returns {number} knots the pool has room for
|
|
64
|
+
*/
|
|
65
|
+
get capacity() {
|
|
66
|
+
return this.#allocator.size;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A run of `count` knots, growing the pool when it has no room.
|
|
71
|
+
*
|
|
72
|
+
* @param {number} count
|
|
73
|
+
* @returns {import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation} its offset is in
|
|
74
|
+
* knots; a failed allocation's is `ALLOCATOR_NO_SPACE`
|
|
75
|
+
*/
|
|
76
|
+
allocate(count) {
|
|
77
|
+
assert.isPositiveInteger(count, 'count');
|
|
78
|
+
|
|
79
|
+
let allocation = this.#allocator.allocate(count);
|
|
80
|
+
|
|
81
|
+
if (allocation.offset === ALLOCATOR_NO_SPACE) {
|
|
82
|
+
this.#grow(count);
|
|
83
|
+
|
|
84
|
+
allocation = this.#allocator.allocate(count);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return allocation;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @param {import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation} allocation from {@link allocate}
|
|
92
|
+
*/
|
|
93
|
+
free(allocation) {
|
|
94
|
+
this.#allocator.free(allocation);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Write knots laid down on the CPU into the run starting at `knot_offset`.
|
|
99
|
+
*
|
|
100
|
+
* @param {number} knot_offset
|
|
101
|
+
* @param {Uint32Array} words whole knots, `TRAIL_KNOT_WORDS` apiece
|
|
102
|
+
*/
|
|
103
|
+
write(knot_offset, words) {
|
|
104
|
+
assert.isNonNegativeInteger(knot_offset, 'knot_offset');
|
|
105
|
+
|
|
106
|
+
this.#device.queue.writeBuffer(
|
|
107
|
+
this.#buffer, knot_offset * TRAIL_KNOT_BYTES,
|
|
108
|
+
words.buffer, words.byteOffset, words.byteLength
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
destroy() {
|
|
113
|
+
this.#buffer.destroy();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @param {number} required knots of the run that did not fit
|
|
118
|
+
*/
|
|
119
|
+
#grow(required) {
|
|
120
|
+
const device = this.#device;
|
|
121
|
+
const limits = device.limits;
|
|
122
|
+
|
|
123
|
+
const old_buffer = this.#buffer;
|
|
124
|
+
const old_size = old_buffer.size;
|
|
125
|
+
|
|
126
|
+
const ceiling_knots = Math.floor(
|
|
127
|
+
Math.min(limits.maxBufferSize, limits.maxStorageBufferBindingSize) / TRAIL_KNOT_BYTES
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// the allocator's own answer for a run that size to land, doubled so a stream of short trails
|
|
131
|
+
// does not pay a copy of the whole pool apiece
|
|
132
|
+
const knots = Math.min(
|
|
133
|
+
Math.max(this.#allocator.size * 2, this.#allocator.grow_target_for(required)),
|
|
134
|
+
ceiling_knots
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
if (knots <= this.#allocator.size) {
|
|
138
|
+
// as large as this device allows
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const new_buffer = device.createBuffer({
|
|
143
|
+
label: old_buffer.label,
|
|
144
|
+
size: knots * TRAIL_KNOT_BYTES,
|
|
145
|
+
usage: old_buffer.usage,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// past the fallible part: OffsetAllocator#grow cannot be undone
|
|
149
|
+
this.#allocator.grow(knots);
|
|
150
|
+
|
|
151
|
+
const encoder = device.createCommandEncoder({ label: "Trails / knots / grow" });
|
|
152
|
+
|
|
153
|
+
// runs did not move, so the bytes land back under the bases the trails already hold
|
|
154
|
+
encoder.copyBufferToBuffer(old_buffer, 0, new_buffer, 0, old_size);
|
|
155
|
+
|
|
156
|
+
device.queue.submit([encoder.finish()]);
|
|
157
|
+
|
|
158
|
+
old_buffer.destroy();
|
|
159
|
+
|
|
160
|
+
this.#buffer = new_buffer;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the GPU trail runtime is told about one trail: its look and its rules, as the CPU authors them.
|
|
3
|
+
* Plain data, compared field by field once a frame by whoever owns it, so a game can write a component
|
|
4
|
+
* field from code that has never heard of the renderer.
|
|
5
|
+
*
|
|
6
|
+
* `knot_count`, `radial` and `authored` are build-time: a change to any of them rebuilds the trail.
|
|
7
|
+
*/
|
|
8
|
+
export class TrailParameters {
|
|
9
|
+
/** @type {number} knots in the ring, at least 2 */
|
|
10
|
+
knot_count: number;
|
|
11
|
+
/** @type {number} radial segments around the tube, at least 3 */
|
|
12
|
+
radial: number;
|
|
13
|
+
/** @type {number} seconds a knot takes to fade out */
|
|
14
|
+
max_age: number;
|
|
15
|
+
/** @type {number} tube diameter */
|
|
16
|
+
width: number;
|
|
17
|
+
/** @type {boolean} knots are committed by distance travelled rather than by time */
|
|
18
|
+
distance_mode: boolean;
|
|
19
|
+
/** @type {number} distance between commits in distance mode */
|
|
20
|
+
spawn_distance: number;
|
|
21
|
+
/** @type {boolean} the head follows the entity */
|
|
22
|
+
spawning: boolean;
|
|
23
|
+
/** @type {boolean} the trail fades in over its first `max_age` seconds */
|
|
24
|
+
warmup: boolean;
|
|
25
|
+
/** @type {Float32Array} linear RGB, unbounded, and base opacity */
|
|
26
|
+
color: Float32Array;
|
|
27
|
+
/** @type {Float32Array} the head's place in the entity's local frame */
|
|
28
|
+
offset: Float32Array;
|
|
29
|
+
/** @type {import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve|null} opacity over a knot's life */
|
|
30
|
+
fade: import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve | null;
|
|
31
|
+
/** @type {import("../../../../engine/graphics/trail/TrailKnots.js").TrailKnots|null} knots laid down by the author, or null for a trail the entity draws */
|
|
32
|
+
authored: import("../../../../engine/graphics/trail/TrailKnots.js").TrailKnots | null;
|
|
33
|
+
/** @type {number} the {@link authored} version these parameters were taken at */
|
|
34
|
+
authored_version: number;
|
|
35
|
+
/**
|
|
36
|
+
* @param {TrailParameters} other
|
|
37
|
+
*/
|
|
38
|
+
copy(other: TrailParameters): void;
|
|
39
|
+
/**
|
|
40
|
+
* Whether `other` would build the same trail: same knot count, radial count and authored layout.
|
|
41
|
+
*
|
|
42
|
+
* @param {TrailParameters} other
|
|
43
|
+
* @returns {boolean}
|
|
44
|
+
*/
|
|
45
|
+
same_build(other: TrailParameters): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* @param {TrailParameters} other
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
equals(other: TrailParameters): boolean;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=TrailParameters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrailParameters.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/trails/runtime/TrailParameters.js"],"names":[],"mappings":"AAeA;;;;;;GAMG;AACH;IACI,mDAAmD;IACnD,YADW,MAAM,CACF;IAEf,iEAAiE;IACjE,QADW,MAAM,CACN;IAEX,sDAAsD;IACtD,SADW,MAAM,CACL;IAEZ,mCAAmC;IACnC,OADW,MAAM,CACP;IAEV,oFAAoF;IACpF,eADW,OAAO,CACI;IAEtB,+DAA+D;IAC/D,gBADW,MAAM,CACE;IAEnB,kDAAkD;IAClD,UADW,OAAO,CACF;IAEhB,0EAA0E;IAC1E,QADW,OAAO,CACJ;IAEd,mEAAmE;IACnE,OADW,YAAY,CACgB;IAEvC,wEAAwE;IACxE,QADW,YAAY,CACM;IAE7B,4HAA4H;IAC5H,MADW,OAAO,sDAAsD,EAAE,cAAc,GAAC,IAAI,CACjF;IAEZ,4JAA4J;IAC5J,UADW,OAAO,iDAAiD,EAAE,UAAU,GAAC,IAAI,CACpE;IAEhB,iFAAiF;IACjF,kBADW,MAAM,CACK;IAEtB;;OAEG;IACH,YAFW,eAAe,QAwBzB;IAED;;;;;OAKG;IACH,kBAHW,eAAe,GACb,OAAO,CAOnB;IAED;;;OAGG;IACH,cAHW,eAAe,GACb,OAAO,CAoBnB;CACJ"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve|null} a
|
|
5
|
+
* @param {import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve|null} b
|
|
6
|
+
* @returns {boolean} whether the two give the same fade
|
|
7
|
+
*/
|
|
8
|
+
function same_curve(a, b) {
|
|
9
|
+
if (a === b) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return a !== null && b !== null && a.equals(b);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* What the GPU trail runtime is told about one trail: its look and its rules, as the CPU authors them.
|
|
18
|
+
* Plain data, compared field by field once a frame by whoever owns it, so a game can write a component
|
|
19
|
+
* field from code that has never heard of the renderer.
|
|
20
|
+
*
|
|
21
|
+
* `knot_count`, `radial` and `authored` are build-time: a change to any of them rebuilds the trail.
|
|
22
|
+
*/
|
|
23
|
+
export class TrailParameters {
|
|
24
|
+
/** @type {number} knots in the ring, at least 2 */
|
|
25
|
+
knot_count = 2;
|
|
26
|
+
|
|
27
|
+
/** @type {number} radial segments around the tube, at least 3 */
|
|
28
|
+
radial = 8;
|
|
29
|
+
|
|
30
|
+
/** @type {number} seconds a knot takes to fade out */
|
|
31
|
+
max_age = 5;
|
|
32
|
+
|
|
33
|
+
/** @type {number} tube diameter */
|
|
34
|
+
width = 1;
|
|
35
|
+
|
|
36
|
+
/** @type {boolean} knots are committed by distance travelled rather than by time */
|
|
37
|
+
distance_mode = false;
|
|
38
|
+
|
|
39
|
+
/** @type {number} distance between commits in distance mode */
|
|
40
|
+
spawn_distance = 1;
|
|
41
|
+
|
|
42
|
+
/** @type {boolean} the head follows the entity */
|
|
43
|
+
spawning = true;
|
|
44
|
+
|
|
45
|
+
/** @type {boolean} the trail fades in over its first `max_age` seconds */
|
|
46
|
+
warmup = true;
|
|
47
|
+
|
|
48
|
+
/** @type {Float32Array} linear RGB, unbounded, and base opacity */
|
|
49
|
+
color = new Float32Array([1, 1, 1, 1]);
|
|
50
|
+
|
|
51
|
+
/** @type {Float32Array} the head's place in the entity's local frame */
|
|
52
|
+
offset = new Float32Array(3);
|
|
53
|
+
|
|
54
|
+
/** @type {import("../../../../engine/animation/curve/AnimationCurve.js").AnimationCurve|null} opacity over a knot's life */
|
|
55
|
+
fade = null;
|
|
56
|
+
|
|
57
|
+
/** @type {import("../../../../engine/graphics/trail/TrailKnots.js").TrailKnots|null} knots laid down by the author, or null for a trail the entity draws */
|
|
58
|
+
authored = null;
|
|
59
|
+
|
|
60
|
+
/** @type {number} the {@link authored} version these parameters were taken at */
|
|
61
|
+
authored_version = -1;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @param {TrailParameters} other
|
|
65
|
+
*/
|
|
66
|
+
copy(other) {
|
|
67
|
+
this.knot_count = other.knot_count;
|
|
68
|
+
this.radial = other.radial;
|
|
69
|
+
this.max_age = other.max_age;
|
|
70
|
+
this.width = other.width;
|
|
71
|
+
this.distance_mode = other.distance_mode;
|
|
72
|
+
this.spawn_distance = other.spawn_distance;
|
|
73
|
+
this.spawning = other.spawning;
|
|
74
|
+
this.warmup = other.warmup;
|
|
75
|
+
this.color.set(other.color);
|
|
76
|
+
this.offset.set(other.offset);
|
|
77
|
+
|
|
78
|
+
// a copy, not the curve: a curve can be edited in place, and a snapshot that shares it would
|
|
79
|
+
// never see the edit
|
|
80
|
+
if (other.fade === null) {
|
|
81
|
+
this.fade = null;
|
|
82
|
+
} else if (this.fade === null || !this.fade.equals(other.fade)) {
|
|
83
|
+
this.fade = other.fade.clone();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.authored = other.authored;
|
|
87
|
+
this.authored_version = other.authored_version;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Whether `other` would build the same trail: same knot count, radial count and authored layout.
|
|
92
|
+
*
|
|
93
|
+
* @param {TrailParameters} other
|
|
94
|
+
* @returns {boolean}
|
|
95
|
+
*/
|
|
96
|
+
same_build(other) {
|
|
97
|
+
return this.knot_count === other.knot_count
|
|
98
|
+
&& this.radial === other.radial
|
|
99
|
+
&& this.authored === other.authored
|
|
100
|
+
&& this.authored_version === other.authored_version;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {TrailParameters} other
|
|
105
|
+
* @returns {boolean}
|
|
106
|
+
*/
|
|
107
|
+
equals(other) {
|
|
108
|
+
assert.defined(other, 'other');
|
|
109
|
+
|
|
110
|
+
return this.same_build(other)
|
|
111
|
+
&& this.max_age === other.max_age
|
|
112
|
+
&& this.width === other.width
|
|
113
|
+
&& this.distance_mode === other.distance_mode
|
|
114
|
+
&& this.spawn_distance === other.spawn_distance
|
|
115
|
+
&& this.spawning === other.spawning
|
|
116
|
+
&& this.warmup === other.warmup
|
|
117
|
+
&& this.color[0] === other.color[0]
|
|
118
|
+
&& this.color[1] === other.color[1]
|
|
119
|
+
&& this.color[2] === other.color[2]
|
|
120
|
+
&& this.color[3] === other.color[3]
|
|
121
|
+
&& this.offset[0] === other.offset[0]
|
|
122
|
+
&& this.offset[1] === other.offset[1]
|
|
123
|
+
&& this.offset[2] === other.offset[2]
|
|
124
|
+
&& same_curve(this.fade, other.fade);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Below this squared length the transported normal is degenerate — the previous normal was nearly
|
|
3
|
+
* parallel to the new tangent — and a fresh basis is built from the tangent instead.
|
|
4
|
+
* @type {number}
|
|
5
|
+
*/
|
|
6
|
+
export const TRAIL_FRAME_DEGENERATE_EPSILON_SQR: number;
|
|
7
|
+
/**
|
|
8
|
+
* `trail_frame_transport(tangent, previous_normal) -> TrailFrame`: the rotation-minimising frame of a
|
|
9
|
+
* tube's ring, carried from the previous knot's normal onto the plane perpendicular to the unit
|
|
10
|
+
* `tangent` (Gram-Schmidt), with `binormal = tangent × normal`. The ring keeps its orientation as the
|
|
11
|
+
* tangent turns, with no twist.
|
|
12
|
+
*
|
|
13
|
+
* When the previous normal is (nearly) parallel to the tangent the projection collapses, and the frame
|
|
14
|
+
* is built from the tangent alone, by the construction `v3_orthonormal_matrix_from_normal` uses on the
|
|
15
|
+
* CPU, so both paths bootstrap the same frame.
|
|
16
|
+
*
|
|
17
|
+
* The same arithmetic as `tube_frame_transport`.
|
|
18
|
+
*
|
|
19
|
+
* @type {CodeChunk}
|
|
20
|
+
*/
|
|
21
|
+
export const chunk_trail_frame_transport: CodeChunk;
|
|
22
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
23
|
+
//# sourceMappingURL=chunk_trail_frame_transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_trail_frame_transport.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/trails/shaders/chunk_trail_frame_transport.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,iDAFU,MAAM,CAEwC;AAExD;;;;;;;;;;;;;GAaG;AACH,0CAFU,SAAS,CAmCjB;0BAxDwB,oCAAoC"}
|