@needle-tools/engine 3.37.3-alpha → 3.37.4-alpha

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 (39) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +5 -3
  3. package/dist/needle-engine.js +115 -94
  4. package/dist/needle-engine.light.js +1220 -1199
  5. package/dist/needle-engine.light.min.js +108 -95
  6. package/dist/needle-engine.light.umd.cjs +133 -120
  7. package/dist/needle-engine.min.js +37 -24
  8. package/dist/needle-engine.umd.cjs +24 -11
  9. package/lib/engine/engine_physics.d.ts +2 -2
  10. package/lib/engine/engine_physics.js +4 -4
  11. package/lib/engine/engine_physics.js.map +1 -1
  12. package/lib/engine/engine_physics_rapier.d.ts +24 -4
  13. package/lib/engine/engine_physics_rapier.js +33 -12
  14. package/lib/engine/engine_physics_rapier.js.map +1 -1
  15. package/lib/engine/engine_types.d.ts +27 -4
  16. package/lib/engine/engine_types.js.map +1 -1
  17. package/lib/engine/extensions/NEEDLE_lighting_settings.d.ts +0 -1
  18. package/lib/engine/extensions/NEEDLE_lighting_settings.js +0 -6
  19. package/lib/engine/extensions/NEEDLE_lighting_settings.js.map +1 -1
  20. package/lib/engine/webcomponents/needle menu/needle-menu.js +14 -1
  21. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  22. package/lib/engine-components/Collider.d.ts +25 -0
  23. package/lib/engine-components/Collider.js +25 -0
  24. package/lib/engine-components/Collider.js.map +1 -1
  25. package/lib/engine-components/RigidBody.d.ts +3 -0
  26. package/lib/engine-components/RigidBody.js +5 -2
  27. package/lib/engine-components/RigidBody.js.map +1 -1
  28. package/lib/engine-components/SyncedTransform.js +3 -15
  29. package/lib/engine-components/SyncedTransform.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/engine/codegen/register_types.ts +2 -2
  32. package/src/engine/engine_physics.ts +4 -4
  33. package/src/engine/engine_physics_rapier.ts +48 -14
  34. package/src/engine/engine_types.ts +29 -6
  35. package/src/engine/extensions/NEEDLE_lighting_settings.ts +0 -5
  36. package/src/engine/webcomponents/needle menu/needle-menu.ts +14 -1
  37. package/src/engine-components/Collider.ts +27 -4
  38. package/src/engine-components/RigidBody.ts +5 -2
  39. package/src/engine-components/SyncedTransform.ts +4 -17
@@ -1,3 +1,4 @@
1
+ import type { QueryFilterFlags } from "@dimforge/rapier3d-compat";
1
2
  import { Camera, Color, Material, Mesh, Object3D, Quaternion, Ray, Scene, WebGLRenderer } from "three";
2
3
  import { Vector3 } from "three";
3
4
  import { type GLTF as GLTF3 } from "three/examples/jsm/loaders/GLTFLoader.js";
@@ -251,12 +252,14 @@ export declare interface ICollider extends IComponent {
251
252
  updatePhysicsMaterial(): void;
252
253
  /** The collider membership indicates what groups the collider is part of (e.g. group 2 and 3)
253
254
  * An `undefined` array indicates that the collider is part of all groups
254
- * Note: Make sure to call updateProperties after having changed this property
255
+ * Note: Make sure to call updateProperties after having changed this property
256
+ * Default: [0]
255
257
  */
256
258
  membership?: number[];
257
259
  /** The collider filter indicates what groups the collider can interact with (e.g. group 3 and 4)
258
260
  * An `undefined` array indicates that the collider can interact with all groups
259
- * Note: Make sure to call updateProperties after having changed this property
261
+ * Note: Make sure to call updateProperties after having changed this property
262
+ * Default: undefined
260
263
  */
261
264
  filter?: number[];
262
265
  }
