@needle-tools/engine 2.36.0-pre → 2.37.0-pre

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 (102) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/needle-engine.d.ts +171 -141
  3. package/dist/needle-engine.js +451 -437
  4. package/dist/needle-engine.js.map +4 -4
  5. package/dist/needle-engine.min.js +82 -82
  6. package/dist/needle-engine.min.js.map +4 -4
  7. package/lib/engine/api.d.ts +1 -0
  8. package/lib/engine/api.js +1 -0
  9. package/lib/engine/api.js.map +1 -1
  10. package/lib/engine/debug/debug.d.ts +1 -0
  11. package/lib/engine/debug/debug.js +3 -0
  12. package/lib/engine/debug/debug.js.map +1 -1
  13. package/lib/engine/engine_gameobject.js +2 -1
  14. package/lib/engine/engine_gameobject.js.map +1 -1
  15. package/lib/engine/engine_physics.d.ts +33 -42
  16. package/lib/engine/engine_physics.js +431 -383
  17. package/lib/engine/engine_physics.js.map +1 -1
  18. package/lib/engine/engine_physics.types.d.ts +16 -0
  19. package/lib/engine/engine_physics.types.js +19 -0
  20. package/lib/engine/engine_physics.types.js.map +1 -0
  21. package/lib/engine/engine_serialization_core.d.ts +3 -0
  22. package/lib/engine/engine_serialization_core.js +5 -0
  23. package/lib/engine/engine_serialization_core.js.map +1 -1
  24. package/lib/engine/engine_setup.js +3 -1
  25. package/lib/engine/engine_setup.js.map +1 -1
  26. package/lib/engine/engine_types.d.ts +45 -26
  27. package/lib/engine/engine_types.js +24 -37
  28. package/lib/engine/engine_types.js.map +1 -1
  29. package/lib/engine/engine_util_decorator.d.ts +6 -0
  30. package/lib/engine/engine_util_decorator.js +54 -0
  31. package/lib/engine/engine_util_decorator.js.map +1 -0
  32. package/lib/engine/engine_utils.d.ts +1 -1
  33. package/lib/engine/engine_utils.js +1 -1
  34. package/lib/engine/engine_utils.js.map +1 -1
  35. package/lib/engine/extensions/NEEDLE_gameobject_data.js +2 -0
  36. package/lib/engine/extensions/NEEDLE_gameobject_data.js.map +1 -1
  37. package/lib/engine-components/Animation.d.ts +6 -5
  38. package/lib/engine-components/Animation.js +0 -7
  39. package/lib/engine-components/Animation.js.map +1 -1
  40. package/lib/engine-components/BoxHelperComponent.js +1 -0
  41. package/lib/engine-components/BoxHelperComponent.js.map +1 -1
  42. package/lib/engine-components/Collider.d.ts +7 -2
  43. package/lib/engine-components/Collider.js +27 -15
  44. package/lib/engine-components/Collider.js.map +1 -1
  45. package/lib/engine-components/Component.d.ts +6 -15
  46. package/lib/engine-components/Component.js +7 -112
  47. package/lib/engine-components/Component.js.map +1 -1
  48. package/lib/engine-components/DragControls.js +9 -6
  49. package/lib/engine-components/DragControls.js.map +1 -1
  50. package/lib/engine-components/NavMesh.d.ts +0 -5
  51. package/lib/engine-components/NavMesh.js +100 -10
  52. package/lib/engine-components/NavMesh.js.map +1 -1
  53. package/lib/engine-components/NestedGltf.js +2 -0
  54. package/lib/engine-components/NestedGltf.js.map +1 -1
  55. package/lib/engine-components/RigidBody.d.ts +40 -25
  56. package/lib/engine-components/RigidBody.js +253 -142
  57. package/lib/engine-components/RigidBody.js.map +1 -1
  58. package/lib/engine-components/SpatialTrigger.js +1 -1
  59. package/lib/engine-components/SpatialTrigger.js.map +1 -1
  60. package/lib/engine-components/SpectatorCamera.d.ts +1 -0
  61. package/lib/engine-components/SpectatorCamera.js +9 -2
  62. package/lib/engine-components/SpectatorCamera.js.map +1 -1
  63. package/lib/engine-components/SpringJoint.d.ts +0 -13
  64. package/lib/engine-components/SpringJoint.js +42 -41
  65. package/lib/engine-components/SpringJoint.js.map +1 -1
  66. package/lib/engine-components/VideoPlayer.js.map +1 -1
  67. package/lib/engine-components/WebXR.d.ts +1 -0
  68. package/lib/engine-components/WebXR.js +10 -2
  69. package/lib/engine-components/WebXR.js.map +1 -1
  70. package/lib/engine-components/WebXRController.js +12 -6
  71. package/lib/engine-components/WebXRController.js.map +1 -1
  72. package/lib/engine-components/codegen/components.d.ts +1 -3
  73. package/lib/engine-components/codegen/components.js +1 -3
  74. package/lib/engine-components/codegen/components.js.map +1 -1
  75. package/package.json +3 -4
  76. package/src/engine/api.ts +2 -1
  77. package/src/engine/codegen/register_types.js +4 -12
  78. package/src/engine/debug/debug.ts +4 -0
  79. package/src/engine/engine_gameobject.ts +4 -4
  80. package/src/engine/engine_physics.ts +460 -421
  81. package/src/engine/engine_physics.types.ts +19 -0
  82. package/src/engine/engine_serialization_core.ts +8 -1
  83. package/src/engine/engine_setup.ts +5 -1
  84. package/src/engine/engine_types.ts +82 -56
  85. package/src/engine/engine_util_decorator.ts +69 -0
  86. package/src/engine/engine_utils.ts +3 -3
  87. package/src/engine/extensions/NEEDLE_gameobject_data.ts +2 -0
  88. package/src/engine-components/Animation.ts +10 -12
  89. package/src/engine-components/BoxHelperComponent.ts +1 -0
  90. package/src/engine-components/Collider.ts +29 -29
  91. package/src/engine-components/Component.ts +15 -130
  92. package/src/engine-components/DragControls.ts +9 -5
  93. package/src/engine-components/NavMesh.ts +114 -115
  94. package/src/engine-components/NestedGltf.ts +2 -0
  95. package/src/engine-components/RigidBody.ts +258 -149
  96. package/src/engine-components/SpatialTrigger.ts +1 -1
  97. package/src/engine-components/SpectatorCamera.ts +10 -2
  98. package/src/engine-components/SpringJoint.ts +41 -41
  99. package/src/engine-components/VideoPlayer.ts +1 -2
  100. package/src/engine-components/WebXR.ts +12 -2
  101. package/src/engine-components/WebXRController.ts +16 -7
  102. package/src/engine-components/codegen/components.ts +1 -3
