@needle-tools/engine 5.1.0-alpha.2 → 5.1.0-alpha.4
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 +74 -1
- package/SKILL.md +4 -1
- package/components.needle.json +1 -1
- package/dist/needle-engine.bundle-AjVIot3d.min.js +1733 -0
- package/dist/{needle-engine.bundle-dit3f1l5.js → needle-engine.bundle-B7cqsI4c.js} +12199 -11704
- package/dist/needle-engine.bundle-DQCuBTVp.umd.cjs +1733 -0
- package/dist/needle-engine.d.ts +879 -226
- package/dist/needle-engine.js +584 -582
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/api.d.ts +5 -0
- package/lib/engine/api.js +4 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/codegen/register_types.js +2 -10
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/debug/debug_spatial_console.d.ts +2 -0
- package/lib/engine/debug/debug_spatial_console.js +10 -7
- package/lib/engine/debug/debug_spatial_console.js.map +1 -1
- package/lib/engine/engine_addressables.d.ts +2 -0
- package/lib/engine/engine_addressables.js +6 -3
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_audio.d.ts +68 -0
- package/lib/engine/engine_audio.js +172 -0
- package/lib/engine/engine_audio.js.map +1 -1
- package/lib/engine/engine_components.js +1 -1
- package/lib/engine/engine_components.js.map +1 -1
- package/lib/engine/engine_context.d.ts +1 -1
- package/lib/engine/engine_context.js +3 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_disposable.d.ts +172 -0
- package/lib/engine/engine_disposable.js +136 -0
- package/lib/engine/engine_disposable.js.map +1 -0
- package/lib/engine/engine_gameobject.d.ts +1 -10
- package/lib/engine/engine_gameobject.js +22 -120
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_gltf_builtin_components.js +7 -69
- package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
- package/lib/engine/engine_init.js +13 -3
- package/lib/engine/engine_init.js.map +1 -1
- package/lib/engine/engine_input.d.ts +1 -1
- package/lib/engine/engine_input.js +1 -1
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_instantiate_resolve.d.ts +42 -0
- package/lib/engine/engine_instantiate_resolve.js +372 -0
- package/lib/engine/engine_instantiate_resolve.js.map +1 -0
- package/lib/engine/engine_license.js +1 -1
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_mainloop_utils.js +7 -4
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_networking.d.ts +51 -37
- package/lib/engine/engine_networking.js +132 -82
- package/lib/engine/engine_networking.js.map +1 -1
- package/lib/engine/engine_networking.transport.websocket.d.ts +15 -0
- package/lib/engine/engine_networking.transport.websocket.js +38 -0
- package/lib/engine/engine_networking.transport.websocket.js.map +1 -0
- package/lib/engine/engine_networking_blob.js +1 -1
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_networking_instantiate.js +2 -2
- package/lib/engine/engine_networking_instantiate.js.map +1 -1
- package/lib/engine/engine_networking_types.d.ts +39 -1
- package/lib/engine/engine_networking_types.js +7 -0
- package/lib/engine/engine_networking_types.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +11 -3
- package/lib/engine/engine_physics_rapier.js +88 -25
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_scenedata.d.ts +2 -0
- package/lib/engine/engine_scenedata.js +4 -2
- package/lib/engine/engine_scenedata.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.d.ts +10 -16
- package/lib/engine/engine_serialization_builtin_serializer.js +56 -46
- package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
- package/lib/engine/engine_serialization_core.d.ts +1 -0
- package/lib/engine/engine_serialization_core.js +7 -0
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_types.d.ts +19 -11
- package/lib/engine/engine_types.js +1 -1
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_util_decorator.js +7 -2
- package/lib/engine/engine_util_decorator.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +1 -1
- package/lib/engine/engine_utils.js +19 -5
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +10 -4
- package/lib/engine/webcomponents/needle-engine.js +1 -1
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/xr/NeedleXRSession.d.ts +3 -2
- package/lib/engine/xr/NeedleXRSession.js +50 -14
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine/xr/events.d.ts +1 -1
- package/lib/engine/xr/events.js.map +1 -1
- package/lib/engine-components/Animation.js +17 -16
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/Animator.d.ts +6 -0
- package/lib/engine-components/Animator.js +17 -12
- package/lib/engine-components/Animator.js.map +1 -1
- package/lib/engine-components/AnimatorController.builder.d.ts +113 -0
- package/lib/engine-components/AnimatorController.builder.js +195 -0
- package/lib/engine-components/AnimatorController.builder.js.map +1 -0
- package/lib/engine-components/AnimatorController.d.ts +4 -119
- package/lib/engine-components/AnimatorController.js +35 -233
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/AudioSource.d.ts +19 -3
- package/lib/engine-components/AudioSource.js +121 -68
- package/lib/engine-components/AudioSource.js.map +1 -1
- package/lib/engine-components/Collider.d.ts +18 -9
- package/lib/engine-components/Collider.js +61 -14
- package/lib/engine-components/Collider.js.map +1 -1
- package/lib/engine-components/Component.d.ts +72 -9
- package/lib/engine-components/Component.js +114 -10
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/DragControls.d.ts +7 -0
- package/lib/engine-components/DragControls.js +19 -7
- package/lib/engine-components/DragControls.js.map +1 -1
- package/lib/engine-components/EventList.d.ts +31 -9
- package/lib/engine-components/EventList.js +37 -76
- package/lib/engine-components/EventList.js.map +1 -1
- package/lib/engine-components/Joints.d.ts +4 -2
- package/lib/engine-components/Joints.js +19 -3
- package/lib/engine-components/Joints.js.map +1 -1
- package/lib/engine-components/Light.js +9 -1
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/Networking.d.ts +1 -1
- package/lib/engine-components/Networking.js +1 -1
- package/lib/engine-components/OrbitControls.js +16 -11
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.js +2 -0
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/RigidBody.d.ts +12 -4
- package/lib/engine-components/RigidBody.js +18 -4
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SeeThrough.js +2 -2
- package/lib/engine-components/SeeThrough.js.map +1 -1
- package/lib/engine-components/api.d.ts +1 -1
- package/lib/engine-components/api.js +1 -1
- package/lib/engine-components/api.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +3 -9
- package/lib/engine-components/codegen/components.js +3 -9
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
- package/lib/engine-components/postprocessing/VolumeParameter.d.ts +2 -0
- package/lib/engine-components/postprocessing/VolumeParameter.js +4 -1
- package/lib/engine-components/postprocessing/VolumeParameter.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +16 -6
- package/lib/engine-components/timeline/PlayableDirector.js +70 -62
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
- package/lib/engine-components/timeline/SignalAsset.js +1 -0
- package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
- package/lib/engine-components/timeline/TimelineBuilder.d.ts +247 -0
- package/lib/engine-components/timeline/TimelineBuilder.js +400 -0
- package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
- package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
- package/lib/engine-components/timeline/TimelineModels.js +3 -0
- package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +23 -0
- package/lib/engine-components/timeline/TimelineTracks.js +71 -13
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/timeline/index.d.ts +2 -1
- package/lib/engine-components/timeline/index.js +2 -0
- package/lib/engine-components/timeline/index.js.map +1 -1
- package/lib/engine-components/ui/Canvas.d.ts +1 -1
- package/lib/engine-components/ui/Canvas.js +2 -8
- package/lib/engine-components/ui/Canvas.js.map +1 -1
- package/lib/engine-components/ui/Text.d.ts +1 -0
- package/lib/engine-components/ui/Text.js +10 -7
- package/lib/engine-components/ui/Text.js.map +1 -1
- package/lib/engine-components/web/CursorFollow.js +21 -12
- package/lib/engine-components/web/CursorFollow.js.map +1 -1
- package/lib/engine-components/webxr/WebXRImageTracking.js +4 -0
- package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
- package/package.json +2 -83
- package/plugins/common/license.js +5 -2
- package/plugins/common/worker.js +9 -4
- package/plugins/vite/asap.js +17 -8
- package/plugins/vite/dependencies.js +29 -10
- package/plugins/vite/dependency-watcher.js +2 -2
- package/plugins/vite/editor-connection.js +3 -3
- package/plugins/vite/local-files-core.js +3 -3
- package/plugins/vite/local-files-utils.d.ts +3 -1
- package/plugins/vite/local-files-utils.js +29 -5
- package/plugins/vite/reload.js +1 -1
- package/plugins/vite/server.js +2 -1
- package/src/engine/api.ts +7 -0
- package/src/engine/codegen/register_types.ts +2 -10
- package/src/engine/debug/debug_spatial_console.ts +10 -7
- package/src/engine/engine_addressables.ts +6 -3
- package/src/engine/engine_audio.ts +184 -0
- package/src/engine/engine_components.ts +1 -1
- package/src/engine/engine_context.ts +4 -3
- package/src/engine/engine_disposable.ts +214 -0
- package/src/engine/engine_gameobject.ts +54 -159
- package/src/engine/engine_gltf_builtin_components.ts +7 -76
- package/src/engine/engine_init.ts +13 -3
- package/src/engine/engine_input.ts +1 -1
- package/src/engine/engine_instantiate_resolve.ts +407 -0
- package/src/engine/engine_license.ts +1 -1
- package/src/engine/engine_mainloop_utils.ts +7 -4
- package/src/engine/engine_networking.transport.websocket.ts +45 -0
- package/src/engine/engine_networking.ts +161 -137
- package/src/engine/engine_networking_blob.ts +1 -1
- package/src/engine/engine_networking_instantiate.ts +2 -2
- package/src/engine/engine_networking_types.ts +41 -1
- package/src/engine/engine_physics_rapier.ts +82 -27
- package/src/engine/engine_scenedata.ts +5 -3
- package/src/engine/engine_serialization_builtin_serializer.ts +64 -52
- package/src/engine/engine_serialization_core.ts +9 -0
- package/src/engine/engine_types.ts +24 -15
- package/src/engine/engine_util_decorator.ts +7 -2
- package/src/engine/engine_utils.ts +16 -5
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
- package/src/engine/webcomponents/needle menu/needle-menu.ts +1 -1
- package/src/engine/webcomponents/needle-engine.ts +10 -4
- package/src/engine/xr/NeedleXRSession.ts +48 -13
- package/src/engine/xr/events.ts +1 -1
- package/src/engine-components/Animation.ts +19 -16
- package/src/engine-components/Animator.ts +18 -11
- package/src/engine-components/AnimatorController.builder.ts +261 -0
- package/src/engine-components/AnimatorController.ts +23 -292
- package/src/engine-components/AudioSource.ts +130 -79
- package/src/engine-components/Collider.ts +66 -18
- package/src/engine-components/Component.ts +118 -20
- package/src/engine-components/DragControls.ts +18 -11
- package/src/engine-components/EventList.ts +45 -83
- package/src/engine-components/Joints.ts +20 -4
- package/src/engine-components/Light.ts +10 -2
- package/src/engine-components/Networking.ts +1 -1
- package/src/engine-components/OrbitControls.ts +18 -9
- package/src/engine-components/ReflectionProbe.ts +2 -0
- package/src/engine-components/RigidBody.ts +18 -4
- package/src/engine-components/SeeThrough.ts +2 -2
- package/src/engine-components/api.ts +1 -1
- package/src/engine-components/codegen/components.ts +3 -9
- package/src/engine-components/postprocessing/VolumeParameter.ts +4 -1
- package/src/engine-components/timeline/PlayableDirector.ts +67 -65
- package/src/engine-components/timeline/SignalAsset.ts +4 -1
- package/src/engine-components/timeline/TimelineBuilder.ts +564 -0
- package/src/engine-components/timeline/TimelineModels.ts +5 -1
- package/src/engine-components/timeline/TimelineTracks.ts +74 -13
- package/src/engine-components/timeline/index.ts +2 -1
- package/src/engine-components/ui/Canvas.ts +2 -8
- package/src/engine-components/ui/Text.ts +12 -8
- package/src/engine-components/web/CursorFollow.ts +21 -13
- package/src/engine-components/webxr/WebXRImageTracking.ts +2 -0
- package/dist/needle-engine.bundle-B-5Q2CpC.min.js +0 -1732
- package/dist/needle-engine.bundle-qZfVf_v-.umd.cjs +0 -1732
- package/lib/engine-components/AvatarLoader.d.ts +0 -80
- package/lib/engine-components/AvatarLoader.js +0 -232
- package/lib/engine-components/AvatarLoader.js.map +0 -1
- package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
- package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
- package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
- package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
- package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
- package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
- package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
- package/src/engine-components/AvatarLoader.ts +0 -264
- package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
- package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
- package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
- package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
- package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Ball, Collider, ColliderDesc, Cuboid, EventQueue, QueryFilterFlags, Ray, RigidBody, RigidBodyDesc, World } from '@dimforge/rapier3d-compat';
|
|
1
|
+
import type { Ball, Collider, ColliderDesc, Cuboid, EventQueue, ImpulseJoint, QueryFilterFlags, Ray, RigidBody, RigidBodyDesc, World } from '@dimforge/rapier3d-compat';
|
|
2
2
|
import { BufferAttribute, BufferGeometry, InterleavedBufferAttribute, LineBasicMaterial, LineSegments, Matrix4, Mesh, Object3D, Quaternion, Vector3, Vector4Like } from 'three'
|
|
3
3
|
import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'
|
|
4
4
|
|
|
@@ -690,12 +690,26 @@ export class RapierPhysics implements IPhysicsEngine {
|
|
|
690
690
|
}
|
|
691
691
|
}
|
|
692
692
|
|
|
693
|
-
|
|
693
|
+
/** Tears down the physics world and frees all WASM resources.
|
|
694
|
+
* After calling this, the world will be re-created on next use. */
|
|
695
|
+
dispose() {
|
|
694
696
|
this._meshCache.clear();
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
697
|
+
this.eventQueue?.free();
|
|
698
|
+
this._world?.free();
|
|
699
|
+
// Reset initialization state so the world can be recreated
|
|
700
|
+
this._world = undefined;
|
|
701
|
+
this.eventQueue = undefined;
|
|
702
|
+
this.collisionHandler = undefined;
|
|
703
|
+
this._isInitialized = false;
|
|
704
|
+
this._hasCreatedWorld = false;
|
|
705
|
+
this._initializePromise = undefined;
|
|
706
|
+
this.objects.length = 0;
|
|
707
|
+
this.bodies.length = 0;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/** @deprecated Use {@link dispose} instead. */
|
|
711
|
+
clearCaches() {
|
|
712
|
+
this.dispose();
|
|
699
713
|
}
|
|
700
714
|
|
|
701
715
|
async addBoxCollider(collider: ICollider, size: Vector3) {
|
|
@@ -981,13 +995,17 @@ export class RapierPhysics implements IPhysicsEngine {
|
|
|
981
995
|
}
|
|
982
996
|
}
|
|
983
997
|
|
|
984
|
-
//
|
|
985
|
-
//
|
|
998
|
+
// When using explicit mass (autoMass=false), set collider mass to near-zero
|
|
999
|
+
// so Rapier doesn't contribute mass from the collider shape.
|
|
1000
|
+
// The actual mass is applied via setAdditionalMass on the rigidbody instead.
|
|
1001
|
+
// Note: setMass overrides any prior setDensity call (they are mutually exclusive in Rapier)
|
|
986
1002
|
// https://rapier.rs/docs/user_guides/javascript/rigid_bodies#mass-properties
|
|
987
1003
|
if (collider.attachedRigidbody?.autoMass === false) {
|
|
988
|
-
desc.setDensity(.000001);
|
|
989
1004
|
desc.setMass(.000001);
|
|
990
1005
|
}
|
|
1006
|
+
else if (collider.density != null) {
|
|
1007
|
+
desc.setDensity(collider.density);
|
|
1008
|
+
}
|
|
991
1009
|
|
|
992
1010
|
try {
|
|
993
1011
|
const col = this.world.createCollider(desc, rigidBody);
|
|
@@ -1130,6 +1148,11 @@ export class RapierPhysics implements IPhysicsEngine {
|
|
|
1130
1148
|
break;
|
|
1131
1149
|
}
|
|
1132
1150
|
|
|
1151
|
+
// Update density if specified (setDensity auto-recomputes parent body mass)
|
|
1152
|
+
if (col.density != null) {
|
|
1153
|
+
collider.setDensity(col.density);
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1133
1156
|
if (sizeHasChanged) {
|
|
1134
1157
|
const rb = col.attachedRigidbody;
|
|
1135
1158
|
if (rb?.autoMass) {
|
|
@@ -1161,7 +1184,8 @@ export class RapierPhysics implements IPhysicsEngine {
|
|
|
1161
1184
|
rigidbody.setAdditionalMass(0, false);
|
|
1162
1185
|
for (let i = 0; i < rigidbody.numColliders(); i++) {
|
|
1163
1186
|
const col = rigidbody.collider(i);
|
|
1164
|
-
col
|
|
1187
|
+
const colliderComponent = col[$componentKey] as ICollider | null;
|
|
1188
|
+
col.setDensity(colliderComponent?.density ?? 1);
|
|
1165
1189
|
}
|
|
1166
1190
|
rigidbody.recomputeMassPropertiesFromColliders();
|
|
1167
1191
|
}
|
|
@@ -1477,16 +1501,21 @@ export class RapierPhysics implements IPhysicsEngine {
|
|
|
1477
1501
|
|
|
1478
1502
|
private static centerConnectionPos = { x: 0, y: 0, z: 0 };
|
|
1479
1503
|
private static centerConnectionRot = { x: 0, y: 0, z: 0, w: 1 };
|
|
1504
|
+
private _jointTempMatrix = new Matrix4();
|
|
1480
1505
|
|
|
1481
1506
|
|
|
1482
|
-
|
|
1483
|
-
|
|
1507
|
+
async addFixedJoint(body1: IRigidbody, body2: IRigidbody): Promise<ImpulseJoint | null> {
|
|
1508
|
+
if (!this._isInitialized) await this.initialize();
|
|
1484
1509
|
if (!this.world) {
|
|
1485
1510
|
console.error("Physics world not initialized");
|
|
1486
|
-
return;
|
|
1511
|
+
return null;
|
|
1487
1512
|
}
|
|
1488
1513
|
const b1 = body1[$bodyKey] as RigidBody;
|
|
1489
1514
|
const b2 = body2[$bodyKey] as RigidBody;
|
|
1515
|
+
if (!b1 || !b2) {
|
|
1516
|
+
console.error("Cannot create fixed joint: one or both physics bodies are not initialized");
|
|
1517
|
+
return null;
|
|
1518
|
+
}
|
|
1490
1519
|
|
|
1491
1520
|
this.calculateJointRelativeMatrices(body1.gameObject, body2.gameObject, this._tempMatrix);
|
|
1492
1521
|
this._tempMatrix.decompose(this._tempPosition, this._tempQuaternion, this._tempScale);
|
|
@@ -1498,41 +1527,67 @@ export class RapierPhysics implements IPhysicsEngine {
|
|
|
1498
1527
|
const joint = this.world.createImpulseJoint(params, b1, b2, true);
|
|
1499
1528
|
if (debugPhysics)
|
|
1500
1529
|
console.log("ADD FIXED JOINT", joint)
|
|
1530
|
+
return joint;
|
|
1501
1531
|
}
|
|
1502
1532
|
|
|
1503
1533
|
|
|
1504
1534
|
/** The joint prevents any relative movement between two rigid-bodies, except for relative rotations along one axis. This is typically used to simulate wheels, fans, etc. They are characterized by one local anchor as well as one local axis on each rigid-body. */
|
|
1505
|
-
addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: { x: number, y: number, z: number }, axis: { x: number, y: number, z: number }) {
|
|
1535
|
+
async addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: { x: number, y: number, z: number }, axis: { x: number, y: number, z: number }): Promise<ImpulseJoint | null> {
|
|
1536
|
+
if (!this._isInitialized) await this.initialize();
|
|
1506
1537
|
if (!this.world) {
|
|
1507
1538
|
console.error("Physics world not initialized");
|
|
1508
|
-
return;
|
|
1539
|
+
return null;
|
|
1509
1540
|
}
|
|
1510
1541
|
const b1 = body1[$bodyKey] as RigidBody;
|
|
1511
1542
|
const b2 = body2[$bodyKey] as RigidBody;
|
|
1543
|
+
if (!b1 || !b2) {
|
|
1544
|
+
console.error("Cannot create hinge joint: one or both physics bodies are not initialized");
|
|
1545
|
+
return null;
|
|
1546
|
+
}
|
|
1512
1547
|
|
|
1513
1548
|
this.calculateJointRelativeMatrices(body1.gameObject, body2.gameObject, this._tempMatrix);
|
|
1514
|
-
|
|
1549
|
+
// Transform anchor from body1's local space to body2's local space
|
|
1550
|
+
const anchor2 = this._tempPosition.set(anchor.x, anchor.y, anchor.z).applyMatrix4(this._tempMatrix);
|
|
1515
1551
|
|
|
1516
|
-
const params = MODULES.RAPIER_PHYSICS.MODULE.JointData.revolute(anchor,
|
|
1552
|
+
const params = MODULES.RAPIER_PHYSICS.MODULE.JointData.revolute(anchor, anchor2, axis);
|
|
1517
1553
|
const joint = this.world.createImpulseJoint(params, b1, b2, true);
|
|
1518
1554
|
if (debugPhysics)
|
|
1519
1555
|
console.log("ADD HINGE JOINT", joint)
|
|
1556
|
+
return joint;
|
|
1520
1557
|
}
|
|
1521
1558
|
|
|
1522
1559
|
|
|
1560
|
+
removeJoint(joint: ImpulseJoint) {
|
|
1561
|
+
if (!this.world) return;
|
|
1562
|
+
this.world.removeImpulseJoint(joint, true);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
|
|
1566
|
+
/** Compute the relative transform from body1's local space to body2's local space (W2⁻¹ * W1), ignoring scale. */
|
|
1523
1567
|
private calculateJointRelativeMatrices(body1: IGameObject, body2: IGameObject, mat: Matrix4) {
|
|
1524
1568
|
body1.updateWorldMatrix(true, false);
|
|
1525
1569
|
body2.updateWorldMatrix(true, false);
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
mat
|
|
1570
|
+
|
|
1571
|
+
// Work on copies to avoid mutating the actual world matrices
|
|
1572
|
+
mat.copy(body1.matrixWorld);
|
|
1573
|
+
const w2 = this._jointTempMatrix.copy(body2.matrixWorld);
|
|
1574
|
+
|
|
1575
|
+
// Strip scale by normalizing each column of the upper 3x3
|
|
1576
|
+
this.normalizeMatrixColumns(mat);
|
|
1577
|
+
this.normalizeMatrixColumns(w2);
|
|
1578
|
+
|
|
1579
|
+
// mat = W2^-1 * W1 (body1's frame in body2's local space)
|
|
1580
|
+
mat.premultiply(w2.invert());
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
private normalizeMatrixColumns(m: Matrix4) {
|
|
1584
|
+
const e = m.elements;
|
|
1585
|
+
let len = Math.sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
|
|
1586
|
+
if (len > 0) { e[0] /= len; e[1] /= len; e[2] /= len; }
|
|
1587
|
+
len = Math.sqrt(e[4] * e[4] + e[5] * e[5] + e[6] * e[6]);
|
|
1588
|
+
if (len > 0) { e[4] /= len; e[5] /= len; e[6] /= len; }
|
|
1589
|
+
len = Math.sqrt(e[8] * e[8] + e[9] * e[9] + e[10] * e[10]);
|
|
1590
|
+
if (len > 0) { e[8] /= len; e[9] /= len; e[10] /= len; }
|
|
1536
1591
|
}
|
|
1537
1592
|
}
|
|
1538
1593
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { SceneData } from "needle-bindings";
|
|
2
2
|
export type { SceneData };
|
|
3
|
-
import type { IContext } from "./engine_types.js";
|
|
4
|
-
import { getComponent } from "./engine_components.js";
|
|
5
|
-
import { TypeStore } from "./engine_typestore.js";
|
|
6
3
|
import { isDevEnvironment } from "./debug/index.js";
|
|
4
|
+
import { getComponent } from "./engine_components.js";
|
|
7
5
|
import { ContextRegistry } from "./engine_context_registry.js";
|
|
6
|
+
import type { IContext } from "./engine_types.js";
|
|
7
|
+
import { TypeStore } from "./engine_typestore.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Quick access to the current Needle Engine context from anywhere — no need to pass `ctx` around.
|
|
@@ -13,6 +13,8 @@ import { ContextRegistry } from "./engine_context_registry.js";
|
|
|
13
13
|
* Safe to import at module level, including in SSR environments.
|
|
14
14
|
* For pages with multiple `<needle-engine>` elements, use `ctx` directly instead.
|
|
15
15
|
*
|
|
16
|
+
* @experimental This API may change in future releases.
|
|
17
|
+
*
|
|
16
18
|
* @example
|
|
17
19
|
* import { needle } from "@needle-tools/engine";
|
|
18
20
|
* button.onclick = () => {
|
|
@@ -4,6 +4,7 @@ import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../eng
|
|
|
4
4
|
import { Behaviour, Component, GameObject } from "../engine-components/Component.js";
|
|
5
5
|
import { CallInfo, EventList } from "../engine-components/EventList.js";
|
|
6
6
|
import { AssetReference } from "./engine_addressables.js";
|
|
7
|
+
import { AudioClip } from "./engine_audio.js";
|
|
7
8
|
import { debugExtension } from "./engine_default_parameters.js";
|
|
8
9
|
import { SerializationContext, TypeSerializer } from "./engine_serialization_core.js";
|
|
9
10
|
import { RenderTexture } from "./engine_texture.js";
|
|
@@ -11,25 +12,7 @@ import { IComponent } from "./engine_types.js";
|
|
|
11
12
|
import { resolveUrl } from "./engine_utils.js";
|
|
12
13
|
import { RGBAColor } from "./js-extensions/index.js";
|
|
13
14
|
|
|
14
|
-
//
|
|
15
|
-
// src?:string
|
|
16
|
-
// };
|
|
17
|
-
|
|
18
|
-
// class SourcePathSerializer extends TypeSerializer{
|
|
19
|
-
// constructor(){
|
|
20
|
-
// super(SourcePath);
|
|
21
|
-
// }
|
|
22
|
-
// onDeserialize(data: any, _context: SerializationContext) {
|
|
23
|
-
// if(data.src && typeof data.src === "string"){
|
|
24
|
-
// return data.src;
|
|
25
|
-
// }
|
|
26
|
-
// }
|
|
27
|
-
// onSerialize(_data: any, _context: SerializationContext) {
|
|
28
|
-
|
|
29
|
-
// }
|
|
30
|
-
// }
|
|
31
|
-
// new SourcePathSerializer();
|
|
32
|
-
|
|
15
|
+
// #region Color
|
|
33
16
|
class ColorSerializer extends TypeSerializer {
|
|
34
17
|
constructor() {
|
|
35
18
|
super([Color, RGBAColor], "ColorSerializer")
|
|
@@ -52,7 +35,8 @@ class ColorSerializer extends TypeSerializer {
|
|
|
52
35
|
return { r: data.r, g: data.g, b: data.b }
|
|
53
36
|
}
|
|
54
37
|
}
|
|
55
|
-
|
|
38
|
+
|
|
39
|
+
// #region Euler
|
|
56
40
|
|
|
57
41
|
class EulerSerializer extends TypeSerializer {
|
|
58
42
|
constructor() {
|
|
@@ -72,12 +56,13 @@ class EulerSerializer extends TypeSerializer {
|
|
|
72
56
|
return { x: data.x, y: data.y, z: data.z, order: data.order };
|
|
73
57
|
}
|
|
74
58
|
}
|
|
75
|
-
export const euler = new EulerSerializer();
|
|
76
59
|
|
|
77
60
|
declare type ObjectData = {
|
|
78
61
|
node?: number;
|
|
79
62
|
guid?: string;
|
|
80
63
|
}
|
|
64
|
+
|
|
65
|
+
// #region ObjectSerializer
|
|
81
66
|
class ObjectSerializer extends TypeSerializer {
|
|
82
67
|
constructor() {
|
|
83
68
|
super(Object3D, "ObjectSerializer");
|
|
@@ -107,16 +92,6 @@ class ObjectSerializer extends TypeSerializer {
|
|
|
107
92
|
console.warn(`Wrong usage of @serializable detected in your script \"${scriptname}\"\n\nIt looks like you used @serializable(Object3D) or @serializable(GameObject) for a prefab or scene reference which is exported to a separate glTF file.\n\nTo fix this please change your code to:\n\n@serializable(AssetReference)\n${context.path}! : AssetReference;\n\0`);
|
|
108
93
|
}
|
|
109
94
|
// ACTUALLY: this is already handled by the extension_utils where we resolve json pointers recursively
|
|
110
|
-
// if(data.startsWith("/nodes/")){
|
|
111
|
-
// const node = parseInt(data.substring("/nodes/".length));
|
|
112
|
-
// if (context.nodeToObject) {
|
|
113
|
-
// const res = context.nodeToObject[node];
|
|
114
|
-
// if (debugExtension)
|
|
115
|
-
// console.log("Deserialized object reference?", data, res, context?.nodeToObject);
|
|
116
|
-
// if (!res) console.warn("Did not find node: " + data, context.nodeToObject, context.object);
|
|
117
|
-
// return res;
|
|
118
|
-
// }
|
|
119
|
-
// }
|
|
120
95
|
return undefined;
|
|
121
96
|
}
|
|
122
97
|
|
|
@@ -149,7 +124,7 @@ class ObjectSerializer extends TypeSerializer {
|
|
|
149
124
|
}
|
|
150
125
|
if (!res) {
|
|
151
126
|
if (isDevEnvironment() || debugExtension)
|
|
152
|
-
console.warn(
|
|
127
|
+
console.warn(`Could not resolve object reference \"${context.path}\" (guid: ${data.guid}). The referenced object may have been deleted — check if the reference is still valid in your scene.`);
|
|
153
128
|
data["could_not_resolve"] = true;
|
|
154
129
|
}
|
|
155
130
|
else {
|
|
@@ -166,9 +141,8 @@ class ObjectSerializer extends TypeSerializer {
|
|
|
166
141
|
return undefined;
|
|
167
142
|
}
|
|
168
143
|
}
|
|
169
|
-
export const objectSerializer = new ObjectSerializer();
|
|
170
|
-
|
|
171
144
|
|
|
145
|
+
// #region ComponentSerializer
|
|
172
146
|
class ComponentSerializer extends TypeSerializer {
|
|
173
147
|
|
|
174
148
|
constructor() {
|
|
@@ -241,7 +215,6 @@ class ComponentSerializer extends TypeSerializer {
|
|
|
241
215
|
}
|
|
242
216
|
}
|
|
243
217
|
}
|
|
244
|
-
export const componentSerializer = new ComponentSerializer();
|
|
245
218
|
|
|
246
219
|
|
|
247
220
|
declare class EventListData {
|
|
@@ -258,6 +231,7 @@ declare type EventListCall = {
|
|
|
258
231
|
|
|
259
232
|
const $eventListDebugInfo = Symbol("eventListDebugInfo");
|
|
260
233
|
|
|
234
|
+
// #region EventListSerializer
|
|
261
235
|
class EventListSerializer extends TypeSerializer {
|
|
262
236
|
constructor() {
|
|
263
237
|
super([EventList]);
|
|
@@ -360,11 +334,6 @@ class EventListSerializer extends TypeSerializer {
|
|
|
360
334
|
if (debugExtension)
|
|
361
335
|
console.log(evt);
|
|
362
336
|
|
|
363
|
-
const eventListOwner = context.target;
|
|
364
|
-
if (eventListOwner !== undefined && context.path !== undefined) {
|
|
365
|
-
evt.setEventTarget(context.path, eventListOwner);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
337
|
return evt;
|
|
369
338
|
}
|
|
370
339
|
return undefined;
|
|
@@ -396,22 +365,14 @@ class EventListSerializer extends TypeSerializer {
|
|
|
396
365
|
// };
|
|
397
366
|
// }
|
|
398
367
|
}
|
|
399
|
-
export const eventListSerializer = new EventListSerializer();
|
|
400
368
|
|
|
401
369
|
|
|
402
370
|
/** Map<Clone, Original> texture. This is used for compressed textures (or when the GLTFLoader is cloning RenderTextures)
|
|
403
371
|
* It's a weak map so we don't have to worry about memory leaks
|
|
404
372
|
*/
|
|
405
373
|
const cloneOriginalMap = new WeakMap<Texture, Texture>();
|
|
406
|
-
const textureClone = Texture.prototype.clone;
|
|
407
|
-
Texture.prototype.clone = function () {
|
|
408
|
-
const clone = textureClone.call(this);
|
|
409
|
-
if (!cloneOriginalMap.has(clone)) {
|
|
410
|
-
cloneOriginalMap.set(clone, this);
|
|
411
|
-
}
|
|
412
|
-
return clone;
|
|
413
|
-
}
|
|
414
374
|
|
|
375
|
+
// #region RenderTextureSerializer
|
|
415
376
|
export class RenderTextureSerializer extends TypeSerializer {
|
|
416
377
|
constructor() {
|
|
417
378
|
super([RenderTexture, WebGLRenderTarget]);
|
|
@@ -452,9 +413,8 @@ export class RenderTextureSerializer extends TypeSerializer {
|
|
|
452
413
|
return undefined;
|
|
453
414
|
}
|
|
454
415
|
}
|
|
455
|
-
new RenderTextureSerializer();
|
|
456
|
-
|
|
457
416
|
|
|
417
|
+
// #region UriSerializer
|
|
458
418
|
export class UriSerializer extends TypeSerializer {
|
|
459
419
|
constructor() {
|
|
460
420
|
super([URL]);
|
|
@@ -471,4 +431,56 @@ export class UriSerializer extends TypeSerializer {
|
|
|
471
431
|
return undefined;
|
|
472
432
|
}
|
|
473
433
|
}
|
|
474
|
-
|
|
434
|
+
|
|
435
|
+
// #region AudioClipSerializer
|
|
436
|
+
class AudioClipSerializer extends TypeSerializer {
|
|
437
|
+
constructor() {
|
|
438
|
+
super([AudioClip]);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
onSerialize(_data: AudioClip, _context: SerializationContext) {
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
onDeserialize(data: string, context: SerializationContext) {
|
|
446
|
+
if (typeof data === "string" && data.length > 0) {
|
|
447
|
+
const url = resolveUrl(context.gltfId, data);
|
|
448
|
+
if (url) return new AudioClip(url);
|
|
449
|
+
}
|
|
450
|
+
return undefined;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
// #region Init serializer
|
|
456
|
+
// Module-level references used by EventListSerializer internally
|
|
457
|
+
export let colorSerializer: ColorSerializer;
|
|
458
|
+
export let objectSerializer: ObjectSerializer;
|
|
459
|
+
export let componentSerializer: ComponentSerializer;
|
|
460
|
+
export let eventListSerializer: EventListSerializer;
|
|
461
|
+
|
|
462
|
+
/** Register all builtin serializers and prototype patches.
|
|
463
|
+
* Must be called from {@link initEngine} so the registrations survive tree-shaking
|
|
464
|
+
* when the package declares `sideEffects: false`.
|
|
465
|
+
*/
|
|
466
|
+
export function initBuiltinSerializers() {
|
|
467
|
+
// Prototype patches
|
|
468
|
+
const textureClone = Texture.prototype.clone;
|
|
469
|
+
Texture.prototype.clone = function () {
|
|
470
|
+
const clone = textureClone.call(this);
|
|
471
|
+
if (!cloneOriginalMap.has(clone)) {
|
|
472
|
+
cloneOriginalMap.set(clone, this);
|
|
473
|
+
}
|
|
474
|
+
return clone;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Register all serializers
|
|
478
|
+
colorSerializer = new ColorSerializer();
|
|
479
|
+
new EulerSerializer();
|
|
480
|
+
objectSerializer = new ObjectSerializer();
|
|
481
|
+
componentSerializer = new ComponentSerializer();
|
|
482
|
+
eventListSerializer = new EventListSerializer();
|
|
483
|
+
new RenderTextureSerializer();
|
|
484
|
+
new UriSerializer();
|
|
485
|
+
new AudioClipSerializer();
|
|
486
|
+
}
|
|
@@ -207,6 +207,15 @@ export interface ISerializable {
|
|
|
207
207
|
onAfterDeserialize?(data: any, context: SerializationContext): void;
|
|
208
208
|
};
|
|
209
209
|
|
|
210
|
+
export function isSerializable(obj: any): obj is ISerializable {
|
|
211
|
+
return obj && typeof obj === "object" && (
|
|
212
|
+
typeof obj.$serializedTypes === "object" ||
|
|
213
|
+
typeof obj.onBeforeDeserialize === "function" ||
|
|
214
|
+
typeof obj.onBeforeDeserializeMember === "function" ||
|
|
215
|
+
typeof obj.onAfterDeserializeMember === "function" ||
|
|
216
|
+
typeof obj.onAfterDeserialize === "function"
|
|
217
|
+
)
|
|
218
|
+
}
|
|
210
219
|
|
|
211
220
|
export function serializeObject(obj: ISerializable, context: SerializationContext): object | null {
|
|
212
221
|
const types = obj.$serializedTypes;
|
|
@@ -5,7 +5,6 @@ import { type GLTF as THREE_GLTF } from "three/examples/jsm/loaders/GLTFLoader.j
|
|
|
5
5
|
|
|
6
6
|
import type { Camera as CameraComponent } from "../engine-components/api.js";
|
|
7
7
|
import type { Context } from "./engine_context.js";
|
|
8
|
-
import { InstantiateContext } from "./engine_gameobject.js";
|
|
9
8
|
import { CollisionDetectionMode, type PhysicsMaterial, RigidbodyConstraints } from "./engine_physics.types.js";
|
|
10
9
|
import { CircularBuffer } from "./engine_utils.js";
|
|
11
10
|
import type { NeedleXRSession } from "./engine_xr.js";
|
|
@@ -196,13 +195,11 @@ export interface IComponent extends IHasGuid {
|
|
|
196
195
|
/** @internal */
|
|
197
196
|
__internalStart();
|
|
198
197
|
/** @internal */
|
|
199
|
-
__internalEnable(
|
|
198
|
+
__internalEnable(isHierarchyChange?: boolean);
|
|
200
199
|
/** @internal */
|
|
201
|
-
__internalDisable(
|
|
200
|
+
__internalDisable(isHierarchyChange?: boolean);
|
|
202
201
|
/** @internal */
|
|
203
202
|
__internalDestroy();
|
|
204
|
-
/** @internal */
|
|
205
|
-
resolveGuids?(guidsMap: GuidsMap): void;
|
|
206
203
|
|
|
207
204
|
/** experimental, called when the script is registered for the first time, this is called even if the component is not enabled. */
|
|
208
205
|
registering?();
|
|
@@ -240,14 +237,14 @@ export interface IComponent extends IHasGuid {
|
|
|
240
237
|
}
|
|
241
238
|
|
|
242
239
|
export function isComponent(obj: any): obj is IComponent {
|
|
243
|
-
return obj && obj.isComponent;
|
|
240
|
+
return obj && typeof obj === "object" && obj.isComponent;
|
|
244
241
|
}
|
|
245
242
|
|
|
246
243
|
export type ICamera = CameraComponent;
|
|
247
244
|
|
|
248
245
|
export type IAnimationComponent = Pick<IComponent, "gameObject"> & {
|
|
249
246
|
isAnimationComponent: boolean;
|
|
250
|
-
addClip?(clip: AnimationClip);
|
|
247
|
+
addClip?(clip: AnimationClip): void;
|
|
251
248
|
}
|
|
252
249
|
|
|
253
250
|
/** Interface for a camera controller component that can be attached to a camera to control it */
|
|
@@ -274,7 +271,10 @@ export declare interface IRenderer extends IComponent {
|
|
|
274
271
|
|
|
275
272
|
export declare interface IEventList {
|
|
276
273
|
readonly isEventList: true;
|
|
277
|
-
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export declare interface ISignalReceiver {
|
|
277
|
+
readonly isSignalReceiver: true;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
// export declare interface IPhysicsComponent extends IComponent {
|
|
@@ -302,12 +302,18 @@ export declare interface ICollider extends IComponent {
|
|
|
302
302
|
* Default: [0]
|
|
303
303
|
*/
|
|
304
304
|
membership?: number[];
|
|
305
|
-
/** The collider filter indicates what groups the collider can interact with (e.g. group 3 and 4)
|
|
306
|
-
* An `undefined` array indicates that the collider can interact with all groups
|
|
307
|
-
* Note: Make sure to call updateProperties after having changed this property
|
|
305
|
+
/** The collider filter indicates what groups the collider can interact with (e.g. group 3 and 4)
|
|
306
|
+
* An `undefined` array indicates that the collider can interact with all groups
|
|
307
|
+
* Note: Make sure to call updateProperties after having changed this property
|
|
308
308
|
* Default: undefined
|
|
309
309
|
*/
|
|
310
310
|
filter?: number[];
|
|
311
|
+
/** The density of the collider used for automatic mass calculation.
|
|
312
|
+
* When the attached Rigidbody has `autoMass` enabled, the mass is computed as `density × volume`.
|
|
313
|
+
* Note: Make sure to call updateProperties after having changed this property
|
|
314
|
+
* Default: undefined (uses physics engine default of 1.0)
|
|
315
|
+
*/
|
|
316
|
+
density?: number;
|
|
311
317
|
}
|
|
312
318
|
|
|
313
319
|
export declare interface ISphereCollider extends ICollider {
|
|
@@ -475,8 +481,10 @@ export interface IPhysicsEngine {
|
|
|
475
481
|
postStep();
|
|
476
482
|
/** Indicates whether the physics engine is currently updating */
|
|
477
483
|
get isUpdating(): boolean;
|
|
478
|
-
/**
|
|
479
|
-
|
|
484
|
+
/** Tears down the physics world and frees all resources. The world will be re-created on next use. */
|
|
485
|
+
dispose(): void;
|
|
486
|
+
/** @deprecated Use {@link dispose} instead. */
|
|
487
|
+
clearCaches(): void;
|
|
480
488
|
|
|
481
489
|
/** Enables or disables the physics engine */
|
|
482
490
|
enabled: boolean;
|
|
@@ -738,8 +746,9 @@ export interface IPhysicsEngine {
|
|
|
738
746
|
getBody(obj: ICollider | IRigidbody): null | any;
|
|
739
747
|
|
|
740
748
|
// Joints
|
|
741
|
-
addFixedJoint(body1: IRigidbody, body2: IRigidbody);
|
|
742
|
-
addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: Vec3, axis: Vec3);
|
|
749
|
+
addFixedJoint(body1: IRigidbody, body2: IRigidbody): Promise<any> | any;
|
|
750
|
+
addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: Vec3, axis: Vec3): Promise<any> | any;
|
|
751
|
+
removeJoint(joint: any): void;
|
|
743
752
|
|
|
744
753
|
/** Enable to render collider shapes */
|
|
745
754
|
debugRenderColliders: boolean;
|
|
@@ -79,8 +79,12 @@ function createPropertyWrapper(target: IComponent | any, _propertyKey: string |
|
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
//
|
|
83
|
-
|
|
82
|
+
// Only install the getter/setter once per instance.
|
|
83
|
+
// processStart may call __internalAwake again for components that were inactive
|
|
84
|
+
// during processNewScripts — the base Component.__internalAwake has a __didAwake guard
|
|
85
|
+
// but this decorator wrapper runs before reaching it, so we need our own idempotency check.
|
|
86
|
+
const desc = Object.getOwnPropertyDescriptor(this, propertyKey);
|
|
87
|
+
if (!desc || !desc.get) {
|
|
84
88
|
|
|
85
89
|
// make sure the field is initialized in a hidden property
|
|
86
90
|
this[$prop] = this[propertyKey];
|
|
@@ -99,6 +103,7 @@ function createPropertyWrapper(target: IComponent | any, _propertyKey: string |
|
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
Object.defineProperty(this, propertyKey, {
|
|
106
|
+
configurable: true,
|
|
102
107
|
set: function (v) {
|
|
103
108
|
if (this[$isAssigningProperties] === true) {
|
|
104
109
|
this[$prop] = v;
|
|
@@ -279,24 +279,35 @@ declare type deepClonePredicate = (owner: any, propertyName: string, current: an
|
|
|
279
279
|
* return true;
|
|
280
280
|
* });
|
|
281
281
|
* */
|
|
282
|
-
export function deepClone(obj: any, predicate?: deepClonePredicate): any {
|
|
282
|
+
export function deepClone(obj: any, predicate?: deepClonePredicate, _visited?: WeakSet<object>): any {
|
|
283
283
|
if (obj !== null && obj !== undefined && typeof obj === "object") {
|
|
284
|
+
if (!_visited) _visited = new WeakSet();
|
|
285
|
+
if (_visited.has(obj)) return obj;
|
|
286
|
+
_visited.add(obj);
|
|
287
|
+
|
|
284
288
|
let clone;
|
|
285
289
|
if (Array.isArray(obj)) clone = [];
|
|
286
290
|
else {
|
|
287
|
-
clone = Object.create(obj);
|
|
288
|
-
|
|
291
|
+
clone = Object.create(Object.getPrototypeOf(obj));
|
|
292
|
+
// Copy own properties, skipping getter-only properties that can't be set
|
|
293
|
+
const descriptors = Object.getOwnPropertyDescriptors(obj);
|
|
294
|
+
for (const key in descriptors) {
|
|
295
|
+
const desc = descriptors[key];
|
|
296
|
+
if (desc.set || desc.writable !== false) {
|
|
297
|
+
try { clone[key] = obj[key]; }
|
|
298
|
+
catch { /* skip read-only properties */ }
|
|
299
|
+
}
|
|
300
|
+
}
|
|
289
301
|
}
|
|
290
302
|
for (const key of Object.keys(obj)) {
|
|
291
303
|
const val = obj[key];
|
|
292
304
|
if (predicate && !predicate(obj, key, val)) {
|
|
293
|
-
// console.log("SKIP", val);
|
|
294
305
|
clone[key] = val;
|
|
295
306
|
}
|
|
296
307
|
else if (val?.clone !== undefined && typeof val.clone === "function")
|
|
297
308
|
clone[key] = val.clone();
|
|
298
309
|
else
|
|
299
|
-
clone[key] = deepClone(val, predicate);
|
|
310
|
+
clone[key] = deepClone(val, predicate, _visited);
|
|
300
311
|
}
|
|
301
312
|
return clone;
|
|
302
313
|
}
|
|
@@ -35,7 +35,7 @@ export class GenerateMeshBVHWorker extends WorkerBase {
|
|
|
35
35
|
|
|
36
36
|
worker.onerror = e => {
|
|
37
37
|
|
|
38
|
-
reject(new Error(`[GenerateMeshBVHWorker] ${e.message || "
|
|
38
|
+
reject(new Error(`[GenerateMeshBVHWorker] ${e.message || "Could not load worker."}`));
|
|
39
39
|
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { showBalloonMessage } from "../../debug/debug.js";
|
|
2
|
-
import { HTMLElementBase } from "../../engine_ssr.js";
|
|
3
2
|
import type { Context } from "../../engine_context.js";
|
|
4
3
|
import { hasCommercialLicense, onLicenseCheckResultChanged, Telemetry } from "../../engine_license.js";
|
|
5
4
|
import { isLocalNetwork } from "../../engine_networking_utils.js";
|
|
5
|
+
import { HTMLElementBase } from "../../engine_ssr.js";
|
|
6
6
|
import { DeviceUtilities, getParam } from "../../engine_utils.js";
|
|
7
7
|
import { onXRSessionStart, XRSessionEventArgs } from "../../xr/events.js";
|
|
8
8
|
import { ButtonsFactory } from "../buttons.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
|
|
2
|
-
import { HTMLElementBase } from "../engine_ssr.js";
|
|
3
2
|
import { PUBLIC_KEY, VERSION } from "../engine_constants.js";
|
|
4
3
|
import { ContextEvent, ContextRegistry } from "../engine_context_registry.js";
|
|
5
4
|
import { hasCommercialLicense } from "../engine_license.js";
|
|
6
5
|
import { onStart } from "../engine_lifecycle_api.js";
|
|
7
6
|
import { setDracoDecoderPath, setDracoDecoderType, setKtx2TranscoderPath } from "../engine_loaders.gltf.js";
|
|
8
7
|
import { Context, ContextCreateArgs } from "../engine_setup.js";
|
|
8
|
+
import { HTMLElementBase } from "../engine_ssr.js";
|
|
9
9
|
import { nameToThreeTonemapping } from "../engine_tonemapping.js";
|
|
10
10
|
import { type INeedleEngineComponent, type LoadedModel } from "../engine_types.js";
|
|
11
11
|
import type { addAttributeChangeCallback } from "../engine_utils.js";
|
|
@@ -42,11 +42,17 @@ export interface NeedleEngineAttributes {
|
|
|
42
42
|
'hash': string;
|
|
43
43
|
/** Set to automatically add OrbitControls to the loaded scene. */
|
|
44
44
|
'camera-controls': string;
|
|
45
|
-
/** Override the default
|
|
45
|
+
/** Override the default Draco decoder/decompressor path. Can be a URL or a local path to a directory containing the Draco decoder files.
|
|
46
|
+
* @default "https://www.gstatic.com/draco/versioned/decoders/1.5.7/"
|
|
47
|
+
* @example <needle-engine dracoDecoderPath="./decoders/draco/"></needle-engine>
|
|
48
|
+
*/
|
|
46
49
|
'dracoDecoderPath': string;
|
|
47
|
-
/** Override the default
|
|
50
|
+
/** Override the default Draco decoder type. */
|
|
48
51
|
'dracoDecoderType': 'wasm' | 'js';
|
|
49
|
-
/** Override the default KTX2 transcoder/decoder path.
|
|
52
|
+
/** Override the default KTX2 transcoder/decoder path. Can be a URL or a local path to a directory containing the KTX2 transcoder files.
|
|
53
|
+
* @default "https://cdn.needle.tools/static/three/0.179.1/basis2/"
|
|
54
|
+
* @example <needle-engine ktx2DecoderPath="./decoders/ktx2/"></needle-engine>
|
|
55
|
+
*/
|
|
50
56
|
'ktx2DecoderPath': string;
|
|
51
57
|
/** Prevent context from being disposed when element is removed from DOM. */
|
|
52
58
|
'keep-alive': 'true' | 'false';
|