faradayfuture commited on
Commit
4361791
·
verified ·
1 Parent(s): 2aa82aa

ego viewer: hand-pose 3D no longer blank when paused at t=0 (snap past leading all-zero pose frames)

Browse files
Files changed (1) hide show
  1. egoSample/mego.html +19 -5
egoSample/mego.html CHANGED
@@ -166,8 +166,11 @@ function loadSig(slug){
166
  const prev=document.getElementById('sigjs'); if(prev) prev.remove();
167
  window.EPDATA=window.EPDATA||{};
168
  const done=()=>{ SIG=window.EPDATA[slug]; if(!SIG) return; sizeCanvases(); drawCharts();
169
- let fv=0; for(let k=0;k<SIG.n;k++){ if(SIG.handL.valid[k]>0.5&&SIG.handR.valid[k]>0.5){ fv=k/SIG.fps; break; } }
170
- if(master && master.currentTime<0.05 && fv>0) setTime(fv); else if(master){ updateUI(master.currentTime||0); blitMain(); }
 
 
 
171
  // start playback only once the master tile can actually play, so the per-frame
172
  // slave sync chases a real timestamp instead of hammering seeks against t=0
173
  const go=()=>{ if(_toggle && !playing) _toggle(); };
@@ -658,9 +661,20 @@ function smoothKp(pos,x,W,k){
658
  acc[0]+=p[0]*wt; acc[1]+=p[1]*wt; acc[2]+=p[2]*wt; sw+=wt; }
659
  return sw>0 ? [acc[0]/sw,acc[1]/sw,acc[2]/sw] : med;
660
  }
661
- function handAt(side,t){ const [j0,j1,a]=sfrac(t); const H=SIG['hand'+side];
662
- if(!(handOk(H.pos[j0])||handOk(H.pos[j1]))) return null;
663
- const x=Math.max(0,Math.min(SIG.n-1.0001, t*SIG.fps)), W=CAL.smoothW||0;
 
 
 
 
 
 
 
 
 
 
 
664
  let pts;
665
  if(W>0){ pts=[]; for(let k=0;k<21;k++){ const p=smoothKp(H.pos,x,W,k); if(!p){ pts=null; break; } pts.push(p); } }
666
  if(!pts){ const A=H.pos[j0],B=H.pos[j1]; pts=(handOk(A)&&handOk(B))?A.map((p,i)=>lerpV(p,B[i],a)):(handOk(A)?A:B); }
 
166
  const prev=document.getElementById('sigjs'); if(prev) prev.remove();
167
  window.EPDATA=window.EPDATA||{};
168
  const done=()=>{ SIG=window.EPDATA[slug]; if(!SIG) return; sizeCanvases(); drawCharts();
169
+ // park on the first frame that actually has hand data (the raw pose arrays have
170
+ // ~2 leading all-zero frames) so the 3D panel isn't blank while the clip is paused
171
+ let fk=0; while(fk<SIG.n && !(handOk(SIG.handL.pos[fk])||handOk(SIG.handR.pos[fk]))) fk++;
172
+ const fv = fk<SIG.n ? (fk+0.5)/SIG.fps : 0;
173
+ if(master && fv>0 && master.currentTime<fv-0.01) setTime(fv); else if(master){ updateUI(master.currentTime||0); blitMain(); }
174
  // start playback only once the master tile can actually play, so the per-frame
175
  // slave sync chases a real timestamp instead of hammering seeks against t=0
176
  const go=()=>{ if(_toggle && !playing) _toggle(); };
 
661
  acc[0]+=p[0]*wt; acc[1]+=p[1]*wt; acc[2]+=p[2]*wt; sw+=wt; }
662
  return sw>0 ? [acc[0]/sw,acc[1]/sw,acc[2]/sw] : med;
663
  }
664
+ function handAt(side,t){ const H=SIG['hand'+side], N=SIG.n;
665
+ let x=Math.max(0,Math.min(N-1.0001, t*SIG.fps));
666
+ // MEgo hand pose carries a few all-zero frames at the very start/end of each
667
+ // episode. If the viewer is parked exactly there (e.g. paused at t=0 because the
668
+ // browser blocked video autoplay), snap to the nearest populated frame so the
669
+ // panel shows the first/last real pose instead of going blank.
670
+ const ok=j=>handOk(H.pos[j]);
671
+ if(!ok(Math.floor(x)) && !ok(Math.ceil(x))){
672
+ let hi=Math.ceil(x); while(hi<N && !ok(hi)) hi++;
673
+ let lo=Math.floor(x); while(lo>=0 && !ok(lo)) lo--;
674
+ if(hi>=N && lo<0) return null;
675
+ x = (hi<N && (lo<0 || hi-x<=x-lo)) ? hi : lo;
676
+ }
677
+ const j0=Math.floor(x), j1=Math.min(N-1,j0+1), a=x-j0, W=CAL.smoothW||0;
678
  let pts;
679
  if(W>0){ pts=[]; for(let k=0;k<21;k++){ const p=smoothKp(H.pos,x,W,k); if(!p){ pts=null; break; } pts.push(p); } }
680
  if(!pts){ const A=H.pos[j0],B=H.pos[j1]; pts=(handOk(A)&&handOk(B))?A.map((p,i)=>lerpV(p,B[i],a)):(handOk(A)?A:B); }