@@ -278,6 +281,7 @@ export declare interface IRigidbody extends IComponent {
278
281
  drag: number;
279
282
  angularDrag: number;
280
283
  useGravity: boolean;
284
+ centerOfMass: Vec3;
281
285
  gravityScale: number;
282
286
  dominanceGroup: number;
283
287
 
@@ -436,12 +440,31 @@ export interface IPhysicsEngine {
436
440
  /** Fast raycast against physics colliders
437
441
  * @param origin ray origin in screen or worldspace
438
442
  * @param direction ray direction in worldspace
439
- * @param maxDistance max distance to raycast
440
- * @param solid if true it will also hit the collider if origin is already inside it
443
+ * @param options additional options
441
444
  */
442
- raycast(origin?: Vec2 | Vec3, direction?: Vec3, maxDistance?: number, solid?: boolean): RaycastResult;
445
+ raycast(origin?: Vec2 | Vec3, direction?: Vec3, options?: {
446
+ maxDistance?: number,
447
+ /** True if you want to also hit objects when the raycast starts from inside a collider */
448
+ solid?: boolean,
449
+ queryFilterFlags?: QueryFilterFlags,
450
+ /** Raycast filter groups. Groups are used to apply the collision group rules for the scene query. The scene query will only consider hits with colliders with collision groups compatible with this collision group (using the bitwise test described in the collision groups section). See https://rapier.rs/docs/user_guides/javascript/colliders#collision-groups-and-solver-groups
451
+ * For example membership 0x0001 and filter 0x0002 should be 0x00010002 */
452
+ filterGroups?: number,
453
+ /** Return false to ignore this collider */
454
+ filterPredicate?: (collider: ICollider) => boolean
455
+ }): RaycastResult;
443
456
  /** raycast that also gets the normal vector. If you don't need it use raycast() */
444
- raycastAndGetNormal(origin?: Vec2 | Vec3, direction?: Vec3, maxDistance?: number, solid?: boolean): RaycastResult;
457
+ raycastAndGetNormal(origin?: Vec2 | Vec3, direction?: Vec3, options?: {
458
+ maxDistance?: number,
459
+ /** True if you want to also hit objects when the raycast starts from inside a collider */
460
+ solid?: boolean,
461
+ queryFilterFlags?: QueryFilterFlags,
462
+ /** Raycast filter groups. Groups are used to apply the collision group rules for the scene query. The scene query will only consider hits with colliders with collision groups compatible with this collision group (using the bitwise test described in the collision groups section). See https://rapier.rs/docs/user_guides/javascript/colliders#collision-groups-and-solver-groups
463
+ * For example membership 0x0001 and filter 0x0002 should be 0x00010002 */
464
+ filterGroups?: number,
465
+ /** Return false to ignore this collider */
466
+ filterPredicate?: (collider: ICollider) => boolean
467
+ }): RaycastResult;
445
468
  sphereOverlap(point: Vector3, radius: number): Array<SphereOverlapResult>;
446
469
 
447
470
  // Collider methods
@@ -94,8 +94,6 @@ export class SceneLightSettings extends Behaviour {
94
94
  private _hasReflection: boolean = false;
95
95
  private _ambientLightObj?: AmbientLight;
96
96
  private _hemisphereLightObj?: HemisphereLight;
97
- // used when skybox is used to support ambient intensity for "non custom shaders"
98
- private _lightProbeObj?: LightProbe;
99
97
 
100
98
  awake() {
101
99
  if (this.sourceId) {
@@ -154,7 +152,6 @@ export class SceneLightSettings extends Behaviour {
154
152
  if (this._ambientLightObj) {
155
153
  this.gameObject.add(this._ambientLightObj)
156
154
  }
157
- if (this._lightProbeObj) this._lightProbeObj.removeFromParent();
158
155
  }
159
156
  else if (this.ambientMode === AmbientMode.Trilight) {
160
157
  if (this.ambientTrilight) {
@@ -180,8 +177,6 @@ export class SceneLightSettings extends Behaviour {
180
177
  onDisable() {
181
178
  if (debug)
182
179
  console.warn("💡⚫ <<< Disable lighting:", this.sourceId, this);
183
- if (this._lightProbeObj)
184
- this._lightProbeObj.removeFromParent();
185
180
  if (this._ambientLightObj)
186
181
  this._ambientLightObj.removeFromParent();
187
182
  if (this._hemisphereLightObj)
@@ -371,7 +371,20 @@ export class NeedleMenuElement extends HTMLElement {
371
371
  width: 100%;
372
372
  }
373
373
 
374
-
374
+ @media (max-width: 300px) or (max-height: 350px){
375
+ .options {
376
+ display: none;
377
+ padding: 0;
378
+ margin: 0;
379
+ border: none;
380
+ }
381
+ .logo.any-options {
382
+ border: none !important;
383
+ padding: 0;
384
+ margin-bottom: 0 !important;
385
+ padding-bottom: 0 !important;
386
+ }
387
+ }
375
388
 
376
389
  /* dark mode */
377
390
  /*
@@ -15,45 +15,65 @@ import { Rigidbody } from "./RigidBody.js";
15
15
  * Collider is the base class for all colliders. A collider is a physical shape that is used to detect collisions with other objects in the scene.
16
16
  * Colliders are used in combination with a Rigidbody to create physical interactions between objects.
17
17
  * Colliders are registered with the physics engine when they are enabled and removed when they are disabled.
18
- * @category Physics
18
+ * @category Physics
19
+ * @inheritdoc
19
20
  */
20
21
  export class Collider extends Behaviour implements ICollider {
21
22
 
23
+ /** @internal */
22
24
  get isCollider(): any {
23
25
  return true;
24
26
  }
25
27
 
28
+ /**
29
+ * The Rigidbody that this collider is attached to.
30
+ */
26
31
  @serializable(Rigidbody)
27
32
  attachedRigidbody: Rigidbody | null = null;
28
33
 
34
+ /**
35
+ * When `true` the collider will not be used for collision detection but will still trigger events.
36
+ */
29
37
  @serializable()
30
38
  isTrigger: boolean = false;
31
39
 
40
+ /**
41
+ * The physics material that is used for the collider. This material defines physical properties of the collider such as friction and bounciness.
42
+ */
32
43
  @serializable()
33
44
  sharedMaterial?: PhysicsMaterial;
34
45
 
46
+ /**
47
+ * The layers that the collider is assigned to.
48
+ */
35
49
  @serializable()
36
50
  membership: number[] = [0];
51
+
52
+ /**
53
+ * The layers that the collider will interact with.
54
+ * @inheritdoc
55
+ */
37
56
  @serializable()
38
57
  filter?: number[];
39
58
 
59
+ /** @internal */
40
60
  awake() {
41
61
  super.awake();
42
62
  if (!this.attachedRigidbody)
43
63
  this.attachedRigidbody = this.gameObject.getComponentInParent(Rigidbody);
44
64
  }
45
-
65
+ /** @internal */
46
66
  start() {
47
67
  if (!this.attachedRigidbody)
48
68
  this.attachedRigidbody = this.gameObject.getComponentInParent(Rigidbody);
49
69
  }
50
-
70
+ /** @internal */
51
71
  onEnable() {
52
72
  // a rigidbody is not assigned if we export an asset
53
73
  if (!this.attachedRigidbody)
54
74
  this.attachedRigidbody = this.gameObject.getComponentInParent(Rigidbody);
55
75
  }
56
-
76
+ /** @internal */
57
77
  onDisable() {
58
78
  this.context.physics.engine?.removeBody(this);
59
79
  }
@@ -63,6 +83,9 @@ export class Collider extends Behaviour implements ICollider {
63
83
  return this.context.physics.engine?.getBody(this);
64
84
  }
65
85
 
86
+ /**
87
+ * Apply the collider properties to the physics engine.
88
+ */
66
89
  updateProperties = () => {
67
90
  this.context.physics.engine?.updateProperties(this);
68
91
  }
@@ -167,8 +167,11 @@ export class Rigidbody extends Behaviour implements IRigidbody {
167
167
  @serializable()
168
168
  useGravity: boolean = true;
169
169
 
170
- @serializable()
171
- centerOfMass: Vector3 = new Vector3();
170
+ /**
171
+ * The center of mass is the point around which the mass of the rigid-body is evenly distributed. It is used to compute the torque applied to the rigid-body when forces are applied to it.
172
+ */
173
+ @serializable(Vector3)
174
+ centerOfMass: Vector3 = new Vector3(0, 0, 0);
172
175
 
173
176
  /**
174
177
  * Constraints are used to lock the position or rotation of an object in a specific axis.
@@ -282,22 +282,14 @@ export class SyncedTransform extends Behaviour {
282
282
  this.lastWorldRotation.copy(wr);
283
283
 
284
284
 
285
- // if (this._model.isOwned === false && this.autoOwnership) {
286
- // this.requestOwnership();
287
- // }
288
-
289
285
  if (!this._model) return;
290
- // only run if we are the owner
286
+
291
287
  if (!this._model || this._model.hasOwnership === undefined || !this._model.hasOwnership) {
292
- if (this.rb) {
293
- this.rb.isKinematic = this._model.isOwned ?? false;
294
- this.rb.setVelocity(0, 0, 0);
295
- }
288
+ // if we're not the owner of this synced transform then don't send any data
296
289
  return;
297
290
  }
298
291
 
299
292
  // local user is owner:
300
-
301
293
  if (this.rb) {
302
294
  if (this._wasKinematic !== undefined) {
303
295
  if (debug)
@@ -305,13 +297,8 @@ export class SyncedTransform extends Behaviour {
305
297
  this.rb.isKinematic = this._wasKinematic;
306
298
  }
307
299
 
308
- // hacky reset if too far off
309
- if (this.gameObject.position.distanceTo(new Vector3(0, 0, 0)) > 1000) {
310
- if (debug)
311
- console.log("RESET", this.name)
312
- this.gameObject.position.set(0, 1, 0);
313
- this.rb.setVelocity(0, 0, 0);
314
- }
300
+ // TODO: if the SyncedTransform has a dynamic rigidbody we should probably synchronize the Rigidbody's properties (velocity etc)
301
+ // Or the Rigidbody should be synchronized separately in which case the SyncedTransform should be passive
315
302
  }
316
303
 
317
304
  const updateInterval = 10;