@woosh/meep-engine 3.46.0 → 3.47.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.
Files changed (230) hide show
  1. package/editor/actions/concrete/TransformModifyAction.d.ts.map +1 -1
  2. package/editor/actions/concrete/TransformModifyAction.js +10 -2
  3. package/editor/ecs/component/FieldDescriptor.js +15 -0
  4. package/editor/ecs/component/createObjectEditor.js +41 -12
  5. package/editor/ecs/component/editors/ecs/Transform64Editor.d.ts.map +1 -1
  6. package/editor/ecs/component/editors/ecs/Transform64Editor.js +77 -70
  7. package/editor/tools/TransformToolV2.d.ts.map +1 -1
  8. package/editor/tools/TransformToolV2.js +4 -0
  9. package/editor/tools/v2/TransformControls.d.ts.map +1 -1
  10. package/editor/tools/v2/TransformControls.js +7 -0
  11. package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
  12. package/editor/view/ecs/EntityEditor.js +4 -2
  13. package/package.json +1 -1
  14. package/src/core/collection/array/array_insert_at.d.ts +16 -0
  15. package/src/core/collection/array/array_insert_at.d.ts.map +1 -0
  16. package/src/core/collection/array/array_insert_at.js +32 -0
  17. package/src/core/collection/array/array_remove_at.d.ts +15 -0
  18. package/src/core/collection/array/array_remove_at.d.ts.map +1 -0
  19. package/src/core/collection/array/array_remove_at.js +30 -0
  20. package/src/core/geom/3d/quaternion/quat3_look_rotation.d.ts +37 -0
  21. package/src/core/geom/3d/quaternion/quat3_look_rotation.d.ts.map +1 -0
  22. package/src/core/geom/3d/quaternion/quat3_look_rotation.js +172 -0
  23. package/src/core/geom/Quaternion.d.ts +1 -0
  24. package/src/core/geom/Quaternion.d.ts.map +1 -1
  25. package/src/core/geom/Quaternion.js +12 -48
  26. package/src/engine/Engine.d.ts.map +1 -1
  27. package/src/engine/Engine.js +9 -4
  28. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  29. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +10 -0
  30. package/src/engine/ecs/transform/t64_look_rotation.d.ts +4 -4
  31. package/src/engine/ecs/transform/t64_look_rotation.d.ts.map +1 -1
  32. package/src/engine/ecs/transform/t64_look_rotation.js +7 -18
  33. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  34. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +30 -1
  35. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +6 -0
  36. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  37. package/src/engine/graphics3/GPUParticleEmitterSystem.js +72 -29
  38. package/src/engine/input/devices/KeyboardDevice.d.ts +1 -0
  39. package/src/engine/input/devices/KeyboardDevice.d.ts.map +1 -1
  40. package/src/engine/input/devices/KeyboardDevice.js +7 -6
  41. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts.map +1 -1
  42. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +15 -2
  43. package/src/engine/network/CONGESTION_CONTROL.md +9 -9
  44. package/src/engine/network/MESSAGE_TRANSPORT.md +364 -0
  45. package/src/engine/network/NetworkSession.d.ts +31 -11
  46. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  47. package/src/engine/network/NetworkSession.js +453 -286
  48. package/src/engine/network/README.md +77 -27
  49. package/src/engine/network/SMOOTHNESS_DESIGN.md +13 -5
  50. package/src/engine/network/diagnostics/BandwidthMeter.d.ts +1 -1
  51. package/src/engine/network/diagnostics/BandwidthMeter.js +1 -1
  52. package/src/engine/network/orchestrator/HostJoin.d.ts +111 -0
  53. package/src/engine/network/orchestrator/HostJoin.d.ts.map +1 -0
  54. package/src/engine/network/orchestrator/HostJoin.js +271 -0
  55. package/src/engine/network/orchestrator/NetworkPeer.d.ts +151 -112
  56. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  57. package/src/engine/network/orchestrator/NetworkPeer.js +450 -499
  58. package/src/engine/network/orchestrator/PendingSlices.d.ts +30 -0
  59. package/src/engine/network/orchestrator/PendingSlices.d.ts.map +1 -0
  60. package/src/engine/network/orchestrator/PendingSlices.js +83 -0
  61. package/src/engine/network/orchestrator/ReliableFrames.d.ts +34 -0
  62. package/src/engine/network/orchestrator/ReliableFrames.d.ts.map +1 -0
  63. package/src/engine/network/orchestrator/ReliableFrames.js +96 -0
  64. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +77 -10
  65. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  66. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +236 -61
  67. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +20 -6
  68. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  69. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +33 -8
  70. package/src/engine/network/replication/Replicator.d.ts.map +1 -1
  71. package/src/engine/network/replication/Replicator.js +7 -1
  72. package/src/engine/network/sim/ActionLog.d.ts +32 -5
  73. package/src/engine/network/sim/ActionLog.d.ts.map +1 -1
  74. package/src/engine/network/sim/ActionLog.js +47 -5
  75. package/src/engine/network/sim/SimActionExecutor.d.ts +42 -2
  76. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  77. package/src/engine/network/sim/SimActionExecutor.js +100 -4
  78. package/src/engine/network/sim/Snapshotter.d.ts +12 -0
  79. package/src/engine/network/sim/Snapshotter.d.ts.map +1 -1
  80. package/src/engine/network/sim/Snapshotter.js +43 -0
  81. package/src/engine/network/state/Baseline.d.ts +1 -1
  82. package/src/engine/network/state/Baseline.js +1 -1
  83. package/src/engine/network/state/FrameBufferRing.d.ts +25 -6
  84. package/src/engine/network/state/FrameBufferRing.d.ts.map +1 -1
  85. package/src/engine/network/state/FrameBufferRing.js +51 -6
  86. package/src/engine/network/state/InputRing.d.ts +4 -0
  87. package/src/engine/network/state/InputRing.d.ts.map +1 -1
  88. package/src/engine/network/state/InputRing.js +7 -0
  89. package/src/engine/network/transport/DeferredTransport.d.ts.map +1 -1
  90. package/src/engine/network/transport/DeferredTransport.js +1 -0
  91. package/src/engine/network/transport/LoopbackTransport.d.ts.map +1 -1
  92. package/src/engine/network/transport/LoopbackTransport.js +4 -2
  93. package/src/engine/network/transport/Transport.d.ts +7 -0
  94. package/src/engine/network/transport/Transport.d.ts.map +1 -1
  95. package/src/engine/network/transport/Transport.js +8 -0
  96. package/src/engine/network/transport/adapters/NodeUDPTransport.d.ts.map +1 -1
  97. package/src/engine/network/transport/adapters/NodeUDPTransport.js +20 -5
  98. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.d.ts.map +1 -1
  99. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +8 -0
  100. package/src/engine/network/transport/adapters/WebTransportTransport.d.ts.map +1 -1
  101. package/src/engine/network/transport/adapters/WebTransportTransport.js +6 -0
  102. package/src/engine/network/transport/connection/Connection.d.ts +191 -0
  103. package/src/engine/network/transport/connection/Connection.d.ts.map +1 -0
  104. package/src/engine/network/transport/connection/Connection.js +1262 -0
  105. package/src/engine/network/transport/connection/RangeSet.d.ts +94 -0
  106. package/src/engine/network/transport/connection/RangeSet.d.ts.map +1 -0
  107. package/src/engine/network/transport/connection/RangeSet.js +260 -0
  108. package/src/engine/network/transport/connection/RxStream.d.ts +48 -0
  109. package/src/engine/network/transport/connection/RxStream.d.ts.map +1 -0
  110. package/src/engine/network/transport/connection/RxStream.js +211 -0
  111. package/src/engine/network/transport/connection/TxStream.d.ts +90 -0
  112. package/src/engine/network/transport/connection/TxStream.d.ts.map +1 -0
  113. package/src/engine/network/transport/connection/TxStream.js +243 -0
  114. package/src/engine/network/transport/connection/bytes_copy.d.ts +17 -0
  115. package/src/engine/network/transport/connection/bytes_copy.d.ts.map +1 -0
  116. package/src/engine/network/transport/connection/bytes_copy.js +34 -0
  117. package/src/engine/network/transport/connection/varint.d.ts +46 -0
  118. package/src/engine/network/transport/connection/varint.d.ts.map +1 -0
  119. package/src/engine/network/transport/connection/varint.js +107 -0
  120. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  121. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts +38 -7
  122. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts.map +1 -1
  123. package/src/engine/sound/ecs/audio/AudioEmitter.js +35 -7
  124. package/src/engine/sound/ecs/audio/AudioEmitterSerializationAdapter.d.ts.map +1 -1
  125. package/src/engine/sound/ecs/audio/AudioEmitterSerializationAdapter.js +5 -1
  126. package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.d.ts +18 -0
  127. package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.d.ts.map +1 -0
  128. package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.js +48 -0
  129. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts +12 -2
  130. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts.map +1 -1
  131. package/src/engine/sound/ecs/audio/AudioEmitterSystem.js +173 -9
  132. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts +9 -3
  133. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts.map +1 -1
  134. package/src/engine/sound/ecs/audio/LiveEmitterSet.js +28 -8
  135. package/src/engine/sound/ecs/trigger/AudioEventTrigger.d.ts +8 -0
  136. package/src/engine/sound/ecs/trigger/AudioEventTrigger.d.ts.map +1 -1
  137. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationAdapter.d.ts.map +1 -1
  138. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationAdapter.js +5 -1
  139. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.d.ts +18 -0
  140. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.d.ts.map +1 -0
  141. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.js +51 -0
  142. package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.d.ts.map +1 -1
  143. package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.js +15 -1
  144. package/src/engine/sound/sopra/README.md +768 -644
  145. package/src/engine/sound/sopra/SopraEngine.d.ts +104 -8
  146. package/src/engine/sound/sopra/SopraEngine.d.ts.map +1 -1
  147. package/src/engine/sound/sopra/SopraEngine.js +327 -12
  148. package/src/engine/sound/sopra/definition/EventDescription.d.ts +28 -2
  149. package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -1
  150. package/src/engine/sound/sopra/definition/EventDescription.js +55 -5
  151. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts +10 -0
  152. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts.map +1 -1
  153. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +77 -55
  154. package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.d.ts +31 -0
  155. package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.d.ts.map +1 -0
  156. package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.js +75 -0
  157. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts +38 -9
  158. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts.map +1 -1
  159. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +34 -5
  160. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts +7 -2
  161. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts.map +1 -1
  162. package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +137 -122
  163. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts +3 -1
  164. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts.map +1 -1
  165. package/src/engine/sound/sopra/definition/effect/EqEffect.js +146 -131
  166. package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts +1 -0
  167. package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts.map +1 -1
  168. package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +6 -1
  169. package/src/engine/sound/sopra/runtime/BusGraph.d.ts +44 -2
  170. package/src/engine/sound/sopra/runtime/BusGraph.d.ts.map +1 -1
  171. package/src/engine/sound/sopra/runtime/BusGraph.js +83 -43
  172. package/src/engine/sound/sopra/runtime/EffectChain.d.ts +96 -0
  173. package/src/engine/sound/sopra/runtime/EffectChain.d.ts.map +1 -0
  174. package/src/engine/sound/sopra/runtime/EffectChain.js +286 -0
  175. package/src/engine/sound/sopra/runtime/EffectParamOverrides.d.ts +123 -0
  176. package/src/engine/sound/sopra/runtime/EffectParamOverrides.d.ts.map +1 -0
  177. package/src/engine/sound/sopra/runtime/EffectParamOverrides.js +320 -0
  178. package/src/engine/sound/sopra/runtime/EventInstance.d.ts +55 -5
  179. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
  180. package/src/engine/sound/sopra/runtime/EventInstance.js +201 -26
  181. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts +2 -1
  182. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts.map +1 -1
  183. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +6 -1
  184. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts +15 -0
  185. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts.map +1 -1
  186. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +32 -0
  187. package/src/engine/sound/sopra/util/MockAudioContext.d.ts.map +1 -1
  188. package/src/engine/sound/sopra/util/MockAudioContext.js +3 -0
  189. package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts +13 -3
  190. package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts.map +1 -1
  191. package/src/engine/sound/sopra/util/fadeOutAndStop.js +25 -13
  192. package/src/shade/RENDERER_CONTRACT.md +6 -3
  193. package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts +24 -0
  194. package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts.map +1 -0
  195. package/src/shade/device/SHADE_DEVICE_FLOOR.js +34 -0
  196. package/src/shade/device/ShadeDeviceFailure.d.ts +12 -5
  197. package/src/shade/device/ShadeDeviceFailure.d.ts.map +1 -1
  198. package/src/shade/device/ShadeDeviceFailure.js +17 -8
  199. package/src/shade/device/ShadeDeviceFailureReason.d.ts +1 -1
  200. package/src/shade/device/ShadeDeviceFailureReason.js +2 -2
  201. package/src/shade/device/shade_device_floor_unmet.d.ts +13 -0
  202. package/src/shade/device/shade_device_floor_unmet.d.ts.map +1 -0
  203. package/src/shade/device/shade_device_floor_unmet.js +32 -0
  204. package/src/shade/renderer/Renderer.d.ts +2 -0
  205. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  206. package/src/shade/renderer/Renderer.js +29 -55
  207. package/src/shade/renderer/buffer/GPUBufferAllocator.d.ts.map +1 -1
  208. package/src/shade/renderer/buffer/GPUBufferAllocator.js +9 -0
  209. package/src/shade/renderer/buffer/buffer_pool_ops.d.ts +21 -12
  210. package/src/shade/renderer/buffer/buffer_pool_ops.d.ts.map +1 -1
  211. package/src/shade/renderer/buffer/buffer_pool_ops.js +18 -19
  212. package/src/shade/renderer/gpu_primitive/test/gpu_test.d.ts.map +1 -1
  213. package/src/shade/renderer/gpu_primitive/test/gpu_test.js +8 -11
  214. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  215. package/src/shade/renderer/pool/TransientResourcePool.d.ts +24 -0
  216. package/src/shade/renderer/pool/TransientResourcePool.d.ts.map +1 -1
  217. package/src/shade/renderer/pool/TransientResourcePool.js +41 -10
  218. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  219. package/src/shade/renderer/shader/ComputeShader.js +18 -2
  220. package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
  221. package/src/shade/renderer/shader/ImageShader.js +230 -218
  222. package/src/view/graphics/GraphicsContextFailureView.d.ts +1 -2
  223. package/src/view/graphics/GraphicsContextFailureView.d.ts.map +1 -1
  224. package/src/view/graphics/GraphicsContextFailureView.js +1 -2
  225. package/src/engine/network/transport/Channel.js +0 -336
  226. package/src/engine/network/transport/ReliableCommandPipeline.js +0 -335
  227. package/src/engine/network/transport/fragments/FragmentAssembler.js +0 -350
  228. package/src/engine/network/transport/fragments/FragmentRetention.js +0 -191
  229. package/src/engine/network/transport/fragments/fragment_send.js +0 -157
  230. package/src/engine/network/transport/fragments/packet_size.js +0 -107