@@ -1,234 +1,343 @@
1
1
  import { Behaviour } from "./Component";
2
- import { BodyOptions } from '../engine/engine_physics'
3
- import * as CANNON from 'cannon-es'
4
2
  import * as THREE from 'three'
5
3
  import { getWorldPosition } from "../engine/engine_three_utils";
6
4
  import { serializeable } from "../engine/engine_serialization_decorator";
7
5
  import { Watch } from "../engine/engine_utils";
8
- import { Vector3 } from "three";
6
+ import { Object3D, Vector3 } from "three";
9
7
  import { IRigidbody } from "../engine/engine_types";
8
+ import { CollisionDetectionMode, RigidbodyConstraints } from "../engine/engine_physics.types";
9
+ import { validate } from "../engine/engine_util_decorator";
10
+ import { Context } from "../engine/engine_setup";
11
+
12
+ class TransformWatch {
13
+
14
+ get isDirty(): boolean {
15
+ return this.positionChanged || this.rotationChanged;
16
+ }
17
+ positionChanged: boolean = false;
18
+ rotationChanged: boolean = false;
19
+ position?: Vector3;
20
+ quaternion?: THREE.Quaternion;
21
+
22
+ reset() {
23
+ this.positionChanged = false;
24
+ this.rotationChanged = false;
25
+ this.mute = false;
26
+ }
27
+
28
+ mute: boolean = false;
29
+
30
+ applyValues() {
31
+ if (this.positionChanged) {
32
+ this.obj.position.copy(this.position!)
33
+ }
34
+ if (this.rotationChanged) {
35
+ this.obj.quaternion.copy(this.quaternion!)
36
+ }
37
+ }
38
+
39
+ readonly context: Context;
40
+ readonly obj: Object3D;
41
+ private _positionWatch?: Watch;
42
+ private _rotationWatch?: Watch;
43
+
44
+ constructor(obj: Object3D, context: Context) {
45
+ this.context = context;
46
+ this.obj = obj;
47
+ }
48
+
49
+ start(position: boolean, rotation: boolean) {
50
+ this.reset();
51
+ if (position) {
52
+ if (!this._positionWatch)
53
+ this._positionWatch = new Watch(this.obj.position, ["x", "y", "z"]);
54
+ this._positionWatch.apply();
55
+ this.position = this.obj.position.clone();
56
+ this._positionWatch.subscribeWrite((val, prop) => {
57
+ if (this.context.physics.isUpdating || this.mute) return;
58
+ // if (this.position![prop] !== val) {
59
+ this.position![prop] = val;
60
+ this.positionChanged = true;
61
+ // }
62
+ })
63
+ }
64
+ if (rotation) {
65
+ if (!this._rotationWatch)
66
+ this._rotationWatch = new Watch(this.obj.quaternion, ["_x", "_y", "_z", "_w"]);
67
+ this._rotationWatch.apply();
68
+ this.quaternion = this.obj.quaternion.clone();
69
+ this._rotationWatch.subscribeWrite((val, prop) => {
70
+ if (this.context.physics.isUpdating || this.mute) return;
71
+ // if (this.quaternion![prop] !== val) {
72
+ this.quaternion![prop] = val;
73
+ this.rotationChanged = true;
74
+ // }
75
+ })
76
+ }
77
+ }
78
+
79
+ stop() {
80
+ this._positionWatch?.revoke();
81
+ this._rotationWatch?.revoke();
82
+ }
83
+ }
84
+
10
85
 
