@needle-tools/engine 2.31.1-pre → 2.32.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 (33) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/needle-engine.d.ts +111 -111
  3. package/dist/needle-engine.js +72 -72
  4. package/dist/needle-engine.js.map +3 -3
  5. package/dist/needle-engine.min.js +17 -17
  6. package/dist/needle-engine.min.js.map +3 -3
  7. package/lib/engine/debug/error_overlay.js +4 -4
  8. package/lib/engine/debug/error_overlay.js.map +1 -1
  9. package/lib/engine/engine_input.d.ts +87 -102
  10. package/lib/engine/engine_input.js +173 -99
  11. package/lib/engine/engine_input.js.map +1 -1
  12. package/lib/engine/engine_mainloop_utils.d.ts +2 -1
  13. package/lib/engine/engine_mainloop_utils.js +5 -2
  14. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  15. package/lib/engine/engine_physics.d.ts +5 -1
  16. package/lib/engine/engine_physics.js +72 -22
  17. package/lib/engine/engine_physics.js.map +1 -1
  18. package/lib/engine/engine_setup.js +7 -3
  19. package/lib/engine/engine_setup.js.map +1 -1
  20. package/lib/engine-components/Component.d.ts +10 -3
  21. package/lib/engine-components/Component.js +98 -40
  22. package/lib/engine-components/Component.js.map +1 -1
  23. package/lib/engine-components/Rigidbody.d.ts +7 -4
  24. package/lib/engine-components/Rigidbody.js +43 -26
  25. package/lib/engine-components/Rigidbody.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/engine/debug/error_overlay.ts +3 -3
  28. package/src/engine/engine_input.ts +179 -103
  29. package/src/engine/engine_mainloop_utils.ts +6 -2
  30. package/src/engine/engine_physics.ts +86 -24
  31. package/src/engine/engine_setup.ts +8 -3
  32. package/src/engine-components/Component.ts +109 -40
  33. package/src/engine-components/RigidBody.ts +51 -29
