RickDakan commited on
Commit
aa9528b
·
1 Parent(s): 96635ca

feat: body follows head continuously; body sweeps in idle scan

Browse files
Files changed (1) hide show
  1. app.js +13 -7
app.js CHANGED
@@ -28,8 +28,10 @@ const TRACK = {
28
  maxPitchUpDeg: 45, // how far above level the head may look while tracking (nose up)
29
  maxPitchDownDeg: 25, // how far below level
30
  maxHeadYawFromBodyDeg: 55, // hard SDK limit is 65
31
- bodyFollowStartDeg: 22, // head-body offset that starts the body turning
32
- bodyRateDegPerSec: 40,
 
 
33
  maxBodyYawDeg: 150, // hard SDK limit is 160
34
  noFaceResetSec: 3.0, // ease back to center after this long without a face
35
  noticeAfterAbsentSec: 4.0, // (legacy) new-arrival nod gap; per-person nod is handled by the tracker now
@@ -485,11 +487,12 @@ class HowdyApp {
485
  let yaw = this.headYaw + dYaw;
486
  let pitch = clamp(this.headPitch + dPitch, -TRACK.maxPitchUpDeg, TRACK.maxPitchDownDeg);
487
 
488
- // Body follows when the head is far off the body's axis
489
  if (this.bodyFollow) {
490
  const offset = yaw - this.bodyYaw;
491
  if (Math.abs(offset) > TRACK.bodyFollowStartDeg) {
492
- const move = Math.sign(offset) * Math.min(Math.abs(offset), TRACK.bodyRateDegPerSec * dt);
 
493
  this.bodyYaw = clamp(this.bodyYaw + move, -TRACK.maxBodyYawDeg, TRACK.maxBodyYawDeg);
494
  }
495
  }
@@ -517,10 +520,13 @@ class HowdyApp {
517
  // Slow look-around while nobody is close: head only, body drifts home
518
  scan(t, dt) {
519
  const k = Math.min(1, dt * 1.5);
520
- const yaw = TRACK.scanAmpDeg * Math.sin((t / TRACK.scanPeriodSec) * Math.PI * 2);
521
- this.headYaw = lerp(this.headYaw, this.bodyYaw + yaw, k);
 
 
 
 
522
  this.headPitch = lerp(this.headPitch, TRACK.restPitchDeg, k);
523
- if (Math.abs(this.bodyYaw) > 0.5) this.bodyYaw = lerp(this.bodyYaw, 0, k * 0.5); else this.bodyYaw = 0;
524
  }
525
 
526
  easeHome(dt) {
 
28
  maxPitchUpDeg: 45, // how far above level the head may look while tracking (nose up)
29
  maxPitchDownDeg: 25, // how far below level
30
  maxHeadYawFromBodyDeg: 55, // hard SDK limit is 65
31
+ bodyFollowStartDeg: 6, // head-body offset beyond which the body turns to settle under the head
32
+ bodyRateDegPerSec: 70, // max body turn speed
33
+ bodyGainPerSec: 2.5, // body speed = offset * gain (capped at bodyRateDegPerSec); higher = body leads sooner
34
+ scanBodyAmpDeg: 35, // idle look-around: how far the body sweeps (head adds scanAmpDeg on top)
35
  maxBodyYawDeg: 150, // hard SDK limit is 160
36
  noFaceResetSec: 3.0, // ease back to center after this long without a face
37
  noticeAfterAbsentSec: 4.0, // (legacy) new-arrival nod gap; per-person nod is handled by the tracker now
 
487
  let yaw = this.headYaw + dYaw;
488
  let pitch = clamp(this.headPitch + dPitch, -TRACK.maxPitchUpDeg, TRACK.maxPitchDownDeg);
489
 
490
+ // Body settles under the head: speed proportional to the offset, so the head leads and the body follows through
491
  if (this.bodyFollow) {
492
  const offset = yaw - this.bodyYaw;
493
  if (Math.abs(offset) > TRACK.bodyFollowStartDeg) {
494
+ const speed = Math.min(TRACK.bodyRateDegPerSec, Math.abs(offset) * TRACK.bodyGainPerSec);
495
+ const move = Math.sign(offset) * Math.min(Math.abs(offset) - TRACK.bodyFollowStartDeg * 0.5, speed * dt);
496
  this.bodyYaw = clamp(this.bodyYaw + move, -TRACK.maxBodyYawDeg, TRACK.maxBodyYawDeg);
497
  }
498
  }
 
520
  // Slow look-around while nobody is close: head only, body drifts home
521
  scan(t, dt) {
522
  const k = Math.min(1, dt * 1.5);
523
+ const phase = (t / TRACK.scanPeriodSec) * Math.PI * 2;
524
+ // Body sweeps slowly; head leads the body a little (phase-advanced) so it looks like it's peering around
525
+ const bodyTarget = this.bodyFollow ? TRACK.scanBodyAmpDeg * Math.sin(phase) : 0;
526
+ const headTarget = bodyTarget + TRACK.scanAmpDeg * 0.5 * Math.sin(phase + 0.6);
527
+ this.bodyYaw = clamp(lerp(this.bodyYaw, bodyTarget, k * 0.6), -TRACK.maxBodyYawDeg, TRACK.maxBodyYawDeg);
528
+ this.headYaw = lerp(this.headYaw, headTarget, k);
529
  this.headPitch = lerp(this.headPitch, TRACK.restPitchDeg, k);
 
530
  }
531
 
532
  easeHome(dt) {