11
86
  export class Rigidbody extends Behaviour implements IRigidbody {
12
87
 
88
+ @validate()
13
89
  @serializeable()
14
90
  mass: number = 1;
15
91
 
92
+ @validate()
16
93
  @serializeable()
17
- public set isKinematic(kinematic: boolean) {
18
- this._isKinematic = kinematic;
19
- if (this._body) {
20
- this._body.type = kinematic ? CANNON.Body.KINEMATIC : CANNON.Body.DYNAMIC;
21
- }
22
- }
94
+ useGravity: boolean = true;
23
95
 
24
- public get isKinematic(): boolean {
25
- return this._isKinematic;
26
- }
27
- private _isKinematic: boolean = false;
96
+ @validate()
97
+ @serializeable()
98
+ constraints: RigidbodyConstraints = RigidbodyConstraints.None;
99
+
100
+ @validate()
101
+ @serializeable()
102
+ isKinematic: boolean = false;
28
103
 
104
+ @validate()
29
105
  @serializeable()
30
106
  drag: number = 0;
107
+
108
+ @validate()
31
109
  @serializeable()
32
110
  angularDrag: number = 1;
111
+
112
+ @validate()
33
113
  @serializeable()
34
114
  detectCollisions: boolean = true;
115
+
116
+ @validate()
35
117
  @serializeable()
36
118
  sleepThreshold: number = 0.01;
37
119
 
120
+ @validate()
121
+ @serializeable()
122
+ collisionDetectionMode: CollisionDetectionMode = CollisionDetectionMode.Discrete;
123
+
124
+ get lockPositionX() {
125
+ return (this.constraints & RigidbodyConstraints.FreezePositionX) !== 0;
126
+ }
127
+ get lockPositionY() {
128
+ return (this.constraints & RigidbodyConstraints.FreezePositionY) !== 0;
129
+ }
130
+ get lockPositionZ() {
131
+ return (this.constraints & RigidbodyConstraints.FreezePositionZ) !== 0;
132
+ }
133
+ get lockRotationX() {
134
+ return (this.constraints & RigidbodyConstraints.FreezeRotationX) !== 0;
135
+ }
136
+ get lockRotationY() {
137
+ return (this.constraints & RigidbodyConstraints.FreezeRotationY) !== 0;
138
+ }
139
+ get lockRotationZ() {
140
+ return (this.constraints & RigidbodyConstraints.FreezeRotationZ) !== 0;
141
+ }
38
142
 
39
- get body(): CANNON.Body | null {
40
- if (this._body === null) {
41
- this.initialize();
42
- }
43
- return this._body;
143
+ set lockPositionX(v: boolean) {
144
+ if (v) this.constraints |= RigidbodyConstraints.FreezePositionX;
145
+ else this.constraints &= ~RigidbodyConstraints.FreezePositionX;
146
+ }
147
+ set lockPositionY(v: boolean) {
148
+ if (v) this.constraints |= RigidbodyConstraints.FreezePositionY;
149
+ else this.constraints &= ~RigidbodyConstraints.FreezePositionY;
150
+ }
151
+ set lockPositionZ(v: boolean) {
152
+ if (v) this.constraints |= RigidbodyConstraints.FreezePositionZ;
153
+ else this.constraints &= ~RigidbodyConstraints.FreezePositionZ;
154
+ }
155
+ set lockRotationX(v: boolean) {
156
+ if (v) this.constraints |= RigidbodyConstraints.FreezeRotationX;
157
+ else this.constraints &= ~RigidbodyConstraints.FreezeRotationX;
158
+ }
159
+ set lockRotationY(v: boolean) {
160
+ if (v) this.constraints |= RigidbodyConstraints.FreezeRotationY;
161
+ else this.constraints &= ~RigidbodyConstraints.FreezeRotationY;
162
+ }
163
+ set lockRotationZ(v: boolean) {
164
+ if (v) this.constraints |= RigidbodyConstraints.FreezeRotationZ;
165
+ else this.constraints &= ~RigidbodyConstraints.FreezeRotationZ;
44
166
  }
45
167
 
168
+ private _propertiesChanged: boolean = false;
46
169
  private static tempPosition: THREE.Vector3 = new THREE.Vector3();
47
- private _body: CANNON.Body | null = null;
48
- private currentVelocity!: THREE.Vector3;
170
+ private _currentVelocity!: THREE.Vector3;
49
171
  private _smoothedVelocity!: THREE.Vector3;
50
- private lastWorldPosition!: THREE.Vector3;
172
+ private _smoothedVelocityGetter!: THREE.Vector3;
173
+ private _lastPosition!: THREE.Vector3;
51
174
 
52
- private _ignoreChange: boolean = false;
53
- private _dirty: boolean = false;
54
-
55
- private _positionWatch?: Watch;
56
- private _matrixWatch?: Watch;
57
- private _setMatrix: THREE.Matrix4;
175
+ private _watch?: TransformWatch;
58
176
 
59
- constructor() {
60
- super();
61
- this._setMatrix = new THREE.Matrix4();
62
- }
63
177
 
64
178
  awake() {
65
- this._body = null;
66
- this.currentVelocity = new THREE.Vector3();
179
+ this._watch = undefined;
180
+ this._currentVelocity = new THREE.Vector3();
67
181
  this._smoothedVelocity = new THREE.Vector3();
68
- this.lastWorldPosition = getWorldPosition(this.gameObject).clone();
69
- this._matrixWatch = undefined;
70
- this._positionWatch = undefined;
182
+ this._smoothedVelocityGetter = new THREE.Vector3();
183
+ this._lastPosition = new THREE.Vector3();
71
184
  }
72
185
 
73
- // start() {
74
- // this.setBodyFromGameObject();
75
- // }
76
-
77
186
  onEnable() {
78
- if (this._body) {
79
- this.context.physics.addBody(this.gameObject, this._body);
80
- }
81
- else
82
- this.initialize();
83
-
84
- if (this.body) {
85
- this.body.wakeUp();
86
- this.gameObject.updateWorldMatrix(true, false);
87
- this.setBodyFromGameObject();
187
+ if (!this._watch) {
188
+ this._watch = new TransformWatch(this.gameObject, this.context);
88
189
  }
89
-
90
- if (!this._positionWatch)
91
- this._positionWatch = new Watch(this.gameObject.position, ["x", "y", "z"]);
92
- this._positionWatch.subscribeWrite(_ => {
93
- if (!this.context.physics.isUpdating && !this._ignoreChange) {
94
- this._dirty = true;
95
- this._setMatrix.copy(this.gameObject.matrix);
96
- this._setMatrix.setPosition(this.gameObject.position);
97
- }
98
- })
190
+ this._watch.start(true, true);
99
191
  }
100
192
 
101
- onDisable(): void {
102
- if (this._body)
103
- this.context.physics.removeBody(this.gameObject, this._body, false);
193
+ onDisable() {
194
+ this._watch?.stop();
195
+ this.context.physics.removeBody(this);
104
196
  }
105
197
 
106
198
  onDestroy(): void {
107
- if (this._body)
108
- this.context.physics.removeBody(this.gameObject, this._body);
199
+ this.context.physics.removeBody(this);
109
200
  }
110
201
 
111
- onBeforeRender() {
112
- this._ignoreChange = true;
113
- this.updateVelocity();
202
+ onValidate() {
203
+ this._propertiesChanged = true;
204
+ }
114
205
 
115
- if (this._dirty) {
116
- this._dirty = false;
117
- this._setMatrix.decompose(this.gameObject.position, this.gameObject.quaternion, this.gameObject.scale);
118
- this.setBodyFromGameObject();
206
+ earlyUpdate() {
207
+ if (this._propertiesChanged) {
208
+ this._propertiesChanged = false;
209
+ this.context.physics.updateProperties(this);
210
+ }
211
+ if (this._watch?.isDirty) {
212
+ this._watch.mute = true;
213
+ this._watch.applyValues();
214
+ this.context.physics.updateBody(this, this._watch.positionChanged, this._watch.rotationChanged);
215
+ this._watch.reset();
119
216
  }
120
217
 
121
- this._ignoreChange = false;
218
+ this.captureVelocity();
122
219
  }
123
220
 
124
- initialize() {
125
- if (this._body) {
126
- return;
127
- }
128
- const options = new BodyOptions();
129
- options.drag = this.drag;
130
- options.angularDrag = this.angularDrag;
131
- options.mass = this.mass;
132
- options.kinematic = this.isKinematic;
133
- options.physicsEvents = this.detectCollisions;
134
- options.sleepThreshold = this.sleepThreshold;
135
- this._body = this.context.physics.createBody(this.gameObject, options);
221
+ private get body() {
222
+ return this.context.physics.internal_getRigidbody(this);
223
+ }
224
+
225
+ // TODO: we need to differentiate between setting a physics body to a new position and moving it where we also want to affect the velocity
226
+ // public teleport(){
227
+ // this.context.physics.updateBody(this);
228
+ // }
229
+
230
+ public resetForces() {
231
+ this.body?.resetForces(true);
136
232
  }
137
233
 
234
+ public resetTorques() {
235
+ this.body?.resetTorques(true);
236
+ }
237
+
238
+ public resetVelocities() {
239
+ this.setVelocity(0, 0, 0);
240
+ this.setAngularVelocity(0, 0, 0);
241
+ }
242
+
243
+ public resetForcesAndTorques() {
244
+ this.resetForces();
245
+ this.resetTorques();
246
+ }
138
247
 
139
248
  public wakeUp() {
140
249
  this.body?.wakeUp();
141
250
  }
142
251
 
143
- public applyForce(vec: THREE.Vector3, rel?: THREE.Vector3) {
144
- const force = new CANNON.Vec3(vec.x, vec.y, vec.z);
145
- force.scale(1 / this.context.time.deltaTime, force);
146
- this.body?.applyForce(force, rel ? new CANNON.Vec3(rel.x, rel.y, rel.z) : undefined);
252
+ public applyForce(vec: Vector3, _rel?: THREE.Vector3) {
253
+ this.body?.addForce(vec, true);
254
+ }
255
+
256
+ public applyImpulse(vec: Vector3) {
257
+ this.body?.applyImpulse(vec, true);
147
258
  }
148
259
 
149
260
  public setForce(x: number, y: number, z: number) {
150
- this.body?.force.set(x, y, z);
261
+ this.body?.resetForces(true);
262
+ this.body?.addForce({ x, y, z }, true);
151
263
  }
152
264
 
153
- public getVelocity(): THREE.Vector3 {
154
- if (this.body)
155
- return Rigidbody.tempPosition.set(this.body?.velocity.x, this.body?.velocity.y, this.body?.velocity.z);
156
- return Rigidbody.tempPosition.set(0, 0, 0);
265
+ public getVelocity(): Vector3 {
266
+ const vel = this.body?.linvel();
267
+ if (!vel) return this._currentVelocity.set(0, 0, 0);
268
+ this._currentVelocity.x = vel.x;
269
+ this._currentVelocity.y = vel.y;
270
+ this._currentVelocity.z = vel.z;
271
+ return this._currentVelocity;
157
272
  }
158
273
 
159
- public setVelocity(x: number | Vector3, y: number, z: number) {
160
- if (!this.body) return;
274
+ public setVelocity(x: number | Vector3, y?: number, z?: number) {
161
275
  if (x instanceof Vector3) {
162
276
  const vec = x;
163
- x = vec.x;
164
- y = vec.y;
165
- z = vec.z;
277
+ this.body?.setLinvel(vec, true);
278
+ return;
166
279
  }
167
- this.body.velocity.x = x / this.context.time.deltaTime;
168
- this.body.velocity.y = y / this.context.time.deltaTime;
169
- this.body.velocity.z = z / this.context.time.deltaTime;
170
- }
171
-
172
- public getTorque(): THREE.Vector3 {
173
- if (this.body)
174
- return Rigidbody.tempPosition.set(this.body?.torque.x, this.body?.torque.y, this.body?.torque.z);
175
- return Rigidbody.tempPosition.set(0, 0, 0);
280
+ if (y === undefined || z === undefined) return;
281
+ this.body?.setLinvel({ x: x, y: y, z: z }, true);
176
282
  }
177
283
 
178
- public setTorque(x: number | Vector3, y: number, z: number) {
179
- if (!this.body) return;
284
+ public setAngularVelocity(x: number | Vector3, y?: number, z?: number) {
180
285
  if (x instanceof Vector3) {
181
286
  const vec = x;
182
- x = vec.x;
183
- y = vec.y;
184
- z = vec.z;
287
+ this.body?.setAngvel(vec, true);
288
+ return;
185
289
  }
186
- this.body.torque.x = x / this.context.time.deltaTime;
187
- this.body.torque.y = y / this.context.time.deltaTime;
188
- this.body.torque.z = z / this.context.time.deltaTime;
189
-
290
+ if (y === undefined || z === undefined) return;
291
+ this.body?.setAngvel({ x: x, y: y, z: z }, true);
190
292
  }
191
293
 
192
- public get smoothedVelocity() { return this._smoothedVelocity; }
193
-
194
- public setAngularVelocity(x: number, y: number, z: number) {
195
- if (!this.body) return;
196
- this.body.angularVelocity.x = x / this.context.time.deltaTime;
197
- this.body.angularVelocity.y = y / this.context.time.deltaTime;
198
- this.body.angularVelocity.z = z / this.context.time.deltaTime;
294
+ public setTorque(x: number | Vector3, y: number, z: number) {
295
+ this.setAngularVelocity(x, y, z);
199
296
  }
200
297
 
201
- private static copyVector3: THREE.Vector3 = new THREE.Vector3();
202
-
203
-
204
- public setBodyFromGameObject(velocity: THREE.Vector3 | null | { x: number, y: number, z: number } = null) {
205
- if (this.body && this.gameObject && !this.destroyed) {
206
- this._ignoreChange = true;
207
- const wp = this.worldPosition;
208
- this.body.position.set(wp.x, wp.y, wp.z);
209
- const wr = this.worldQuaternion;
210
- this.body.quaternion.set(wr.x, wr.y, wr.z, wr.w);
298
+ public get smoothedVelocity(): Vector3 {
299
+ this._smoothedVelocityGetter.copy(this._smoothedVelocity);
300
+ return this._smoothedVelocityGetter.multiplyScalar(1 / this.context.time.deltaTime);
301
+ }
211
302
 
212
- if (velocity) {
213
- Rigidbody.copyVector3.set(velocity.x, velocity.y, velocity.z);
214
- this._smoothedVelocity.lerp(Rigidbody.copyVector3, this.context.time.deltaTime / .1);
215
- const sm = this._smoothedVelocity;
216
- this.body.velocity.x = sm.x;
217
- this.body.velocity.y = sm.y;
218
- this.body.velocity.z = sm.z;
219
- }
220
- this._ignoreChange = false;
303
+ // public get smoothedVelocity() { return this._smoothedVelocity; }
304
+
305
+
306
+
307
+ /**d
308
+ * @deprecated not used anymore
309
+ */
310
+ public setBodyFromGameObject(_velocity: THREE.Vector3 | null | { x: number, y: number, z: number } = null) {
311
+ if (this.gameObject && !this.destroyed) {
312
+ // this.context.physics.updateBody(this);
313
+ // this._ignoreChange = true;
314
+ // const wp = this.worldPosition;
315
+ // this.body.position.set(wp.x, wp.y, wp.z);
316
+ // const wr = this.worldQuaternion;
317
+ // this.body.quaternion.set(wr.x, wr.y, wr.z, wr.w);
318
+
319
+ // if (velocity) {
320
+ // Rigidbody.copyVector3.set(velocity.x, velocity.y, velocity.z);
321
+ // this._smoothedVelocity.lerp(Rigidbody.copyVector3, this.context.time.deltaTime / .1);
322
+ // const sm = this._smoothedVelocity;
323
+ // this.body.velocity.x = sm.x;
324
+ // this.body.velocity.y = sm.y;
325
+ // this.body.velocity.z = sm.z;
326
+ // }
327
+ // this._ignoreChange = false;
221
328
  }
222
329
  }
223
330
 
224
331
 
225
- private updateVelocity() {
226
- if (!this.currentVelocity) return;
227
- if (this.body && this.gameObject) {
332
+
333
+ private captureVelocity() {
334
+ if (this.body) {
228
335
  const wp = getWorldPosition(this.gameObject);
229
- this.currentVelocity.subVectors(wp, this.lastWorldPosition);
230
- this.lastWorldPosition.copy(wp);
231
- this._smoothedVelocity.lerp(this.currentVelocity, this.context.time.deltaTime / .1);
336
+ Rigidbody.tempPosition.copy(wp);
337
+ const vel = wp.sub(this._lastPosition);
338
+ this._lastPosition.copy(Rigidbody.tempPosition);
339
+ this._smoothedVelocity.lerp(vel, this.context.time.deltaTime / .1);
340
+ // this._smoothedVelocity.set(0, 1 / this.context.time.deltaTime, 0);
232
341
  }
233
342
  }
234
343
  }
@@ -95,7 +95,7 @@ export class SpatialTrigger extends Behaviour {
95
95
  SpatialTrigger.triggers.push(this);
96
96
  if (!this.boxHelper) {
97
97
  this.boxHelper = GameObject.addNewComponent(this.gameObject, BoxHelperComponent);
98
- this.boxHelper?.showHelper();
98
+ this.boxHelper?.showHelper(null, debug as boolean);
99
99
  }
100
100
  }
101
101
  onDisable(): void {
@@ -61,6 +61,10 @@ export class SpectatorCamera extends Behaviour {
61
61
  this.target = undefined;
62
62
  }
63
63
 
64
+ private get localId() : string {
65
+ return this.context.connection.connectionId ?? "local";
66
+ }
67
+
64
68
  /** player view to follow */
65
69
  set target(target: PlayerView | undefined) {
66
70
  if (this._handler) {
@@ -74,7 +78,7 @@ export class SpectatorCamera extends Behaviour {
74
78
  // }
75
79
 
76
80
  const prev = this._handler.currentTarget?.userId;
77
- const self = this.context.players.getPlayerView(this.context.connection.connectionId);
81
+ const self = this.context.players.getPlayerView(this.localId);
78
82
 
79
83
  // if user is in XR and sets target to self disable it
80
84
  if (target === undefined || (this.context.isInXR === false && self?.currentObject === target.currentObject)) {
@@ -103,7 +107,7 @@ export class SpectatorCamera extends Behaviour {
103
107
  }
104
108
 
105
109
  private get isSpectatingSelf() {
106
- return this.isSpectating && this.target?.currentObject === this.context.players.getPlayerView(this.context.connection.connectionId)?.currentObject;
110
+ return this.isSpectating && this.target?.currentObject === this.context.players.getPlayerView(this.localId)?.currentObject;
107
111
  }
108
112
 
109
113
  // private currentViewport : THREE.Vector4 = new THREE.Vector4();
@@ -191,6 +195,10 @@ export class SpectatorCamera extends Behaviour {
191
195
 
192
196
  private followSelf() {
193
197
  this.target = this.context.players.getPlayerView(this.context.connection.connectionId);
198
+ if (!this.target) {
199
+ this.context.players.setPlayerView(this.localId, this.context.mainCamera, ViewDevice.Headset);
200
+ this.target = this.context.players.getPlayerView(this.localId);
201
+ }
194
202
  if (debug) console.log("Follow self", this.target);
195
203
  }
196
204
 
@@ -1,45 +1,45 @@
1
- import { Behaviour, GameObject } from "./Component";
2
- import { Rigidbody } from "./RigidBody";
3
- import * as CANNON from 'cannon-es'
4
- import { Vector3 } from "three";
1
+ // import { Behaviour, GameObject } from "./Component";
2
+ // import { Rigidbody } from "./RigidBody";
3
+ // import * as CANNON from 'cannon-es'
4
+ // import { Vector3 } from "three";
5
5
 
6
- export class SpringJoint extends Behaviour {
7
- anchor: Vector3 | null = null;
8
- connectedBody: Rigidbody | null = null;
9
- connectedAnchor: Vector3 | null = null;
10
- spring: number = 10;
11
- damper: number = .2;
6
+ // export class SpringJoint extends Behaviour {
7
+ // anchor: Vector3 | null = null;
8
+ // connectedBody: Rigidbody | null = null;
9
+ // connectedAnchor: Vector3 | null = null;
10
+ // spring: number = 10;
11
+ // damper: number = .2;
12
12
 
13
- private rb : Rigidbody | null = null;
13
+ // private rb : Rigidbody | null = null;
14
14
 
15
- awake(): void {
16
- this.rb = GameObject.getComponent(this.gameObject, Rigidbody);
17
- if(!this.connectedBody || !this.connectedBody.body || !this.rb || !this.rb.body) return;
18
- this.connectedBody.body.mass = Math.min(this.rb.body.mass*.99, this.connectedBody.body.mass);
19
- const spring = new CANNON.Spring(this.rb.body, this.connectedBody.body, {
20
- // localAnchorA: new CANNON.Vec3(-1, 1, 0),
21
- // localAnchorB: new CANNON.Vec3(0, 0, 0),
22
- // restLength: -.1,
23
- // stiffness: 10,
24
- // damping: .2,
25
- restLength: 0.01,
26
- stiffness: this.spring*.5,
27
- damping: this.damper,
28
- // localAnchorA: new CANNON.Vec3(this.anchor.x, this.anchor.y, this.anchor.z),
29
- // localAnchorB: new CANNON.Vec3(
30
- // this.connectedAnchor.x,
31
- // this.connectedAnchor.y,
32
- // this.connectedAnchor.z
33
- // ),
34
- });
35
- this.context.physics.addPostStepListener(_ => {
36
- // const wp = this.connectedBody.worldPosition;
37
- // console.log(wp.y, this.connectedBody.body.position.y, this.rb.body.position.y);
38
- spring.applyForce();
39
- });
40
- }
15
+ // awake(): void {
16
+ // this.rb = GameObject.getComponent(this.gameObject, Rigidbody);
17
+ // if(!this.connectedBody || !this.connectedBody.body || !this.rb || !this.rb.body) return;
18
+ // this.connectedBody.body.mass = Math.min(this.rb.body.mass*.99, this.connectedBody.body.mass);
19
+ // const spring = new CANNON.Spring(this.rb.body, this.connectedBody.body, {
20
+ // // localAnchorA: new CANNON.Vec3(-1, 1, 0),
21
+ // // localAnchorB: new CANNON.Vec3(0, 0, 0),
22
+ // // restLength: -.1,
23
+ // // stiffness: 10,
24
+ // // damping: .2,
25
+ // restLength: 0.01,
26
+ // stiffness: this.spring*.5,
27
+ // damping: this.damper,
28
+ // // localAnchorA: new CANNON.Vec3(this.anchor.x, this.anchor.y, this.anchor.z),
29
+ // // localAnchorB: new CANNON.Vec3(
30
+ // // this.connectedAnchor.x,
31
+ // // this.connectedAnchor.y,
32
+ // // this.connectedAnchor.z
33
+ // // ),
34
+ // });
35
+ // this.context.physics.addPostStepListener(_ => {
36
+ // // const wp = this.connectedBody.worldPosition;
37
+ // // console.log(wp.y, this.connectedBody.body.position.y, this.rb.body.position.y);
38
+ // spring.applyForce();
39
+ // });
40
+ // }
41
41
 
42
- update(): void {
43
- // console.log(this.worldPosition.y)
44
- }
45
- }
42
+ // update(): void {
43
+ // // console.log(this.worldPosition.y)
44
+ // }
45
+ // }
@@ -1,8 +1,7 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
2
  import * as THREE from "three";
3
- import { Material } from "material/Material";
4
3
  import { serializeable } from "../engine/engine_serialization_decorator";
5
- import { LinearFilter, Mesh, Object3D, RawShaderMaterial, ShaderMaterial, Texture, TextureLoader, Vector2, Vector4, VideoTexture } from "three";
4
+ import { LinearFilter, Material, Mesh, Object3D, RawShaderMaterial, ShaderMaterial, Texture, TextureLoader, Vector2, Vector4, VideoTexture } from "three";
6
5
  import { awaitInput } from "../engine/engine_input_utils";
7
6
  import { getParam } from "../engine/engine_utils";
8
7
  import { Renderer } from "./Renderer";
@@ -461,6 +461,7 @@ export class WebAR {
461
461
  private _webxr: WebXR;
462
462
 
463
463
  private reticle: Object3D | null = null;
464
+ private reticleParent: Object3D | null = null;
464
465
  private hitTestSource: XRHitTestSource | null = null;
465
466
  private reticleActive: boolean = true;
466
467
 
@@ -535,9 +536,18 @@ export class WebAR {
535
536
  this.reticle.name = "AR Placement reticle";
536
537
  this.reticle.matrixAutoUpdate = false;
537
538
  this.reticle.visible = false;
539
+
540
+ // create AR reticle parent to allow WebXRSessionRoot to be translated, rotated or scaled
541
+ this.reticleParent = new Object3D();
542
+ this.reticleParent.name = "AR Reticle Parent";
543
+ this.reticleParent.matrixAutoUpdate = false;
544
+ this.reticleParent.add(this.reticle);
545
+ this.reticleParent.matrix.copy(this.sessionRoot.gameObject.matrixWorld);
546
+
538
547
  if (this.webxr.scene) {
539
- this.webxr.scene.add(this.reticle);
540
- this.webxr.scene.visible = true;
548
+ this.context.scene.add(this.reticleParent);
549
+ // this.context.scene.add(this.reticle);
550
+ this.context.scene.visible = true;
541
551
  }
542
552
  else console.warn("Could not found WebXR Rig");
543
553
  }