@@ -15,7 +15,7 @@ export class KeyEventArgs {
15
15
  key: string;
16
16
  keyType: string;
17
17
  source?: Event;
18
- constructor(evt : KeyboardEvent){
18
+ constructor(evt: KeyboardEvent) {
19
19
  this.key = evt.key;
20
20
  this.keyType = evt.type;
21
21
  this.source = evt;
@@ -186,14 +186,25 @@ export class Input extends EventTarget {
186
186
  }
187
187
  return null;
188
188
  }
189
- isKeyDown(keyCode: number) {
189
+ isKeyDown(keyCode: KeyCode | string | number) {
190
+ if (typeof keyCode === "number") {
191
+ console.warn("Use of keycode as number is not recommended, please use KeyCode or string instead");
192
+ keyCode = String.fromCharCode(keyCode);
193
+ }
190
194
  // console.log( this.keysPressed[keyCode]?.frame, time.frameCount);
191
195
  return this.context.application.isVisible && this.context.application.hasFocus && this.keysPressed[keyCode]?.startFrame === this.context.time.frameCount && this.keysPressed[keyCode].pressed;
192
196
  }
193
- isKeyUp(keyCode: number) {
197
+ isKeyUp(keyCode: KeyCode | string | number) {
198
+ if (typeof keyCode === "number") {
199
+ console.warn("Use of keycode as number is not recommended, please use KeyCode or string instead");
200
+ keyCode = String.fromCharCode(keyCode);
201
+ }
194
202
  return this.context.application.isVisible && this.context.application.hasFocus && this.keysPressed[keyCode]?.frame === this.context.time.frameCount && !this.keysPressed[keyCode].pressed;
195
203
  }
196
- isKeyPressed(keyCode: number) {
204
+ isKeyPressed(keyCode: KeyCode | string | number) {
205
+ if (typeof keyCode === "number") {
206
+ keyCode = String.fromCharCode(keyCode);
207
+ }
197
208
  return this.context.application.isVisible && this.context.application.hasFocus && this.keysPressed[keyCode]?.pressed;// && time.frameCount - this.keysPressed[keyCode].frame < 100;
198
209
  }
199
210
 
@@ -521,103 +532,168 @@ export class Input extends EventTarget {
521
532
 
522
533
 
523
534
  export enum KeyCode {
524
- BACKSPACE = 8,
525
- TAB = 9,
526
- ENTER = 13,
527
- SHIFT = 16,
528
- CTRL = 17,
529
- ALT = 18,
530
- PAUSE = 19,
531
- CAPS_LOCK = 20,
532
- ESCAPE = 27,
533
- SPACE = 32,
534
- PAGE_UP = 33,
535
- PAGE_DOWN = 34,
536
- END = 35,
537
- HOME = 36,
538
- LEFT_ARROW = 37,
539
- UP_ARROW = 38,
540
- RIGHT_ARROW = 39,
541
- DOWN_ARROW = 40,
542
- INSERT = 45,
543
- DELETE = 46,
544
- KEY_0 = 48,
545
- KEY_1 = 49,
546
- KEY_2 = 50,
547
- KEY_3 = 51,
548
- KEY_4 = 52,
549
- KEY_5 = 53,
550
- KEY_6 = 54,
551
- KEY_7 = 55,
552
- KEY_8 = 56,
553
- KEY_9 = 57,
554
- KEY_A = 65,
555
- KEY_B = 66,
556
- KEY_C = 67,
557
- KEY_D = 68,
558
- KEY_E = 69,
559
- KEY_F = 70,
560
- KEY_G = 71,
561
- KEY_H = 72,
562
- KEY_I = 73,
563
- KEY_J = 74,
564
- KEY_K = 75,
565
- KEY_L = 76,
566
- KEY_M = 77,
567
- KEY_N = 78,
568
- KEY_O = 79,
569
- KEY_P = 80,
570
- KEY_Q = 81,
571
- KEY_R = 82,
572
- KEY_S = 83,
573
- KEY_T = 84,
574
- KEY_U = 85,
575
- KEY_V = 86,
576
- KEY_W = 87,
577
- KEY_X = 88,
578
- KEY_Y = 89,
579
- KEY_Z = 90,
580
- LEFT_META = 91,
581
- RIGHT_META = 92,
582
- SELECT = 93,
583
- NUMPAD_0 = 96,
584
- NUMPAD_1 = 97,
585
- NUMPAD_2 = 98,
586
- NUMPAD_3 = 99,
587
- NUMPAD_4 = 100,
588
- NUMPAD_5 = 101,
589
- NUMPAD_6 = 102,
590
- NUMPAD_7 = 103,
591
- NUMPAD_8 = 104,
592
- NUMPAD_9 = 105,
593
- MULTIPLY = 106,
594
- ADD = 107,
595
- SUBTRACT = 109,
596
- DECIMAL = 110,
597
- DIVIDE = 111,
598
- F1 = 112,
599
- F2 = 113,
600
- F3 = 114,
601
- F4 = 115,
602
- F5 = 116,
603
- F6 = 117,
604
- F7 = 118,
605
- F8 = 119,
606
- F9 = 120,
607
- F10 = 121,
608
- F11 = 122,
609
- F12 = 123,
610
- NUM_LOCK = 144,
611
- SCROLL_LOCK = 145,
612
- SEMICOLON = 186,
613
- EQUALS = 187,
614
- COMMA = 188,
615
- DASH = 189,
616
- PERIOD = 190,
617
- FORWARD_SLASH = 191,
618
- GRAVE_ACCENT = 192,
619
- OPEN_BRACKET = 219,
620
- BACK_SLASH = 220,
621
- CLOSE_BRACKET = 221,
622
- SINGLE_QUOTE = 222
535
+ BACKSPACE = "Backspace",
536
+ TAB = "Tab",
537
+ ENTER = "Enter",
538
+ SHIFT = "Shift",
539
+ CTRL = "Control",
540
+ ALT = "Alt",
541
+ PAUSE = "Pause",
542
+ CAPS_LOCK = "CapsLock",
543
+ ESCAPE = "Escape",
544
+ SPACE = " ",
545
+ PAGE_UP = "PageUp",
546
+ PAGE_DOWN = "PageDown",
547
+ END = "End",
548
+ HOME = "Home",
549
+ LEFT_ARROW = "ArrowLeft",
550
+ UP_ARROW = "ArrowUp",
551
+ RIGHT_ARROW = "ArrowRight",
552
+ DOWN_ARROW = "ArrowDown",
553
+ INSERT = "Insert",
554
+ DELETE = "Delete",
555
+ KEY_0 = "0",
556
+ KEY_1 = "1",
557
+ KEY_2 = "2",
558
+ KEY_3 = "3",
559
+ KEY_4 = "4",
560
+ KEY_5 = "5",
561
+ KEY_6 = "6",
562
+ KEY_7 = "7",
563
+ KEY_8 = "8",
564
+ KEY_9 = "9",
565
+ KEY_A = "a",
566
+ KEY_B = "b",
567
+ KEY_C = "c",
568
+ KEY_D = "d",
569
+ KEY_E = "e",
570
+ KEY_F = "f",
571
+ KEY_G = "g",
572
+ KEY_H = "h",
573
+ KEY_I = "i",
574
+ KEY_K = "k",
575
+ KEY_J = "j",
576
+ KEY_L = "l",
577
+ KEY_M = "m",
578
+ KEY_N = "n",
579
+ KEY_O = "o",
580
+ KEY_P = "p",
581
+ KEY_Q = "q",
582
+ KEY_R = "r",
583
+ KEY_S = "s",
584
+ KEY_T = "t",
585
+ KEY_U = "u",
586
+ KEY_V = "v",
587
+ KEY_W = "w",
588
+ KEY_X = "x",
589
+ KEY_Z = "z",
590
+ KEY_Y = "y",
591
+ SELECT = "Select",
592
+ NUMPAD_0 = "Numpad0",
593
+ NUMPAD_1 = "Numpad1",
594
+ NUMPAD_2 = "Numpad2",
595
+ NUMPAD_3 = "Numpad3",
596
+ NUMPAD_4 = "Numpad4",
597
+ NUMPAD_5 = "Numpad5",
598
+ NUMPAD_6 = "Numpad6",
599
+ NUMPAD_7 = "Numpad7",
600
+ NUMPAD_8 = "Numpad8",
601
+ NUMPAD_9 = "Numpad9",
602
+ MULTIPLY = "Multiply",
603
+ ADD = "Add",
604
+ SUBTRACT = "Subtract",
605
+ DECIMAL = "Decimal",
606
+ DIVIDE = "Divide",
607
+ F1 = "F1",
608
+ F2 = "F2",
609
+ F3 = "F3",
610
+ F4 = "F4",
611
+ F5 = "F5",
612
+ F6 = "F6",
613
+ F7 = "F7",
614
+ F8 = "F8",
615
+ F9 = "F9",
616
+ F10 = "F10",
617
+ F11 = "F11",
618
+ F12 = "F12"
623
619
  };
620
+
621
+
622
+ // KEY_1 = 49,
623
+ // KEY_2 = 50,
624
+ // KEY_3 = 51,
625
+ // KEY_4 = 52,
626
+ // KEY_5 = 53,
627
+ // KEY_6 = 54,
628
+ // KEY_7 = 55,
629
+ // KEY_8 = 56,
630
+ // KEY_9 = 57,
631
+ // KEY_A = 65,
632
+ // KEY_B = 66,
633
+ // KEY_C = 67,
634
+ // KEY_D = "d",
635
+ // KEY_E = 69,
636
+ // KEY_F = 70,
637
+ // KEY_G = 71,
638
+ // KEY_H = 72,
639
+ // KEY_I = 73,
640
+ // KEY_J = 74,
641
+ // KEY_K = 75,
642
+ // KEY_L = 76,
643
+ // KEY_M = 77,
644
+ // KEY_N = 78,
645
+ // KEY_O = 79,
646
+ // KEY_P = 80,
647
+ // KEY_Q = 81,
648
+ // KEY_R = 82,
649
+ // KEY_S = 83,
650
+ // KEY_T = 84,
651
+ // KEY_U = 85,
652
+ // KEY_V = 86,
653
+ // KEY_W = 87,
654
+ // KEY_X = 88,
655
+ // KEY_Y = 89,
656
+ // KEY_Z = 90,
657
+ // LEFT_META = 91,
658
+ // RIGHT_META = 92,
659
+ // SELECT = 93,
660
+ // NUMPAD_0 = 96,
661
+ // NUMPAD_1 = 97,
662
+ // NUMPAD_2 = 98,
663
+ // NUMPAD_3 = 99,
664
+ // NUMPAD_4 = 100,
665
+ // NUMPAD_5 = 101,
666
+ // NUMPAD_6 = 102,
667
+ // NUMPAD_7 = 103,
668
+ // NUMPAD_8 = 104,
669
+ // NUMPAD_9 = 105,
670
+ // MULTIPLY = 106,
671
+ // ADD = 107,
672
+ // SUBTRACT = 109,
673
+ // DECIMAL = 110,
674
+ // DIVIDE = 111,
675
+ // F1 = 112,
676
+ // F2 = 113,
677
+ // F3 = 114,
678
+ // F4 = 115,
679
+ // F5 = 116,
680
+ // F6 = 117,
681
+ // F7 = 118,
682
+ // F8 = 119,
683
+ // F9 = 120,
684
+ // F10 = 121,
685
+ // F11 = 122,
686
+ // F12 = 123,
687
+ // NUM_LOCK = 144,
688
+ // SCROLL_LOCK = 145,
689
+ // SEMICOLON = 186,
690
+ // EQUALS = 187,
691
+ // COMMA = 188,
692
+ // DASH = 189,
693
+ // PERIOD = 190,
694
+ // FORWARD_SLASH = 191,
695
+ // GRAVE_ACCENT = 192,
696
+ // OPEN_BRACKET = 219,
697
+ // BACK_SLASH = 220,
698
+ // CLOSE_BRACKET = 221,
699
+ // SINGLE_QUOTE = 222
@@ -3,6 +3,7 @@ import * as utils from "./engine_generic_utils";
3
3
  import * as constants from "./engine_constants";
4
4
  import { Behaviour, Component, GameObject } from '../engine-components/Component';
5
5
  import { getParam } from './engine_utils';
6
+ import { Object3D } from 'three';
6
7
 
7
8
  const debug = getParam("debugnewscripts");
8
9
 
@@ -143,13 +144,16 @@ export function processRemoveFromScene(script: Component) {
143
144
  removeScriptFromContext(script, script.context);
144
145
  }
145
146
 
146
- export function processStart(context: Context) {
147
+ export function processStart(context: Context, object? : Object3D) {
147
148
  // Call start on scripts
148
149
  for (let i = 0; i < context.new_script_start.length; i++) {
149
150
  try {
150
151
  const script = context.new_script_start[i];
152
+ if(object !== undefined && script.gameObject !== object) continue;
151
153
  if (script.destroyed) continue;
152
- if (script.activeAndEnabled === false) continue;
154
+ if (script.activeAndEnabled === false) {
155
+ continue;
156
+ }
153
157
  // keep them in queue until script has started
154
158
  // call awake if the script was inactive before
155
159
  utils.safeInvoke(script.__internalAwake.bind(script));
@@ -6,9 +6,9 @@ import { Rigidbody } from '../engine-components/Rigidbody';
6
6
  import * as utils from "./engine_utils"
7
7
  import * as threeutils from "./engine_three_utils"
8
8
  import { InstancingUtil } from '../engine-components/Renderer';
9
- import { GameObject } from '../engine-components/Component';
9
+ import { Behaviour, Component, GameObject } from '../engine-components/Component';
10
10
  import { Body, RigidVehicle, Shape, Vec3 } from 'cannon-es';
11
- import { Object3D, Vector3 } from 'three';
11
+ import { Matrix4, Object3D, RGBA_BPTC_Format, Vector3, Wrapping } from 'three';
12
12
  import { Collider } from '../engine-components/Collider';
13
13
 
14
14
  const debugPhysics = utils.getParam("debugphysics");
@@ -288,7 +288,10 @@ export class Physics {
288
288
  break;
289
289
  }
290
290
  }
291
- this.world.addBody(body);
291
+ // dont add the body before it has shapes
292
+ // otherwise things like forces appplied in the frame before the shapes exist will be zeroed out
293
+ if (body.shapes.length > 0)
294
+ this.world.addBody(body);
292
295
  }
293
296
 
294
297
  public removeBody(go: GameObject, body: CANNON.Body, removeCompletely: boolean = true) {
@@ -331,7 +334,8 @@ export class Physics {
331
334
  if (settings.sleepThreshold)
332
335
  body.sleepSpeedLimit = settings.sleepThreshold;
333
336
 
334
- this.world.addBody(body);
337
+ if (body.shapes.length > 0)
338
+ this.world.addBody(body);
335
339
  const po = new PhysicsObject(obj, body);
336
340
  po._hasRigidbody = true;
337
341
  this.objects.push(po);
@@ -364,6 +368,7 @@ export class Physics {
364
368
 
365
369
  const body = this.addShape(obj, shape, center, rb);
366
370
  if (body !== null) {
371
+ this.world.addBody(body);
367
372
  if (this.isAlreadyRegistered(body)) return shape;
368
373
  const po = new PhysicsObject(obj, body);
369
374
  this.objects.push(po);
@@ -384,6 +389,7 @@ export class Physics {
384
389
 
385
390
  const body = this.addShape(obj, shape, center, rb);
386
391
  if (body !== null) {
392
+ this.world.addBody(body);
387
393
  if (this.isAlreadyRegistered(body)) return shape;
388
394
  const po = new PhysicsObject(obj, body);
389
395
  this.objects.push(po);
@@ -430,6 +436,9 @@ export class Physics {
430
436
  return false;
431
437
  }
432
438
 
439
+ private readonly tempMat1: THREE.Matrix4 = new THREE.Matrix4();
440
+ private readonly tempMat2: THREE.Matrix4 = new THREE.Matrix4();
441
+
433
442
  private addShape(obj: THREE.Object3D, shape: CANNON.Shape, center: THREE.Vector3, rb: Rigidbody | null): CANNON.Body | null {
434
443
 
435
444
  let body: CANNON.Body | null = null;
@@ -445,28 +454,59 @@ export class Physics {
445
454
  // console.log("has no rb", obj);
446
455
  body = this.internalCreateBody(obj, null);
447
456
  body.type = CANNON.Body.KINEMATIC;
448
- this.world.addBody(body);
449
457
  }
450
458
 
451
459
  if (body) {
460
+ // console.log(obj.name, obj.position, obj.rotation)
461
+
462
+ // the center is serialized from Unity so we need to move it into threejs space
463
+ // this should probably happen on export for colliders
452
464
  center.x *= -1;
453
465
 
454
- const wr = threeutils.getWorldQuaternion(obj);
466
+ let wp = obj.position;
467
+ let wr = obj.quaternion;
468
+
469
+ // console.log(obj.name, wp)
470
+
471
+ if (rb && rb.gameObject !== obj) {
472
+ this.tempMat1.copy(obj.matrixWorld);
473
+ this.tempMat2.copy(rb.gameObject.matrixWorld).invert();
474
+ this.tempMat1.premultiply(this.tempMat2);
475
+ this.tempMat1.decompose(wp, wr, this.tempPosition);
476
+ }
477
+ else {
478
+ wp = threeutils.getWorldPosition(obj);
479
+ const bp = body.position;
480
+ wp.x -= bp.x;
481
+ wp.y -= bp.y;
482
+ wp.z -= bp.z;
483
+
484
+ wr = threeutils.getWorldQuaternion(obj);
485
+ const r = new THREE.Quaternion(body.quaternion.x, body.quaternion.y, body.quaternion.z, body.quaternion.w);
486
+ wr.multiply(r.invert());
487
+ }
455
488
  // get rotation difference
456
489
 
457
- const wp = threeutils.getWorldPosition(obj);
458
490
  wp.add(center);
459
491
 
460
- const r = new THREE.Quaternion(body.quaternion.x, body.quaternion.y, body.quaternion.z, body.quaternion.w);
461
- wr.multiply(r.invert());
492
+
493
+
494
+
495
+ // if (rb) {
496
+ // this.tempMat.setPosition(wp);
497
+ // this.tempMat.makeRotationFromQuaternion(wr);
498
+ // this.tempMat.multiplyMatrices(this.tempMat, rb?.gameObject.matrix);
499
+ // this.tempMat.decompose(this.tempPosition, this.tempQuaternion, new THREE.Vector3());
500
+ // wp.copy(this.tempPosition);
501
+ // }
462
502
 
463
503
  // wp.applyQuaternion(wr);
464
504
 
465
- const bp = body.position;
466
- const pos = new CANNON.Vec3(wp.x - bp.x, wp.y - bp.y, wp.z - bp.z);
505
+ const pos = new CANNON.Vec3(wp.x, wp.y, wp.z);
467
506
  const rot = new CANNON.Quaternion(wr.x, wr.y, wr.z, wr.w);
468
507
  body.addShape(shape, pos, rot);
469
508
  body.updateMassProperties();
509
+ this.world.addBody(body);
470
510
  }
471
511
  return body;
472
512
  }
@@ -479,7 +519,7 @@ export class Physics {
479
519
  this.world.step(deltaTime);
480
520
  this._isUpdatingPhysicsWorld = false;
481
521
  if (debugPhysics && this.context.time.frameCount % 60 === 0) {
482
- console.log("physics world has " + this.world.bodies.length + " bodies", this.world);
522
+ // console.log("physics world has " + this.world.bodies.length + " bodies", this.world);
483
523
  }
484
524
  }
485
525
 
@@ -602,26 +642,42 @@ export class Physics {
602
642
 
603
643
  private onBeginContact(_) {
604
644
  // this is called after the object collide event so we dont really need it
605
- // console.log("START", args);
645
+ // console.log("START");
606
646
  }
607
647
 
608
648
  private raiseCollisionEvents(obj: THREE.Object3D, event: CannonCollision) {
609
649
  const collision = new Collision(obj, event);
610
650
  if (debugCollisions)
611
651
  console.log("collision between", event.contact.bi, event.contact.bj, obj, event);
612
- for (let i = 0; i < obj.userData?.components?.length; i++) {
613
- const component = obj.userData.components[i];
614
- component.__internalHandleCollision(collision);
652
+ GameObject.foreachComponent(obj, (c: Component) => {
653
+ c.__internalHandleCollision(collision, false);
654
+ });
655
+
656
+ // handle triggers
657
+ if (collision.collider && !collision.collider.attachedRigidbody && collision.collider.isTrigger) {
658
+ const collision2 = new Collision(collision.gameObject, event, true);
659
+ GameObject.foreachComponent(collision.gameObject, (c: Component) => {
660
+ c.__internalHandleCollision(collision2, true);
661
+ });
615
662
  }
616
663
  }
617
664
 
618
665
  private onEndContact(args: { bodyA: CANNON.Body, bodyB: CANNON.Body }) {
619
- // console.log("END", args.bodyA, args.bodyB);
666
+ // if(args.bodyB.sleepState !== CANNON.Body.AWAKE) return;
667
+ // console.log("END", CANNON.BODY_SLEEP_STATES, args.bodyB.sleepState);
620
668
  const obj1 = args.bodyA[bodyObjectKey];
621
669
  const obj2 = args.bodyB[bodyObjectKey];
622
- for (let i = 0; i < obj2.userData?.components?.length; i++) {
623
- const component = obj2.userData.components[i];
624
- component.sendExitCollisionEvent(obj1);
670
+ // console.log(obj2);
671
+ GameObject.foreachComponent(obj2, (c: Component) => {
672
+ c.__internalHandleExitCollisionEvent(obj1, false);
673
+ });
674
+
675
+ const collider = GameObject.getComponent(obj1, Collider);
676
+ if (collider && !collider.attachedRigidbody && collider.isTrigger) {
677
+
678
+ GameObject.foreachComponent(collider.gameObject, (c: Component) => {
679
+ c.__internalHandleExitCollisionEvent(obj2, true);
680
+ });
625
681
  }
626
682
  }
627
683
 
@@ -629,14 +685,18 @@ export class Physics {
629
685
 
630
686
 
631
687
  export class Collision {
688
+
689
+ private readonly invert: boolean;
632
690
  private readonly collision: CannonCollision;
691
+ private readonly targetBody: CANNON.Body;
633
692
 
634
693
  readonly me: Object3D;
635
694
 
636
695
  private _normal?: Vector3;
637
696
  get normal(): Vector3 {
638
697
  if (!this._normal) {
639
- this._normal = new Vector3(this.collision.contact.ni.x, this.collision.contact.ni.y, this.collision.contact.ni.z);
698
+ const vec = this.collision.contact.ni;
699
+ this._normal = new Vector3(vec.x, vec.y, vec.z);
640
700
  }
641
701
  return this._normal;
642
702
  }
@@ -644,13 +704,13 @@ export class Collision {
644
704
  private _collider?: Collider;
645
705
  get collider(): Collider {
646
706
  if (this._collider === undefined) {
647
- this._collider = GameObject.getComponent(this.gameObject, Collider)!;
707
+ this._collider = GameObject.getComponentInChildren(this.gameObject, Collider)!;
648
708
  }
649
709
  return this._collider;
650
710
  }
651
711
 
652
712
  get gameObject(): Object3D {
653
- return this.collision.body[bodyObjectKey];
713
+ return this.targetBody[bodyObjectKey];
654
714
  }
655
715
 
656
716
  // private _point?: Vector3;
@@ -663,8 +723,10 @@ export class Collision {
663
723
  // return this._point;
664
724
  // }
665
725
 
666
- constructor(obj: Object3D, collision: CannonCollision) {
726
+ constructor(obj: Object3D, collision: CannonCollision, invert: boolean = false) {
727
+ this.invert = invert;
667
728
  this.me = obj;
668
729
  this.collision = collision;
730
+ this.targetBody = this.invert ? collision.target : collision.body;
669
731
  }
670
732
  }
@@ -222,11 +222,13 @@ export class Context {
222
222
  this.lightmaps = new LightDataRegistry(this);
223
223
  this.players = new PlayerViewManager(this);
224
224
 
225
- window.addEventListener('resize', this.updateSize.bind(this));
225
+ window.addEventListener('resize', () => this._sizeChanged = true );
226
226
  const ro = new ResizeObserver(_ => this._sizeChanged = true);
227
227
  ro.observe(this.domElement);
228
228
  }
229
229
 
230
+ // private _requestSizeUpdate : boolean = false;
231
+
230
232
  private updateSize() {
231
233
  if (!this.isManagedExternally && !this.renderer.xr.isPresenting) {
232
234
  this._sizeChanged = false;
@@ -237,8 +239,11 @@ export class Context {
237
239
  this.updateAspect(camera);
238
240
  this.renderer.setSize(width, height);
239
241
  this.renderer.setPixelRatio(window.devicePixelRatio);
240
- this.renderer.domElement.style.width = this.domWidth + "px";
241
- this.renderer.domElement.style.height = this.domHeight + "px";
242
+ // avoid setting pixel values here since this can cause pingpong updates
243
+ // e.g. when system scale is set to 125%
244
+ // https://github.com/needle-tools/needle-engine-support/issues/69
245
+ this.renderer.domElement.style.width = "100%";
246
+ this.renderer.domElement.style.height = "100%";
242
247
  if (this.composer) {
243
248
  this.composer.setSize(width, height);
244
249
  this.composer.setPixelRatio(window.devicePixelRatio);