Spaces:
Running
Running
mego viewer: HF download links for dataset files, spans auto-scroll to current step, projection off by default
Browse files- egoSample/mego.html +19 -8
egoSample/mego.html
CHANGED
|
@@ -114,7 +114,7 @@ const EPS = D.eps, SKC = D.skc, CAL = D.cal;
|
|
| 114 |
const CAMS = ["head_fisheye","head_fisheye_left","head_fisheye_right","head_stereo_left","head_stereo_right"];
|
| 115 |
const KLAB = {wild:"In-the-wild", sim:"Simulated-scenario (staged)"};
|
| 116 |
const AX = {x:"#e0616f", y:"#41c76b", z:"#4f8ff7"};
|
| 117 |
-
let cur=-1, vids=[], master=null, playing=false, EP=null, SIG=null, raf=0, _toggle=null;
|
| 118 |
let orbH={yaw:0,pitch:-0.28,drag:0}, orbP={yaw:0,pitch:-0.28,drag:0};
|
| 119 |
|
| 120 |
const esc = s => (s||'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
|
|
@@ -177,6 +177,7 @@ function loadSig(slug){
|
|
| 177 |
|
| 178 |
/* ---------- render ---------- */
|
| 179 |
function render(){
|
|
|
|
| 180 |
const e=EP, dur=e.duration, segs=e.segments;
|
| 181 |
const skc=s=>SKC[s]||'#666';
|
| 182 |
|
|
@@ -204,14 +205,15 @@ function render(){
|
|
| 204 |
`<span class="it"><span class="sw" style="background:${skc(s)}"></span>${s} <b style="color:#e6e8ee">${e.skills[s]}</b></span>`).join('');
|
| 205 |
const validRows = Object.entries(e.valids).map(([k,v])=>
|
| 206 |
`<div class="ro"><span class="k">${k}</span><span class="v ${v<0.98?'':'hi'}">${(v*100).toFixed(1)}%</span></div>`).join('');
|
| 207 |
-
const
|
| 208 |
-
const
|
|
|
|
| 209 |
const camDl = CAMS.map(c=>`<a class="fc dl" href="media/${e.slug}/${c}.mp4" download="${e.slug}_${c}.mp4">${c}.mp4</a>`).join('');
|
| 210 |
const refChips = [
|
| 211 |
-
|
| 212 |
'meta/ff/segments.parquet','meta/ff/episode_meta.parquet',
|
| 213 |
'meta/ff/camera_params.json','meta/ff/quality.json','meta/info.json'
|
| 214 |
-
].map(f=>`<
|
| 215 |
|
| 216 |
document.getElementById('main').innerHTML = `
|
| 217 |
<header>
|
|
@@ -249,7 +251,7 @@ function render(){
|
|
| 249 |
<button id="play">▶</button>
|
| 250 |
<input type="range" id="seek" min="0" max="1000" value="0">
|
| 251 |
<span class="t" id="tlab">0:00.00 / ${fmt(dur)}</span>
|
| 252 |
-
<label><input type="checkbox" id="ovck"
|
| 253 |
</div>
|
| 254 |
<div class="badges" style="padding:0 20px;margin-top:8px">
|
| 255 |
<span class="bdg"><b>${e.nframes}</b> frames</span>
|
|
@@ -295,7 +297,7 @@ function render(){
|
|
| 295 |
<div class="panel" style="margin:14px 20px 30px;padding:11px 16px">
|
| 296 |
<div class="rt">episode clips — click to download</div>
|
| 297 |
<div class="files" style="padding:0 0 6px">${camDl}</div>
|
| 298 |
-
<div class="rt" style="margin-top:8px">dataset files ·
|
| 299 |
<div class="files" style="padding:0">${refChips}</div>
|
| 300 |
</div>`;
|
| 301 |
|
|
@@ -390,8 +392,17 @@ function updateUI(t){
|
|
| 390 |
const ci=curSpan(t);
|
| 391 |
document.getElementById('roSk').textContent = ci>=0?segs[ci].skill:'–';
|
| 392 |
document.getElementById('roSp').textContent = ci>=0?`${ci+1} / ${segs.length}`:'–';
|
| 393 |
-
document.querySelectorAll('#slist .si')
|
|
|
|
| 394 |
document.querySelectorAll('#chips .chip').forEach((el,k)=>el.classList.toggle('on',k===ci));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 395 |
if(SIG){
|
| 396 |
const j=Math.min(SIG.n-1, Math.round(t*SIG.fps));
|
| 397 |
const gx=SIG.headImu.gyro[j], ax=SIG.headImu.acc[j];
|
|
|
|
| 114 |
const CAMS = ["head_fisheye","head_fisheye_left","head_fisheye_right","head_stereo_left","head_stereo_right"];
|
| 115 |
const KLAB = {wild:"In-the-wild", sim:"Simulated-scenario (staged)"};
|
| 116 |
const AX = {x:"#e0616f", y:"#41c76b", z:"#4f8ff7"};
|
| 117 |
+
let cur=-1, vids=[], master=null, playing=false, EP=null, SIG=null, raf=0, _toggle=null, _lastCi=-2;
|
| 118 |
let orbH={yaw:0,pitch:-0.28,drag:0}, orbP={yaw:0,pitch:-0.28,drag:0};
|
| 119 |
|
| 120 |
const esc = s => (s||'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
|
|
|
|
| 177 |
|
| 178 |
/* ---------- render ---------- */
|
| 179 |
function render(){
|
| 180 |
+
_lastCi=-2;
|
| 181 |
const e=EP, dur=e.duration, segs=e.segments;
|
| 182 |
const skc=s=>SKC[s]||'#666';
|
| 183 |
|
|
|
|
| 205 |
`<span class="it"><span class="sw" style="background:${skc(s)}"></span>${s} <b style="color:#e6e8ee">${e.skills[s]}</b></span>`).join('');
|
| 206 |
const validRows = Object.entries(e.valids).map(([k,v])=>
|
| 207 |
`<div class="ro"><span class="k">${k}</span><span class="v ${v<0.98?'':'hi'}">${(v*100).toFixed(1)}%</span></div>`).join('');
|
| 208 |
+
const HF = 'https://huggingface.co/datasets/faradayfuture/egoSample';
|
| 209 |
+
const HFDIR = HF+'/tree/main/mego_'+e.slug;
|
| 210 |
+
const raw = f => HF+'/resolve/main/mego_'+e.slug+'/'+f;
|
| 211 |
const camDl = CAMS.map(c=>`<a class="fc dl" href="media/${e.slug}/${c}.mp4" download="${e.slug}_${c}.mp4">${c}.mp4</a>`).join('');
|
| 212 |
const refChips = [
|
| 213 |
+
'data/file-000.parquet',
|
| 214 |
'meta/ff/segments.parquet','meta/ff/episode_meta.parquet',
|
| 215 |
'meta/ff/camera_params.json','meta/ff/quality.json','meta/info.json'
|
| 216 |
+
].map(f=>`<a class="fc dl" href="${raw(f)}" target="_blank" rel="noopener">${f}</a>`).join('');
|
| 217 |
|
| 218 |
document.getElementById('main').innerHTML = `
|
| 219 |
<header>
|
|
|
|
| 251 |
<button id="play">▶</button>
|
| 252 |
<input type="range" id="seek" min="0" max="1000" value="0">
|
| 253 |
<span class="t" id="tlab">0:00.00 / ${fmt(dur)}</span>
|
| 254 |
+
<label><input type="checkbox" id="ovck"> project hand pose on head_fisheye</label>
|
| 255 |
</div>
|
| 256 |
<div class="badges" style="padding:0 20px;margin-top:8px">
|
| 257 |
<span class="bdg"><b>${e.nframes}</b> frames</span>
|
|
|
|
| 297 |
<div class="panel" style="margin:14px 20px 30px;padding:11px 16px">
|
| 298 |
<div class="rt">episode clips — click to download</div>
|
| 299 |
<div class="files" style="padding:0 0 6px">${camDl}</div>
|
| 300 |
+
<div class="rt" style="margin-top:8px">dataset files · <a href="${HFDIR}" target="_blank" rel="noopener" style="text-transform:none;color:#7fe0a0">full episode on HuggingFace →</a></div>
|
| 301 |
<div class="files" style="padding:0">${refChips}</div>
|
| 302 |
</div>`;
|
| 303 |
|
|
|
|
| 392 |
const ci=curSpan(t);
|
| 393 |
document.getElementById('roSk').textContent = ci>=0?segs[ci].skill:'–';
|
| 394 |
document.getElementById('roSp').textContent = ci>=0?`${ci+1} / ${segs.length}`:'–';
|
| 395 |
+
const slEls=document.querySelectorAll('#slist .si');
|
| 396 |
+
slEls.forEach((el,k)=>el.classList.toggle('on',k===ci));
|
| 397 |
document.querySelectorAll('#chips .chip').forEach((el,k)=>el.classList.toggle('on',k===ci));
|
| 398 |
+
// keep the current span visible inside the spans list (scrolls only that container)
|
| 399 |
+
if(ci>=0 && slEls[ci] && ci!==_lastCi){
|
| 400 |
+
const sl=document.getElementById('slist'), el=slEls[ci];
|
| 401 |
+
const top=el.offsetTop-sl.offsetTop, bot=top+el.offsetHeight;
|
| 402 |
+
if(top<sl.scrollTop || bot>sl.scrollTop+sl.clientHeight)
|
| 403 |
+
sl.scrollTop = top - sl.clientHeight/2 + el.offsetHeight/2;
|
| 404 |
+
}
|
| 405 |
+
_lastCi=ci;
|
| 406 |
if(SIG){
|
| 407 |
const j=Math.min(SIG.n-1, Math.round(t*SIG.fps));
|
| 408 |
const gx=SIG.headImu.gyro[j], ax=SIG.headImu.acc[j];
|