reze-engine 0.55.13 → 0.55.14

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/dist/camera.d.ts CHANGED
@@ -19,15 +19,16 @@ export declare class Camera {
19
19
  private canvas;
20
20
  private inputLocked;
21
21
  /**
22
- * Panning is refused while the orbit rides a bone (Engine.setCameraFollow).
22
+ * Where a pan goes while the orbit rides a bone (Engine.setCameraFollow).
23
23
  *
24
24
  * A pan moves `target`, and the follow rewrites `target` from the bone every
25
- * frame — so the drag was already going nowhere, it just spent a frame
26
- * fighting for it and read as the camera stuttering under the pointer.
27
- * Refusing it says the same thing the follow already means: while the shot is
28
- * on somebody, where it points is theirs to decide.
25
+ * frame — so a pan into the target went nowhere, and read as the camera
26
+ * stuttering under the pointer. While following, the engine points this at
27
+ * the follow's OFFSET from the bone, and a pan moves that instead: the shot
28
+ * stays on her, and the drag decides where beside her it sits. Null while
29
+ * the target is free.
29
30
  */
30
- panLocked: boolean;
31
+ panSink: Vec3 | null;
31
32
  private isDragging;
32
33
  private mouseButton;
33
34
  private lastMousePos;
@@ -1 +1 @@
1
- {"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAQ,IAAI,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAyBpD,qBAAa,MAAM;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,IAAI,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAI;IAClB;;;oFAGgF;IAChF,IAAI,EAAE,MAAM,CAAiB;IAC7B,GAAG,EAAE,MAAM,CAAU;IACrB;+EAC2E;IAC3E,SAAS,UAAQ;IAGjB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,WAAW,CAAiB;IACpC;;;;;;;;OAQG;IACH,SAAS,EAAE,OAAO,CAAQ;IAC1B,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,oBAAoB,CAAY;IAGxC,kBAAkB,EAAE,MAAM,CAAQ;IAClC,cAAc,EAAE,MAAM,CAAS;IAC/B,cAAc,EAAE,MAAM,CAAO;IAC7B,cAAc,EAAE,MAAM,CAAO;IAC7B,IAAI,EAAE,MAAM,CAAO;IACnB,IAAI,EAAE,MAAM,CAAU;IACtB,cAAc,EAAE,MAAM,CAAQ;IAC9B,cAAc,EAAE,MAAM,CAAkB;IACxC;;;;;;;;;;;OAWG;IACH,IAAI,EAAE,MAAM,CAAI;IAGhB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAAiC;IAKjD,SAAS,EAAE,OAAO,CAAQ;IAC1B,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,YAAY,CAAuB;gBAE/B,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAE,MAAoB;IAmBhG,WAAW,IAAI,IAAI;IAQnB;wFACoF;IACpF,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOpC,0FAA0F;IAC1F;;;;;;;;;;OAUG;IACH,OAAO,IAAI,UAAU;IAuBrB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAelC,OAAO,CAAC,MAAM;IAUd;;;;;;;;;;;OAWG;IACH,cAAc,IAAI,IAAI;IAItB,aAAa,IAAI,IAAI;IAqErB,OAAO,CAAC,gBAAgB;IA0CxB,OAAO,CAAC,SAAS;IAiBjB,kFAAkF;IAClF,OAAO,CAAC,mBAAmB;IAK3B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,oBAAoB;IAM5B,mBAAmB,IAAI,IAAI;IAW3B,aAAa,CAAC,MAAM,EAAE,iBAAiB;IAiBvC,aAAa;IAkBb,cAAc,CAAC,MAAM,EAAE,OAAO;IAS9B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,WAAW;IAuFnB,OAAO,CAAC,UAAU;CA+BnB"}
1
+ {"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAQ,IAAI,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAyBpD,qBAAa,MAAM;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,IAAI,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAI;IAClB;;;oFAGgF;IAChF,IAAI,EAAE,MAAM,CAAiB;IAC7B,GAAG,EAAE,MAAM,CAAU;IACrB;+EAC2E;IAC3E,SAAS,UAAQ;IAGjB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,WAAW,CAAiB;IACpC;;;;;;;;;OASG;IACH,OAAO,EAAE,IAAI,GAAG,IAAI,CAAO;IAC3B,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,oBAAoB,CAAY;IAGxC,kBAAkB,EAAE,MAAM,CAAQ;IAClC,cAAc,EAAE,MAAM,CAAS;IAC/B,cAAc,EAAE,MAAM,CAAO;IAC7B,cAAc,EAAE,MAAM,CAAO;IAC7B,IAAI,EAAE,MAAM,CAAO;IACnB,IAAI,EAAE,MAAM,CAAU;IACtB,cAAc,EAAE,MAAM,CAAQ;IAC9B,cAAc,EAAE,MAAM,CAAkB;IACxC;;;;;;;;;;;OAWG;IACH,IAAI,EAAE,MAAM,CAAI;IAGhB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAAiC;IAKjD,SAAS,EAAE,OAAO,CAAQ;IAC1B,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,YAAY,CAAuB;gBAE/B,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAE,MAAoB;IAmBhG,WAAW,IAAI,IAAI;IAQnB;wFACoF;IACpF,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOpC,0FAA0F;IAC1F;;;;;;;;;;OAUG;IACH,OAAO,IAAI,UAAU;IAuBrB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAelC,OAAO,CAAC,MAAM;IAUd;;;;;;;;;;;OAWG;IACH,cAAc,IAAI,IAAI;IAItB,aAAa,IAAI,IAAI;IAqErB,OAAO,CAAC,gBAAgB;IA0CxB,OAAO,CAAC,SAAS;IAwBjB,kFAAkF;IAClF,OAAO,CAAC,mBAAmB;IAK3B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,oBAAoB;IAM5B,mBAAmB,IAAI,IAAI;IAW3B,aAAa,CAAC,MAAM,EAAE,iBAAiB;IAiBvC,aAAa;IAkBb,cAAc,CAAC,MAAM,EAAE,OAAO;IAS9B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,WAAW;IAuFnB,OAAO,CAAC,UAAU;CA+BnB"}
package/dist/camera.js CHANGED
@@ -37,15 +37,16 @@ export class Camera {
37
37
  this.canvas = null;
38
38
  this.inputLocked = false;
39
39
  /**
40
- * Panning is refused while the orbit rides a bone (Engine.setCameraFollow).
40
+ * Where a pan goes while the orbit rides a bone (Engine.setCameraFollow).
41
41
  *
42
42
  * A pan moves `target`, and the follow rewrites `target` from the bone every
43
- * frame — so the drag was already going nowhere, it just spent a frame
44
- * fighting for it and read as the camera stuttering under the pointer.
45
- * Refusing it says the same thing the follow already means: while the shot is
46
- * on somebody, where it points is theirs to decide.
43
+ * frame — so a pan into the target went nowhere, and read as the camera
44
+ * stuttering under the pointer. While following, the engine points this at
45
+ * the follow's OFFSET from the bone, and a pan moves that instead: the shot
46
+ * stays on her, and the drag decides where beside her it sits. Null while
47
+ * the target is free.
47
48
  */
48
- this.panLocked = false;
49
+ this.panSink = null;
49
50
  this.isDragging = false;
50
51
  this.mouseButton = null; // Track which mouse button is pressed (0 = left, 2 = right)
51
52
  this.lastMousePos = { x: 0, y: 0 };
@@ -311,7 +312,14 @@ export class Camera {
311
312
  // Vertical movement: drag up pans up (positive up vector)
312
313
  const panRight = right.scale(-deltaX * panDistance);
313
314
  const panUp = up.scale(deltaY * panDistance);
314
- // Update target position smoothly
315
+ // Into the follow's offset while the shot rides a bone — see panSink.
316
+ const sink = this.panSink;
317
+ if (sink) {
318
+ sink.x += panRight.x + panUp.x;
319
+ sink.y += panRight.y + panUp.y;
320
+ sink.z += panRight.z + panUp.z;
321
+ return;
322
+ }
315
323
  this.target = this.target.add(panRight).add(panUp);
316
324
  }
317
325
  /** Far plane grows with zoom-out so big floors / distant geometry stay visible */
@@ -405,8 +413,7 @@ export class Camera {
405
413
  const deltaY = e.clientY - this.lastMousePos.y;
406
414
  if (this.mouseButton === 2) {
407
415
  // Right-click: pan the camera target
408
- if (!this.panLocked)
409
- this.panCamera(deltaX, deltaY);
416
+ this.panCamera(deltaX, deltaY);
410
417
  }
411
418
  else {
412
419
  // Left-click (or default): rotate the camera
@@ -512,8 +519,7 @@ export class Camera {
512
519
  if (isPanGesture) {
513
520
  // Primary gesture is pan (two-finger drag)
514
521
  // Use panning similar to right-click pan
515
- if (!this.panLocked)
516
- this.panCamera(midpointDeltaX, midpointDeltaY);
522
+ this.panCamera(midpointDeltaX, midpointDeltaY);
517
523
  }
518
524
  // Update tracking values
519
525
  this.lastPinchDistance = distance;
package/dist/engine.js CHANGED
@@ -6585,23 +6585,23 @@ export class Engine {
6585
6585
  this.camera.attachControl(this.canvas);
6586
6586
  }
6587
6587
  setCameraTarget(modelOrVec, boneName, offset) {
6588
- // panLocked tracks the BINDING, on every path that changes it — a target
6589
- // set to a fixed point is pannable again, and forgetting it here is how the
6590
- // pan stays dead after the follow was turned off. See Camera.panLocked.
6588
+ // panSink tracks the BINDING, on every path that changes it — a target set
6589
+ // after a follow would otherwise still send pans into an offset nothing
6590
+ // reads any more. See Camera.panSink.
6591
6591
  if (modelOrVec === null) {
6592
- this.camera.panLocked = false;
6592
+ this.camera.panSink = null;
6593
6593
  this.cameraTargetModel = null;
6594
6594
  return;
6595
6595
  }
6596
6596
  if ("x" in modelOrVec && "y" in modelOrVec && "z" in modelOrVec) {
6597
- this.camera.panLocked = false;
6597
+ this.camera.panSink = null;
6598
6598
  this.cameraTargetModel = null;
6599
6599
  this.camera.target.x = modelOrVec.x;
6600
6600
  this.camera.target.y = modelOrVec.y;
6601
6601
  this.camera.target.z = modelOrVec.z;
6602
6602
  return;
6603
6603
  }
6604
- this.camera.panLocked = true;
6604
+ this.camera.panSink = this.cameraTargetOffset;
6605
6605
  this.cameraTargetModel = modelOrVec;
6606
6606
  this.cameraTargetBoneName = boneName ?? "";
6607
6607
  this.cameraTargetOffset.x = offset?.x ?? 0;
@@ -6611,8 +6611,8 @@ export class Engine {
6611
6611
  /** Souls-style follow cam: orbit center tracks a model bone each frame. Shorthand for setCameraTarget(model, boneName, offset). */
6612
6612
  setCameraFollow(model, boneName, offset, smoothing) {
6613
6613
  // Panning sets the very thing the follow overwrites each frame, so it is
6614
- // refused for as long as the shot is riding a bone. See Camera.panLocked.
6615
- this.camera.panLocked = model !== null;
6614
+ // goes to the offset for as long as the shot is riding a bone. See Camera.panSink.
6615
+ this.camera.panSink = model !== null ? this.cameraTargetOffset : null;
6616
6616
  if (model === null) {
6617
6617
  this.cameraTargetModel = null;
6618
6618
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.55.13",
3
+ "version": "0.55.14",
4
4
  "description": "A lightweight WebGPU engine for real-time 3D MMD/PMX model rendering",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/src/camera.ts CHANGED
@@ -45,15 +45,16 @@ export class Camera {
45
45
  private canvas: HTMLCanvasElement | null = null
46
46
  private inputLocked: boolean = false
47
47
  /**
48
- * Panning is refused while the orbit rides a bone (Engine.setCameraFollow).
48
+ * Where a pan goes while the orbit rides a bone (Engine.setCameraFollow).
49
49
  *
50
50
  * A pan moves `target`, and the follow rewrites `target` from the bone every
51
- * frame — so the drag was already going nowhere, it just spent a frame
52
- * fighting for it and read as the camera stuttering under the pointer.
53
- * Refusing it says the same thing the follow already means: while the shot is
54
- * on somebody, where it points is theirs to decide.
51
+ * frame — so a pan into the target went nowhere, and read as the camera
52
+ * stuttering under the pointer. While following, the engine points this at
53
+ * the follow's OFFSET from the bone, and a pan moves that instead: the shot
54
+ * stays on her, and the drag decides where beside her it sits. Null while
55
+ * the target is free.
55
56
  */
56
- panLocked: boolean = false
57
+ panSink: Vec3 | null = null
57
58
  private isDragging: boolean = false
58
59
  private mouseButton: number | null = null // Track which mouse button is pressed (0 = left, 2 = right)
59
60
  private lastMousePos = { x: 0, y: 0 }
@@ -337,7 +338,14 @@ export class Camera {
337
338
  const panRight = right.scale(-deltaX * panDistance)
338
339
  const panUp = up.scale(deltaY * panDistance)
339
340
 
340
- // Update target position smoothly
341
+ // Into the follow's offset while the shot rides a bone — see panSink.
342
+ const sink = this.panSink
343
+ if (sink) {
344
+ sink.x += panRight.x + panUp.x
345
+ sink.y += panRight.y + panUp.y
346
+ sink.z += panRight.z + panUp.z
347
+ return
348
+ }
341
349
  this.target = this.target.add(panRight).add(panUp)
342
350
  }
343
351
 
@@ -440,7 +448,7 @@ export class Camera {
440
448
 
441
449
  if (this.mouseButton === 2) {
442
450
  // Right-click: pan the camera target
443
- if (!this.panLocked) this.panCamera(deltaX, deltaY)
451
+ this.panCamera(deltaX, deltaY)
444
452
  } else {
445
453
  // Left-click (or default): rotate the camera
446
454
  this.alpha += deltaX * this.angularSensitivity
@@ -559,7 +567,7 @@ export class Camera {
559
567
  if (isPanGesture) {
560
568
  // Primary gesture is pan (two-finger drag)
561
569
  // Use panning similar to right-click pan
562
- if (!this.panLocked) this.panCamera(midpointDeltaX, midpointDeltaY)
570
+ this.panCamera(midpointDeltaX, midpointDeltaY)
563
571
  }
564
572
 
565
573
  // Update tracking values
package/src/engine.ts CHANGED
@@ -7897,23 +7897,23 @@ export class Engine {
7897
7897
  /** Bind camera orbit center to a model's bone (Souls-style follow cam). Pass null to unbind. */
7898
7898
  setCameraTarget(model: Model | null, boneName: string, offset?: Vec3): void
7899
7899
  setCameraTarget(modelOrVec: Model | Vec3 | null, boneName?: string, offset?: Vec3): void {
7900
- // panLocked tracks the BINDING, on every path that changes it — a target
7901
- // set to a fixed point is pannable again, and forgetting it here is how the
7902
- // pan stays dead after the follow was turned off. See Camera.panLocked.
7900
+ // panSink tracks the BINDING, on every path that changes it — a target set
7901
+ // after a follow would otherwise still send pans into an offset nothing
7902
+ // reads any more. See Camera.panSink.
7903
7903
  if (modelOrVec === null) {
7904
- this.camera.panLocked = false
7904
+ this.camera.panSink = null
7905
7905
  this.cameraTargetModel = null
7906
7906
  return
7907
7907
  }
7908
7908
  if ("x" in modelOrVec && "y" in modelOrVec && "z" in modelOrVec) {
7909
- this.camera.panLocked = false
7909
+ this.camera.panSink = null
7910
7910
  this.cameraTargetModel = null
7911
7911
  this.camera.target.x = modelOrVec.x
7912
7912
  this.camera.target.y = modelOrVec.y
7913
7913
  this.camera.target.z = modelOrVec.z
7914
7914
  return
7915
7915
  }
7916
- this.camera.panLocked = true
7916
+ this.camera.panSink = this.cameraTargetOffset
7917
7917
  this.cameraTargetModel = modelOrVec
7918
7918
  this.cameraTargetBoneName = boneName ?? ""
7919
7919
  this.cameraTargetOffset.x = offset?.x ?? 0
@@ -7924,8 +7924,8 @@ export class Engine {
7924
7924
  /** Souls-style follow cam: orbit center tracks a model bone each frame. Shorthand for setCameraTarget(model, boneName, offset). */
7925
7925
  setCameraFollow(model: Model | null, boneName?: string, offset?: Vec3, smoothing?: number): void {
7926
7926
  // Panning sets the very thing the follow overwrites each frame, so it is
7927
- // refused for as long as the shot is riding a bone. See Camera.panLocked.
7928
- this.camera.panLocked = model !== null
7927
+ // goes to the offset for as long as the shot is riding a bone. See Camera.panSink.
7928
+ this.camera.panSink = model !== null ? this.cameraTargetOffset : null
7929
7929
  if (model === null) {
7930
7930
  this.cameraTargetModel = null
7931
7931
  return