@@ -0,0 +1,172 @@
1
+ import { assert } from "../../../assert.js";
2
+
3
+ /**
4
+ * @param {number} length
5
+ * @returns {number} what normalises a vector of that length: `1 / length`, or 1 for a zero vector, which
6
+ * leaves it as it is
7
+ */
8
+ function inverse_or_one(length) {
9
+ return length === 0 ? 1 : 1 / length;
10
+ }
11
+
12
+ /**
13
+ * The rotation that points local +Z along `forward`, with local +Y turned as close to `up` as it can be:
14
+ * the orientation of a camera, a turret or a walking body told where to face.
15
+ *
16
+ * Neither vector has to be unit length, within what their squares can hold: lanes from about 1e-154
17
+ * to 1e154. Below that a square is 0 and the vector reads as zero, above it Infinity. The frame is built
18
+ * from them the usual way — `right = up × forward` and `up' = forward × right`, each normalised — and the
19
+ * rotation is read off that matrix, so it maps +X to `right`, +Y to `up'` and +Z to `forward`.
20
+ *
21
+ * **When `up` is parallel to `forward` there is no frame to build**: their cross product is the zero
22
+ * vector, and any roll about `forward` would do. The forward direction is then nudged by 0.001 along X
23
+ * when `up` is ±Z, and along Z otherwise, and renormalised. For a unit `up` the answer is then a unit
24
+ * rotation within about a milliradian of `forward`, rolled however the nudge leaves it; do not rely on
25
+ * the roll there. The ±Z test reads `|uz| === 1`, so a longer `up` along Z is nudged along Z, stays
26
+ * parallel, and gets a rotation that is not unit length. Pass a unit `up` where it can be parallel.
27
+ *
28
+ * Sign convention: `(x, y, z, w)` — `w` last, matching {@link Quaternion} and the rest of the
29
+ * `core/geom/3d/quaternion/` family.
30
+ *
31
+ * Everything is worked in locals and only the result is written, so it allocates nothing, and a caller
32
+ * that hands its own parameters straight on boxes nothing either. {@link Quaternion#_lookRotation} and
33
+ * `t64_look_rotation` both answer through this.
34
+ *
35
+ * @param {number[]|Float32Array|Float64Array} out
36
+ * @param {number} out_offset offset into `out`; receives 4 floats (x, y, z, w)
37
+ * @param {number} fx forward, any length
38
+ * @param {number} fy
39
+ * @param {number} fz
40
+ * @param {number} ux up, any length
41
+ * @param {number} uy
42
+ * @param {number} uz
43
+ *
44
+ * @author Alex Goldring
45
+ * @copyright Company Named Limited (c) 2026
46
+ */
47
+ export function quat3_look_rotation(out, out_offset, fx, fy, fz, ux, uy, uz) {
48
+ assert.isFinite(fx, 'fx');
49
+ assert.isFinite(fy, 'fy');
50
+ assert.isFinite(fz, 'fz');
51
+ assert.isFinite(ux, 'ux');
52
+ assert.isFinite(uy, 'uy');
53
+ assert.isFinite(uz, 'uz');
54
+
55
+ /*
56
+ Forward, normalised; a zero vector is left as it is.
57
+
58
+ Every normalisation here scales unconditionally, by 1 for a zero vector, which leaves each lane as it
59
+ was bit for bit. Written as `if (length !== 0) { ax *= 1 / length; }` it merged a computed number
60
+ with the incoming argument, and V8 then held `ax` as a boxed number: 32 B a call.
61
+ */
62
+ let scale = inverse_or_one(Math.sqrt(fx * fx + fy * fy + fz * fz));
63
+
64
+ let ax = fx * scale;
65
+ let ay = fy * scale;
66
+ let az = fz * scale;
67
+
68
+ // right = up × forward
69
+ let cx = uy * az - uz * ay;
70
+ let cy = uz * ax - ux * az;
71
+ let cz = ux * ay - uy * ax;
72
+
73
+ if (cx * cx + cy * cy + cz * cz === 0) {
74
+ // up and forward are parallel; adjust forward slightly, as three.js does
75
+ // https://github.com/mrdoob/three.js/blob/88e8954b69377dad4ad1ceaf1a383f3536e88e5a/src/math/Matrix4.js#L304
76
+
77
+ if (Math.abs(uz) === 1) {
78
+ ax += 0.001;
79
+ } else {
80
+ az += 0.001;
81
+ }
82
+
83
+ scale = inverse_or_one(Math.sqrt(ax * ax + ay * ay + az * az));
84
+
85
+ ax *= scale;
86
+ ay *= scale;
87
+ az *= scale;
88
+
89
+ cx = uy * az - uz * ay;
90
+ cy = uz * ax - ux * az;
91
+ cz = ux * ay - uy * ax;
92
+ }
93
+
94
+ scale = inverse_or_one(Math.sqrt(cx * cx + cy * cy + cz * cz));
95
+
96
+ cx *= scale;
97
+ cy *= scale;
98
+ cz *= scale;
99
+
100
+ // up' = forward × right
101
+ const bx = ay * cz - az * cy;
102
+ const by = az * cx - ax * cz;
103
+ const bz = ax * cy - ay * cx;
104
+
105
+ // the rotation of the matrix whose columns are right, up' and forward
106
+ const m11 = cx, m12 = bx, m13 = ax;
107
+ const m21 = cy, m22 = by, m23 = ay;
108
+ const m31 = cz, m32 = bz, m33 = az;
109
+
110
+ const trace = m11 + m22 + m33;
111
+
112
+ let x, y, z, w, s;
113
+
114
+ if (trace > 0) {
115
+
116
+ s = Math.sqrt(trace + 1.0);
117
+
118
+ w = 0.5 * s;
119
+
120
+ s = 0.5 / s;
121
+
122
+ x = (m32 - m23) * s;
123
+ y = (m13 - m31) * s;
124
+ z = (m21 - m12) * s;
125
+
126
+ } else if (m11 > m22 && m11 > m33) {
127
+
128
+ s = Math.sqrt(1.0 + m11 - m22 - m33);
129
+
130
+ x = 0.5 * s;
131
+
132
+ s = 0.5 / s;
133
+
134
+ w = (m32 - m23) * s;
135
+ y = (m12 + m21) * s;
136
+ z = (m13 + m31) * s;
137
+
138
+ } else if (m22 > m33) {
139
+
140
+ s = Math.sqrt(1.0 + m22 - m11 - m33);
141
+
142
+ y = 0.5 * s;
143
+
144
+ s = 0.5 / s;
145
+
146
+ w = (m13 - m31) * s;
147
+ x = (m12 + m21) * s;
148
+ z = (m23 + m32) * s;
149
+
150
+ } else {
151
+
152
+ s = Math.sqrt(1.0 + m33 - m11 - m22);
153
+
154
+ z = 0.5 * s;
155
+
156
+ s = 0.5 / s;
157
+
158
+ w = (m21 - m12) * s;
159
+ x = (m13 + m31) * s;
160
+ y = (m23 + m32) * s;
161
+
162
+ }
163
+
164
+ // Finite inputs can still come out NaN, when a square or a cross product overflows. One check of one
165
+ // boolean, so a build keeping assertions boxes nothing for it.
166
+ assert.ok(x === x && y === y && z === z && w === w, 'look rotation is NaN: forward or up is too large for its square');
167
+
168
+ out[out_offset] = x;
169
+ out[out_offset + 1] = y;
170
+ out[out_offset + 2] = z;
171
+ out[out_offset + 3] = w;
172
+ }
@@ -125,6 +125,7 @@ export class Quaternion extends Float64Array implements Iterable<number> {
125
125
  * @param {number} uy up vector
126
126
  * @param {number} uz up vector
127
127
  * @returns {this}
128
+ * @see quat3_look_rotation the arithmetic, which this hands its arguments to unchanged
128
129
  */
129
130
  _lookRotation(fx: number, fy: number, fz: number, ux: number, uy: number, uz: number): this;
130
131
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Quaternion.d.ts","sourceRoot":"","sources":["../../../../src/core/geom/Quaternion.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Quaternion.d.ts","sourceRoot":"","sources":["../../../../src/core/geom/Quaternion.js"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ import { epsilonEquals } from "../math/epsilonEquals.js";
8
8
  import { lerp } from "../math/lerp.js";
9
9
  import { PI2 } from "../math/PI2.js";
10
10
  import { computeHashFloat } from "../primitives/numbers/computeHashFloat.js";
11
+ import { quat3_look_rotation } from "./3d/quaternion/quat3_look_rotation.js";
11
12
  import { v3_dot } from "./vec3/v3_dot.js";
12
13
  import { v4_length } from "./vec4/v4_length.js";
13
14
  import Vector3 from "./Vector3.js";
@@ -17,8 +18,13 @@ import Vector3 from "./Vector3.js";
17
18
  */
18
19
 
19
20
  const scratch_v3_a = new Vector3();
20
- const scratch_v3_b = new Vector3();
21
- const scratch_v3_c = new Vector3();
21
+
22
+ /**
23
+ * Where {@link Quaternion#_lookRotation} has its answer worked out before setting it.
24
+ *
25
+ * @type {Float64Array}
26
+ */
27
+ const scratch_rotation = new Float64Array(4);
22
28
 
23
29
  const sin = Math.sin;
24
30
  const cos = Math.cos;
@@ -158,58 +164,16 @@ export class Quaternion extends Float64Array {
158
164
  * @param {number} uy up vector
159
165
  * @param {number} uz up vector
160
166
  * @returns {this}
167
+ * @see quat3_look_rotation the arithmetic, which this hands its arguments to unchanged
161
168
  */
162
169
  _lookRotation(
163
170
  fx, fy, fz,
164
171
  ux, uy, uz
165
172
  ) {
173
+ quat3_look_rotation(scratch_rotation, 0, fx, fy, fz, ux, uy, uz);
166
174
 
167
- scratch_v3_a.set(fx, fy, fz);
168
- scratch_v3_a.normalize();
169
-
170
- scratch_v3_c._crossVectors(ux, uy, uz, scratch_v3_a.x, scratch_v3_a.y, scratch_v3_a.z);
171
-
172
- if (scratch_v3_c.lengthSq() === 0) {
173
- // up and forward are parallel
174
-
175
- /*
176
- adjust forward direction slightly
177
- code take from : https://github.com/mrdoob/three.js/blob/88e8954b69377dad4ad1ceaf1a383f3536e88e5a/src/math/Matrix4.js#L304
178
- */
179
-
180
- if (Math.abs(uz) === 1) {
181
- scratch_v3_a.x += 0.001;
182
- } else {
183
- scratch_v3_a.z += 0.001;
184
- }
185
-
186
- scratch_v3_a.normalize();
187
- scratch_v3_c._crossVectors(ux, uy, uz, scratch_v3_a.x, scratch_v3_a.y, scratch_v3_a.z);
188
-
189
- }
190
-
191
- scratch_v3_c.normalize();
192
-
193
- scratch_v3_b.crossVectors(scratch_v3_a, scratch_v3_c);
194
-
195
- // construct partial transform matrix
196
- const m00 = scratch_v3_c.x;
197
- const m10 = scratch_v3_c.y;
198
- const m20 = scratch_v3_c.z;
199
-
200
- const m01 = scratch_v3_b.x;
201
- const m11 = scratch_v3_b.y;
202
- const m21 = scratch_v3_b.z;
203
-
204
- const m02 = scratch_v3_a.x;
205
- const m12 = scratch_v3_a.y;
206
- const m22 = scratch_v3_a.z;
207
-
208
- return this.__setFromRotationMatrix(
209
- m00, m01, m02,
210
- m10, m11, m12,
211
- m20, m21, m22
212
- );
175
+ // through set(), so the change is announced as any other write is
176
+ return this.set(scratch_rotation[0], scratch_rotation[1], scratch_rotation[2], scratch_rotation[3]);
213
177
  }
214
178
 
215
179
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../../src/engine/Engine.js"],"names":[],"mappings":";6BAqCa,OAAO,8BAA8B,EAAE,cAAc;AAwClE;IA4FI;;;;;;;;;OASG;IACH,sBARW,cAAc;QAEU,aAAa,GAArC,aAAa;QACK,cAAc,GAAhC,OAAO;QACW,WAAW,GAA7B,OAAO;QACW,KAAK,GAAvB,OAAO;OAiPjB;IAtSD;;;OAGG;IACH,UAFU,cAAc,GAAC,IAAI,CAEb;IAEhB;;;OAGG;IACH,OAFU,WAAW,GAAC,IAAI,CAEb;IAEb,qBAA4B;IAE5B;;;;;;;;;OASG;IACH,0BAFU,uBAAuB,CAEe;IAEhD;;;OAGG;IACH,kBAFU,mBAAmB,CAEO;IAEpC;;;;OAIG;IACH,iBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,mBAFU,kBAAkB,CAEa;IAoBrC;;;OAGG;IACH,UAFU,cAAc,CAEA;IAKxB;;;OAGG;IACH,aAFU,gBAAgB,CAEe;IAGzC,yCAAkE;IAK9D,6BAAkC;IAMtC;;;OAGG;IACH,cAFU,aAAa,MAAM,CAAC,CAK5B;IAEF,8CAiCE;IAgCF;;;OAGG;IACH,SAFU,WAAW,CAEoB;IAEzC;;;OAGG;IACH,oCAA0C;IAE1C;;;OAGG;IACH,sCAFU,2BAA2B,CAE+B;IAEpE,yBAAoC;IAGpC;;OAEG;IACH,aAAkB;IAElB;;;OAGG;IACH,SAFU,OAAO,CAEwB;IAGzC,2BAAsC;IAuCtC;;;OAGG;IACH,KAFU,SAAS,CAEO;IAE1B;;;OAGG;IACH,uBAFU,YAAY,CAEqD;IAI3E;;;;;MAKC;IA8BD;;;OAGG;IACH,kBAFU,OAAO,CAEW;IAwIhC,wBAgCC;IApBG,oBAAwB;IAsB5B,2BA8CC;IAED,oBAiBC;IAED;;;OAGG;IACH,+CAUC;IAED,eAkDC;IAED;;;OAGG;IACH,sBA0GC;IAoBD;;OAEG;IACH,sBA+DC;IAED,aAEC;IAED;;OAEG;IACH,4BAOC;IAIL;;;OAGG;IACH,mBAFU,OAAO,CAEQ;;CAPxB;+BA94B8B,+BAA+B;wBAWtC,wBAAwB;0BArBtB,0CAA0C;wCAeN,iDAAiD;oCAG3E,iCAAiC;mBAElD,wBAAwB;+BAtBZ,gDAAgD;iCAO9C,+CAA+C;8BAGlD,wBAAwB;6BALzB,yBAAyB;uCAIf,6DAA6D;4BAUxE,0BAA0B;+BArBvB,iCAAiC;4CAapB,qDAAqD;AAgBjG;;GAEG;AAGH;IACI,gDAA2D;IAC3D,0BAAkC;IAClC,iCAAyC;CAC5C;6BAvC4B,sCAAsC;sBA4B7C,mBAAmB;yBAJhB,yBAAyB;8BALpB,kCAAkC;2BADrC,mCAAmC;8BAFhC,kCAAkC;8BAClC,kCAAkC;sBAb1C,+BAA+B;+BAKtB,qCAAqC;4BAPxC,kCAAkC;oBAH1C,yBAAyB"}
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../../src/engine/Engine.js"],"names":[],"mappings":";6BAqCa,OAAO,8BAA8B,EAAE,cAAc;AAwClE;IA4FI;;;;;;;;;OASG;IACH,sBARW,cAAc;QAEU,aAAa,GAArC,aAAa;QACK,cAAc,GAAhC,OAAO;QACW,WAAW,GAA7B,OAAO;QACW,KAAK,GAAvB,OAAO;OAiPjB;IAtSD;;;OAGG;IACH,UAFU,cAAc,GAAC,IAAI,CAEb;IAEhB;;;OAGG;IACH,OAFU,WAAW,GAAC,IAAI,CAEb;IAEb,qBAA4B;IAE5B;;;;;;;;;OASG;IACH,0BAFU,uBAAuB,CAEe;IAEhD;;;OAGG;IACH,kBAFU,mBAAmB,CAEO;IAEpC;;;;OAIG;IACH,iBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,mBAFU,kBAAkB,CAEa;IAoBrC;;;OAGG;IACH,UAFU,cAAc,CAEA;IAKxB;;;OAGG;IACH,aAFU,gBAAgB,CAEe;IAGzC,yCAAkE;IAK9D,6BAAkC;IAMtC;;;OAGG;IACH,cAFU,aAAa,MAAM,CAAC,CAK5B;IAEF,8CAiCE;IAgCF;;;OAGG;IACH,SAFU,WAAW,CAEoB;IAEzC;;;OAGG;IACH,oCAA0C;IAE1C;;;OAGG;IACH,sCAFU,2BAA2B,CAE+B;IAEpE,yBAAoC;IAGpC;;OAEG;IACH,aAAkB;IAElB;;;OAGG;IACH,SAFU,OAAO,CAEwB;IAGzC,2BAAsC;IAuCtC;;;OAGG;IACH,KAFU,SAAS,CAEO;IAE1B;;;OAGG;IACH,uBAFU,YAAY,CAEqD;IAI3E;;;;;MAKC;IA8BD;;;OAGG;IACH,kBAFU,OAAO,CAEW;IA6IhC,wBAgCC;IApBG,oBAAwB;IAsB5B,2BA8CC;IAED,oBAiBC;IAED;;;OAGG;IACH,+CAUC;IAED,eAkDC;IAED;;;OAGG;IACH,sBA0GC;IAoBD;;OAEG;IACH,sBA+DC;IAED,aAEC;IAED;;OAEG;IACH,4BAOC;IAIL;;;OAGG;IACH,mBAFU,OAAO,CAEQ;;CAPxB;+BAn5B8B,+BAA+B;wBAWtC,wBAAwB;0BArBtB,0CAA0C;wCAeN,iDAAiD;oCAG3E,iCAAiC;mBAElD,wBAAwB;+BAtBZ,gDAAgD;iCAO9C,+CAA+C;8BAGlD,wBAAwB;6BALzB,yBAAyB;uCAIf,6DAA6D;4BAUxE,0BAA0B;+BArBvB,iCAAiC;4CAapB,qDAAqD;AAgBjG;;GAEG;AAGH;IACI,gDAA2D;IAC3D,0BAAkC;IAClC,iCAAyC;CAC5C;6BAvC4B,sCAAsC;sBA4B7C,mBAAmB;yBAJhB,yBAAyB;8BALpB,kCAAkC;2BADrC,mCAAmC;8BAFhC,kCAAkC;8BAClC,kCAAkC;sBAb1C,+BAA+B;+BAKtB,qCAAqC;4BAPxC,kCAAkC;oBAH1C,yBAAyB"}
@@ -477,10 +477,12 @@ class Engine {
477
477
  }
478
478
 
479
479
  /**
480
- * @param {ShadeDeviceFailure} reason carries a message written to be shown to a person
480
+ * There is no usable device, so there will be no rendering at all.
481
+ *
482
+ * @param {ShadeDeviceFailure} failure carries a message written to be shown to a person
481
483
  */
482
- #handle_context_failed(reason) {
483
- logger.error(`Graphics context recovery abandoned (${reason}), no further rendering is possible`);
484
+ #handle_context_failed(failure) {
485
+ logger.error(`Graphics could not start (${failure}), no rendering is possible`);
484
486
 
485
487
  this.#clear_context_loss_pause_timer();
486
488
 
@@ -488,7 +490,10 @@ class Engine {
488
490
  // Application state is left intact, which keeps a save-on-failure handler viable.
489
491
  this.#pause_simulation_for_context_loss();
490
492
 
491
- this.viewStack.addChild(new GraphicsContextFailureView());
493
+ this.viewStack.addChild(new GraphicsContextFailureView({
494
+ title: 'Graphics unavailable',
495
+ text: failure.message,
496
+ }));
492
497
  }
493
498
 
494
499
  #initialize_audio() {
@@ -1 +1 @@
1
- {"version":3,"file":"populateEngineSerializationRegistry.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/storage/populateEngineSerializationRegistry.js"],"names":[],"mappings":"AAwLA;;;;;;;;GAQG;AACH,iGAiHC"}
1
+ {"version":3,"file":"populateEngineSerializationRegistry.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/storage/populateEngineSerializationRegistry.js"],"names":[],"mappings":"AA8LA;;;;;;;;GAQG;AACH,iGAqHC"}
@@ -172,6 +172,12 @@ import {
172
172
  import { SoundControllerSerializationAdapter } from "../../sound/sopra/legacy/SoundController.js";
173
173
  import { SoundListenerSerializationAdapter } from "../../sound/ecs/SoundListener.js";
174
174
  import { AudioEmitterSerializationAdapter } from "../../sound/ecs/audio/AudioEmitterSerializationAdapter.js";
175
+ import { AudioEmitterSerializationUpgrader_0_1 } from "../../sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.js";
176
+ import { AudioEmitter } from "../../sound/ecs/audio/AudioEmitter.js";
177
+ import {
178
+ AudioEventTriggerSerializationUpgrader_0_1
179
+ } from "../../sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.js";
180
+ import { AudioEventTrigger } from "../../sound/ecs/trigger/AudioEventTrigger.js";
175
181
  import {
176
182
  AudioEventTriggerSerializationAdapter
177
183
  } from "../../sound/ecs/trigger/AudioEventTriggerSerializationAdapter.js";
@@ -300,6 +306,10 @@ export function populateEngineSerializationRegistry(registry) {
300
306
  registry.registerUpgrader(SoundEmitter.typeName, new SoundEmitterSerializationUpgrader_0_1());
301
307
  registry.registerUpgrader(SoundEmitter.typeName, new SoundEmitterSerializationUpgrader_1_2());
302
308
 
309
+ // both embed an EventDescription record, so they take a registry to read its clip tree
310
+ registry.registerUpgrader(AudioEmitter.typeName, new AudioEmitterSerializationUpgrader_0_1(registry));
311
+ registry.registerUpgrader(AudioEventTrigger.typeName, new AudioEventTriggerSerializationUpgrader_0_1(registry));
312
+
303
313
  registry.registerUpgrader(TopDownCameraController.typeName, new TopDownCameraControllerSerializationUpgrader_0_1());
304
314
 
305
315
  registry.registerUpgrader(ClingToTerrain.typeName, new ClingToTerrainSerializationUpgrader_0_1());
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Orient a {@link Transform64} so its local +Z axis points along `(fx, fy, fz)`.
3
3
  *
4
- * The {@link Transform64} counterpart of `Quaternion._lookRotation`, and it defers to exactly that
5
- * — the interesting part of the computation is the case where `up` and the forward direction are
6
- * parallel, and there is no reason for a second copy of it to exist. `Quaternion` is itself f64, so
7
- * routing through one costs no precision.
4
+ * The {@link Transform64} counterpart of `Quaternion._lookRotation`; both are
5
+ * {@link quat3_look_rotation}, which also says what happens when `up` and the forward direction are
6
+ * parallel. This writes the rotation lanes in place and hands its arguments on unchanged, so it
7
+ * allocates nothing — it runs once per body per frame in a game that faces a crowd where it walks.
8
8
  *
9
9
  * Nothing here is normalized on the way in, and nothing touches `t64`'s matrix on the way out —
10
10
  * call {@link Transform64.updateMatrix} once you are done setting components.
@@ -1 +1 @@
1
- {"version":3,"file":"t64_look_rotation.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/transform/t64_look_rotation.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wDAPW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAWhB"}
1
+ {"version":3,"file":"t64_look_rotation.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/transform/t64_look_rotation.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wDAPW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAIhB"}
@@ -1,17 +1,13 @@
1
- import { Quaternion } from "../../../core/geom/Quaternion.js";
2
-
3
- /**
4
- * @type {Quaternion}
5
- */
6
- const SCRATCH_ROTATION = new Quaternion();
1
+ import { quat3_look_rotation } from "../../../core/geom/3d/quaternion/quat3_look_rotation.js";
2
+ import { TRANSFORM64_ROTATION_OFFSET } from "./Transform64.js";
7
3
 
8
4
  /**
9
5
  * Orient a {@link Transform64} so its local +Z axis points along `(fx, fy, fz)`.
10
6
  *
11
- * The {@link Transform64} counterpart of `Quaternion._lookRotation`, and it defers to exactly that
12
- * — the interesting part of the computation is the case where `up` and the forward direction are
13
- * parallel, and there is no reason for a second copy of it to exist. `Quaternion` is itself f64, so
14
- * routing through one costs no precision.
7
+ * The {@link Transform64} counterpart of `Quaternion._lookRotation`; both are
8
+ * {@link quat3_look_rotation}, which also says what happens when `up` and the forward direction are
9
+ * parallel. This writes the rotation lanes in place and hands its arguments on unchanged, so it
10
+ * allocates nothing — it runs once per body per frame in a game that faces a crowd where it walks.
15
11
  *
16
12
  * Nothing here is normalized on the way in, and nothing touches `t64`'s matrix on the way out —
17
13
  * call {@link Transform64.updateMatrix} once you are done setting components.
@@ -25,12 +21,5 @@ const SCRATCH_ROTATION = new Quaternion();
25
21
  * @param {number} uz up
26
22
  */
27
23
  export function t64_look_rotation(t64, fx, fy, fz, ux, uy, uz) {
28
- SCRATCH_ROTATION._lookRotation(fx, fy, fz, ux, uy, uz);
29
-
30
- t64.setRotation(
31
- SCRATCH_ROTATION[0],
32
- SCRATCH_ROTATION[1],
33
- SCRATCH_ROTATION[2],
34
- SCRATCH_ROTATION[3]
35
- );
24
+ quat3_look_rotation(t64, TRANSFORM64_ROTATION_OFFSET, fx, fy, fz, ux, uy, uz);
36
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TopDownCameraControllerSystem.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js"],"names":[],"mappings":"AAwDA;;;;GAIG;AACH,iDAHW,uBAAuB,UACvB,WAAW,QA0BrB;AAED;;;;;GAKG;AACH,4DAJW,WAAW,cACX,uBAAuB,aACvB,MAAM,QAahB;;oCA/F+D,8BAA8B;4BAHlE,0CAA0C;AAWtE;;IACI,gCAAkC;IAClC,iDAAyC;IACzC,mEAEE;IAEF;;;;;OAKG;IACH,8BAQC;IAED,6BAaC;CACJ;uBAjDsB,2BAA2B;0BAHxB,4CAA4C;4CAE1B,0DAA0D"}
1
+ {"version":3,"file":"TopDownCameraControllerSystem.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js"],"names":[],"mappings":"AAqFA;;;;GAIG;AACH,iDAHW,uBAAuB,UACvB,WAAW,QA0BrB;AAED;;;;;GAKG;AACH,4DAJW,WAAW,cACX,uBAAuB,aACvB,MAAM,QAahB;;oCA1H+D,8BAA8B;4BAHlE,0CAA0C;AAoBtE;;IACI,gCAAkC;IAClC,iDAAyC;IACzC,mEAEE;IAEF;;;;;OAKG;IACH,8BA0BC;IAED,6BAaC;CACJ;uBA9EsB,2BAA2B;0BAHxB,4CAA4C;4CAE1B,0DAA0D"}
@@ -4,6 +4,8 @@ import ObservedValue from "../../../../../core/model/ObservedValue.js";
4
4
  import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
5
5
  import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
6
6
  import { System } from '../../../../ecs/System.js';
7
+ import { t64_announce_change } from "../../../../ecs/transform/t64_announce_change.js";
8
+ import { t64_read_pose_array } from "../../../../ecs/transform/t64_read_pose_array.js";
7
9
  import { Transform64 } from '../../../../ecs/transform/Transform64.js';
8
10
 
9
11
 
@@ -15,6 +17,15 @@ import { v3_quaternion_apply } from "../../../../../core/geom/vec3/v3_quaternion
15
17
  const v3_scratch = new Vector3();
16
18
  const q_scratch = new Quaternion();
17
19
 
20
+ /**
21
+ * A camera's translation and rotation before and after its controller rewrites them, to tell a move from
22
+ * a rewrite of the same pose.
23
+ * @type {Float64Array}
24
+ */
25
+ const POSE_BEFORE = new Float64Array(7);
26
+ /** @type {Float64Array} */
27
+ const POSE_AFTER = new Float64Array(7);
28
+
18
29
  class TopDownCameraControllerSystem extends System {
19
30
  enabled = new ObservedValue(true);
20
31
  dependencies = [TopDownCameraController];
@@ -29,13 +40,31 @@ class TopDownCameraControllerSystem extends System {
29
40
  * @private
30
41
  */
31
42
  __visit_camera_entity(ctrl, entity){
32
- const transform = this.entityManager.dataset.getComponent(entity,Transform64);
43
+ const dataset = this.entityManager.dataset;
44
+
45
+ const transform = dataset.getComponent(entity,Transform64);
33
46
 
34
47
  if(transform === undefined){
35
48
  return;
36
49
  }
37
50
 
51
+ t64_read_pose_array(POSE_BEFORE, 0, transform);
52
+
38
53
  computeTopDownTransform(ctrl,transform);
54
+
55
+ t64_read_pose_array(POSE_AFTER, 0, transform);
56
+
57
+ // A Transform64 cannot say it was written, so the writer does: this is what moves the sound
58
+ // listener, and everything else that follows the camera by its transform. The pose is rewritten
59
+ // every frame whether the controller moved or not, so it is announced only when it changed: a
60
+ // still camera wakes none of them.
61
+ for (let i = 0; i < 7; i++) {
62
+ if (POSE_BEFORE[i] !== POSE_AFTER[i]) {
63
+ t64_announce_change(dataset, entity);
64
+
65
+ return;
66
+ }
67
+ }
39
68
  }
40
69
 
41
70
  update(timeDelta) {
@@ -11,6 +11,12 @@
11
11
  * to. Layout and program are shared by reference, never copied — two entities of one effect belong
12
12
  * on one program id in the heap.
13
13
  *
14
+ * Every field is compared by name, and that is load-bearing rather than style. Through a shared
15
+ * `assign(target, field, value)` the one `target[field]` access saw all thirteen names, went
16
+ * megamorphic, and read numbers back boxed, while the call boxed the value it was handed: 228 B and
17
+ * ~120 ns per emitter per call, against nothing and ~9 ns written out like this
18
+ * (`GPUParticleEmitterSystem.allocation.spec.js`). This runs for every live emitter twice a frame.
19
+ *
14
20
  * @param {ParticleEmitter} emitter
15
21
  * @param {ParticleEffect} effect
16
22
  * @returns {boolean} whether the emitter differs from what it held before
@@ -1 +1 @@
1
- {"version":3,"file":"GPUParticleEmitterSystem.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/GPUParticleEmitterSystem.js"],"names":[],"mappings":"AAszBA;;;;;;;;;;;;;;;;GAgBG;AACH,+CAJW,eAAe,UACf,cAAc,GACZ,OAAO,CA4BnB;AAv0BD;;;;GAIG;AAEH;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH;IAoDI;;;;;OAKG;IACH,sBALW,OAAO,qBAAqB,EAAE,cAAc,SAC5C,OAAO,qCAAqC,EAAE,KAAK,gEAgB7D;IArED,6DAA6C;IAE7C;;;OAGG;IACH,OAFU,YAAY,CAEO;IAiE7B;;;;;;OAMG;IACH,iEAEC;IAED;;;;;OAKG;IACH,kCAEC;IAED;;;;;;;;;;OAUG;IACH,mBAJW,MAAM,GACJ,eAAe,GAAC,IAAI,CAWhC;IAED;;;;;;;;;;;OAWG;IACH,cAHW,MAAM,SACN,MAAM,QA4BhB;IA6BD,+BAA+B;IAC/B,YADc,QAAQ,IAAI,CAAC,CAyB1B;IAED;;;;OAIG;IACH,aAJW,cAAc,aACd,WAAW,UACX,MAAM,QAqChB;IAED;;;;OAIG;IACH,eAJW,cAAc,aACd,WAAW,UACX,MAAM,QAIhB;IAED;;;;;;;OAOG;IACH,4BAHW,MAAM,GACJ,IAAI,CAgBhB;IAoCD;;;;;;;;;;;;OAYG;IACH,eAHW,OAAO,gDAAgD,EAAE,YAAY,GACnE,IAAI,CAqChB;;CAiWJ;;;;;gBAxxBa,MAAM;;;;WACN,OAAO,yCAAyC,EAAE,UAAU,GAAC,IAAI;;;YAKjE,MAAM;;;;YACN,cAAc;;;;eACd,WAAW;;;;aACX,eAAe,GAAC,IAAI;;;;;aACpB,OAAO,+CAA+C,EAAE,eAAe,GAAC,IAAI;gCAGjE,IAAI;;;;SACf,MAAM,GAAC,IAAI;;;;aACX,oBAAoB,GAAC,IAAI;;gCAvCP,2DAA2D;+BAS5D,6CAA6C;uBAPrD,kBAAkB;4BAEb,iCAAiC;6BAMhC,2CAA2C"}
1
+ {"version":3,"file":"GPUParticleEmitterSystem.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/GPUParticleEmitterSystem.js"],"names":[],"mappings":"AAszBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,+CAJW,eAAe,UACf,cAAc,GACZ,OAAO,CAiFnB;AAl4BD;;;;GAIG;AAEH;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH;IAoDI;;;;;OAKG;IACH,sBALW,OAAO,qBAAqB,EAAE,cAAc,SAC5C,OAAO,qCAAqC,EAAE,KAAK,gEAgB7D;IArED,6DAA6C;IAE7C;;;OAGG;IACH,OAFU,YAAY,CAEO;IAiE7B;;;;;;OAMG;IACH,iEAEC;IAED;;;;;OAKG;IACH,kCAEC;IAED;;;;;;;;;;OAUG;IACH,mBAJW,MAAM,GACJ,eAAe,GAAC,IAAI,CAWhC;IAED;;;;;;;;;;;OAWG;IACH,cAHW,MAAM,SACN,MAAM,QA4BhB;IA6BD,+BAA+B;IAC/B,YADc,QAAQ,IAAI,CAAC,CAyB1B;IAED;;;;OAIG;IACH,aAJW,cAAc,aACd,WAAW,UACX,MAAM,QAqChB;IAED;;;;OAIG;IACH,eAJW,cAAc,aACd,WAAW,UACX,MAAM,QAIhB;IAED;;;;;;;OAOG;IACH,4BAHW,MAAM,GACJ,IAAI,CAgBhB;IAoCD;;;;;;;;;;;;OAYG;IACH,eAHW,OAAO,gDAAgD,EAAE,YAAY,GACnE,IAAI,CAqChB;;CAiWJ;;;;;gBAxxBa,MAAM;;;;WACN,OAAO,yCAAyC,EAAE,UAAU,GAAC,IAAI;;;YAKjE,MAAM;;;;YACN,cAAc;;;;eACd,WAAW;;;;aACX,eAAe,GAAC,IAAI;;;;;aACpB,OAAO,+CAA+C,EAAE,eAAe,GAAC,IAAI;gCAGjE,IAAI;;;;SACf,MAAM,GAAC,IAAI;;;;aACX,oBAAoB,GAAC,IAAI;;gCAvCP,2DAA2D;+BAS5D,6CAA6C;uBAPrD,kBAAkB;4BAEb,iCAAiC;6BAMhC,2CAA2C"}
@@ -833,6 +833,12 @@ export class GPUParticleEmitterSystem extends System {
833
833
  * to. Layout and program are shared by reference, never copied — two entities of one effect belong
834
834
  * on one program id in the heap.
835
835
  *
836
+ * Every field is compared by name, and that is load-bearing rather than style. Through a shared
837
+ * `assign(target, field, value)` the one `target[field]` access saw all thirteen names, went
838
+ * megamorphic, and read numbers back boxed, while the call boxed the value it was handed: 228 B and
839
+ * ~120 ns per emitter per call, against nothing and ~9 ns written out like this
840
+ * (`GPUParticleEmitterSystem.allocation.spec.js`). This runs for every live emitter twice a frame.
841
+ *
836
842
  * @param {ParticleEmitter} emitter
837
843
  * @param {ParticleEffect} effect
838
844
  * @returns {boolean} whether the emitter differs from what it held before
@@ -840,45 +846,82 @@ export class GPUParticleEmitterSystem extends System {
840
846
  export function apply_particle_effect(emitter, effect) {
841
847
  let changed = false;
842
848
 
843
- changed = assign(emitter, "layout", effect.layout) || changed;
844
- changed = assign(emitter, "program", effect.program) || changed;
845
- changed = assign(emitter, "texture", effect.texture) || changed;
846
- changed = assign(emitter, "seed", effect.seed) || changed;
847
- changed = assign(emitter, "spawn_rate", effect.effective_spawn_rate) || changed;
848
- changed = assign(emitter, "prewarm", effect.prewarm) || changed;
849
- changed = assign(emitter, "flags", effect.flags) || changed;
850
- changed = assign(emitter, "render_position", effect.render_position) || changed;
851
- changed = assign(emitter, "render_size", effect.render_size) || changed;
852
- changed = assign(emitter, "render_color", effect.render_color) || changed;
853
- changed = assign(emitter, "render_rotation", effect.render_rotation) || changed;
854
- changed = assign(emitter, "render_frame", effect.render_frame) || changed;
855
- changed = assign(emitter, "render_velocity", effect.render_velocity) || changed;
849
+ if (emitter.layout !== effect.layout) {
850
+ emitter.layout = effect.layout;
851
+ changed = true;
852
+ }
856
853
 
857
- const flipbook = emitter.flipbook;
854
+ if (emitter.program !== effect.program) {
855
+ emitter.program = effect.program;
856
+ changed = true;
857
+ }
858
858
 
859
- if (flipbook[0] !== effect.flipbook[0] || flipbook[1] !== effect.flipbook[1]) {
860
- flipbook.set(effect.flipbook);
859
+ if (emitter.texture !== effect.texture) {
860
+ emitter.texture = effect.texture;
861
+ changed = true;
862
+ }
861
863
 
864
+ if (emitter.seed !== effect.seed) {
865
+ emitter.seed = effect.seed;
862
866
  changed = true;
863
867
  }
864
868
 
865
- return changed;
866
- }
869
+ const spawn_rate = effect.effective_spawn_rate;
867
870
 
868
- /**
869
- * @param {object} target
870
- * @param {string} field
871
- * @param {*} value
872
- * @returns {boolean} whether the field held something else
873
- */
874
- function assign(target, field, value) {
875
- if (target[field] === value) {
876
- return false;
871
+ if (emitter.spawn_rate !== spawn_rate) {
872
+ emitter.spawn_rate = spawn_rate;
873
+ changed = true;
874
+ }
875
+
876
+ if (emitter.prewarm !== effect.prewarm) {
877
+ emitter.prewarm = effect.prewarm;
878
+ changed = true;
877
879
  }
878
880
 
879
- target[field] = value;
881
+ if (emitter.flags !== effect.flags) {
882
+ emitter.flags = effect.flags;
883
+ changed = true;
884
+ }
885
+
886
+ if (emitter.render_position !== effect.render_position) {
887
+ emitter.render_position = effect.render_position;
888
+ changed = true;
889
+ }
880
890
 
881
- return true;
891
+ if (emitter.render_size !== effect.render_size) {
892
+ emitter.render_size = effect.render_size;
893
+ changed = true;
894
+ }
895
+
896
+ if (emitter.render_color !== effect.render_color) {
897
+ emitter.render_color = effect.render_color;
898
+ changed = true;
899
+ }
900
+
901
+ if (emitter.render_rotation !== effect.render_rotation) {
902
+ emitter.render_rotation = effect.render_rotation;
903
+ changed = true;
904
+ }
905
+
906
+ if (emitter.render_frame !== effect.render_frame) {
907
+ emitter.render_frame = effect.render_frame;
908
+ changed = true;
909
+ }
910
+
911
+ if (emitter.render_velocity !== effect.render_velocity) {
912
+ emitter.render_velocity = effect.render_velocity;
913
+ changed = true;
914
+ }
915
+
916
+ const flipbook = emitter.flipbook;
917
+
918
+ if (flipbook[0] !== effect.flipbook[0] || flipbook[1] !== effect.flipbook[1]) {
919
+ flipbook.set(effect.flipbook);
920
+
921
+ changed = true;
922
+ }
923
+
924
+ return changed;
882
925
  }
883
926
 
884
927
  class GPUParticleAtlasExtension extends RenderExtension {
@@ -6,6 +6,7 @@ export default KeyboardDevice;
6
6
  * the key remains pressed and the eventual physical release is picked up at the window level.
7
7
  * NOTE: when the window itself loses focus (e.g. switching to another application), key releases can no longer
8
8
  * be observed at all, so any "pressed" keys are forcibly released with the appropriate signal.
9
+ * A key still held when focus returns is pressed again by its next automatic repetition.
9
10
  *
10
11
  * @author Alex Goldring
11
12
  * @copyright Company Named Limited (c) 2026
@@ -1 +1 @@
1
- {"version":3,"file":"KeyboardDevice.d.ts","sourceRoot":"","sources":["../../../../../src/engine/input/devices/KeyboardDevice.js"],"names":[],"mappings":";AAYA;;;;;;;;;;GAUG;AACH;IA4BI;;;OAGG;IACH,wBAHW,WAAW,GAAC,OAAO,EAgC7B;IA3DD;;OAEG;IACH;QACI;;;WAGG;;QAEH;;;WAGG;;MAEL;IAEF;;;;;;;OAOG;IACH,mBAAU;IAkBN;;;OAGG;IACH,YAFU,WAAW,CAEO;IA2HhC;;;OAGG;IACH,SAFa,IAAI,CAWhB;IAED;;;OAGG;IACH,QAFa,IAAI,CAUhB;;CAEJ"}
1
+ {"version":3,"file":"KeyboardDevice.d.ts","sourceRoot":"","sources":["../../../../../src/engine/input/devices/KeyboardDevice.js"],"names":[],"mappings":";AAYA;;;;;;;;;;;GAWG;AACH;IA4BI;;;OAGG;IACH,wBAHW,WAAW,GAAC,OAAO,EAgC7B;IA3DD;;OAEG;IACH;QACI;;;WAGG;;QAEH;;;WAGG;;MAEL;IAEF;;;;;;;OAOG;IACH,mBAAU;IAkBN;;;OAGG;IACH,YAFU,WAAW,CAEO;IA2HhC;;;OAGG;IACH,SAFa,IAAI,CAWhB;IAED;;;OAGG;IACH,QAFa,IAAI,CAUhB;;CAEJ"}