diff --git a/README.md b/README.md index 943918f5b..98c12d745 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

-[![RuView: spaces become signals, with an animated conceptual RF field](assets/readme/hero-spatial-v5.svg)](docs/user-guide.md) +[![RuView: spaces become signals, with an animated conceptual RF field](assets/readme/hero-spatial-v6.svg)](docs/user-guide.md) @@ -67,7 +67,7 @@ Every WiFi router already fills your space with radio waves. When people move, b - + diff --git a/assets/readme/feature-pose-spatial-v6.svg b/assets/readme/feature-pose-spatial-v6.svg new file mode 100644 index 000000000..9340c5627 --- /dev/null +++ b/assets/readme/feature-pose-spatial-v6.svg @@ -0,0 +1,47 @@ +Pose researchTrain and compare body keypoints. Live accuracy differs from benchmarks. Conceptual animation; follow the linked source for capability limits.RUVIEW / 03Pose researchTrain and compare body keypoints.Live accuracy differs from benchmarks.READ THE EVIDENCE diff --git a/assets/readme/hero-spatial-v6.svg b/assets/readme/hero-spatial-v6.svg new file mode 100644 index 000000000..55de901fc --- /dev/null +++ b/assets/readme/hero-spatial-v6.svg @@ -0,0 +1,47 @@ +RuView: invisible signals, visible possibilityAnimated conceptual RF room with an anatomical human silhouette, moving scan plane and propagating waves. Illustration only, not a sensor measurement.RUVIEW / SPATIAL INTELLIGENCEInvisible signals.Visible possibility.Explore the space between sensing and understanding.WiFi sensing. Edge models. Local automation.Enter the fieldRF SENSING / OPEN RESEARCH / EDGE COMPUTECONCEPTUAL RF FIELD diff --git a/assets/readme/manifest.json b/assets/readme/manifest.json index 65fbb38ff..fd65b4d1a 100644 --- a/assets/readme/manifest.json +++ b/assets/readme/manifest.json @@ -4,7 +4,7 @@ "motion": "Decorative CSS; prefers-reduced-motion supported; no script or remote dependencies", "assets": [ { - "file": "assets/readme/hero-spatial-v5.svg", + "file": "assets/readme/hero-spatial-v6.svg", "title": "RuView: invisible signals, visible possibility", "target": "docs/user-guide.md", "width": 1200, @@ -67,7 +67,7 @@ "height": 276 }, { - "file": "assets/readme/feature-pose-spatial-v5.svg", + "file": "assets/readme/feature-pose-spatial-v6.svg", "title": "Pose research", "target": "docs/benchmarks/pose-estimation-cog.md", "width": 580, diff --git a/docs/readme-visual-system.md b/docs/readme-visual-system.md index f7d2f8050..a5235bf63 100644 --- a/docs/readme-visual-system.md +++ b/docs/readme-visual-system.md @@ -54,8 +54,15 @@ The overview and RF room are conceptual illustrations, not live measurements or Sources: `docs/user-guide.md`, `docs/benchmarks/pose-estimation-cog.md`, `v2/crates/wifi-densepose-signal/README.md`, `firmware/esp32-csi-node/README.md`, `docs/integrations/home-assistant.md`, and `harness/ruview/README.md`. -The hero and pose card use `-spatial-v5.svg`: an original anatomical human +The hero and pose card use `-spatial-v6.svg`: an original anatomical human silhouette with shaded torso, head, hands and feet, overlapping limbs, surface -contours and amber joint markers. Subtle limb motion pivots behind the torso -to preserve joint continuity. This is vector artwork, not a real body scan or +contours and amber joint markers. A 1.6-second gait drives opposing arm and leg swings, weight shifts and ground +shadow compression. An 8-second CSS perspective turn and moving surface light +give the anatomical illustration depth. Each limb pivots at its own shoulder +or hip. The effect remains a projected SVG illustration, not a skinned WebGL +model. The stylesheet disables gait and perspective movement for reduced motion. +Chrome 154 validation confirmed the 3D transform, opposing limb transforms, +animation in an HTML image, and a frozen standalone SVG under reduced motion. +Reduced-motion emulation did not freeze the embedded image in that test; image +preference propagation remains a browser-dependent limitation. This is vector artwork, not a real body scan or measured pose reconstruction. Other assets retain their v4 filenames. diff --git a/scripts/render-readme-visuals.py b/scripts/render-readme-visuals.py index 7a574bae9..7e36839f0 100644 --- a/scripts/render-readme-visuals.py +++ b/scripts/render-readme-visuals.py @@ -26,13 +26,13 @@ def icon(kind,x,y,scale=1): elif kind=='pose': # Authored anatomical mesh silhouette; a conceptual figure, not captured pose data. s+='' - s+='' + s+='' # Far arm and leg provide occlusion and depth. - s+='' - s+='' - s+='' + s+='' + s+='' + s+='' # Near arm: shoulder, upper arm, elbow, forearm and closed hand. - s+='' + s+='' # Shoulder and chest taper into abdomen and pelvis. s+='' # Three-quarter head with jaw, nose and ear contour. @@ -40,10 +40,12 @@ def icon(kind,x,y,scale=1): s+='' # Surface contours make volume legible at README scale. s+=path('M-9 -23Q-2 -18 10 -23M-7 -15Q0 -11 9 -16M-6 -8Q1 -5 8 -9M-7 1Q1 5 9 1M0 -26L2 9M-4 -40Q0 -42 7 -40M2 -32L6 -34',LIME,.55,extra='opacity=".65"') - s+=path('M-5 -45Q1 -49 6 -46M-10 -22L-6 -8M9 17L17 28M-12 20L-20 42',C,.7,extra='opacity=".8"') + s+=path('M-5 -45Q1 -49 6 -46M-10 -22L-6 -8',C,.7,extra='opacity=".8"') + s+='' # Joint markers remain attached to the anatomical surface. for px,py in [(-9,-24),(10,-23),(1,-12),(2,9)]: s+=circle(px,py,3.5,AMBER,extra='stroke-opacity=".25"')+circle(px,py,1.5,AMBER,extra=f'fill="{AMBER}" class="spark"') + s+='' s+=path('M-42 -42V-53H-30M30 -53H42V-42M42 45V55H30M-30 55H-42V45',BLUE,.8) elif kind in ['vitals','models']: for j in range(3): @@ -67,6 +69,9 @@ def icon(kind,x,y,scale=1): s+=circle(0,0,15,LIME)+path('M-6 0L-1 5L8 -6',LIME,2) else:s+=path('M-35 0L0 -25L35 0L0 25Z',C,2) base='' + if kind=='pose': + base='' + return f'{base}{s}' return f'{base}{s}' def spatial(x,y,scale=1): @@ -105,6 +110,22 @@ text{font-family:"Avenir Next","Segoe UI Variable Display","Segoe UI",Helvetica, @keyframes layer{50%{transform:translateY(-5px)}} @keyframes cursor{0%,100%{transform:translateX(-35px);opacity:.3}50%{transform:translateX(35px);opacity:1}} + +.humanTurn{transform-box:fill-box;transform-origin:center 85%;animation:humanTurn 8s ease-in-out infinite} +.humanBody{animation:humanBody 1.6s ease-in-out infinite} +.armFar{transform-origin:-9px -24px;animation:armSwing 1.6s ease-in-out infinite} +.armNear{transform-origin:10px -23px;animation:armSwing 1.6s ease-in-out infinite;animation-delay:-.8s} +.legFar{transform-origin:-3px 9px;animation:legSwing 1.6s ease-in-out infinite;animation-delay:-.8s} +.legNear{transform-origin:2px 9px;animation:legSwing 1.6s ease-in-out infinite} +.humanLight{animation:humanLight 8s ease-in-out infinite} +.gaitShadow{transform-box:fill-box;transform-origin:center;animation:gaitShadow 1.6s ease-in-out infinite} +@keyframes humanTurn{0%,100%{transform:perspective(450px) rotateY(-24deg) rotateZ(-2deg)}50%{transform:perspective(450px) rotateY(24deg) rotateZ(2deg)}} +@keyframes humanBody{0%,50%,100%{transform:translateY(0)}25%,75%{transform:translateY(-2px)}} +@keyframes armSwing{0%,100%{transform:rotate(-17deg)}50%{transform:rotate(17deg)}} +@keyframes legSwing{0%,100%{transform:rotate(-12deg)}50%{transform:rotate(12deg)}} +@keyframes humanLight{0%,100%{opacity:.1}50%{opacity:.45}} +@keyframes gaitShadow{0%,50%,100%{transform:scaleX(1);opacity:.7}25%,75%{transform:scaleX(.85);opacity:.45}} + @keyframes spark{50%{opacity:.25}} @keyframes flow{to{stroke-dashoffset:-136}} @keyframes breathe{50%{opacity:.4}} @@ -116,10 +137,10 @@ text{font-family:"Avenir Next","Segoe UI Variable Display","Segoe UI",Helvetica, def frame(w,h,title,desc,body): value=_frame(w,h,title,desc,body) motion=MOTION - for name in ['float','flow','breathe','trace','scan','orbit','spark','wave','sweep','limb','stride','layer','cursor']: + for name in ['float','flow','breathe','trace','scan','orbit','spark','wave','sweep','limb','stride','layer','cursor','humanTurn','humanBody','armFar','armNear','legFar','legNear','humanLight','gaitShadow']: if f'class="{name}"' not in body: motion=re.sub(r'\.'+name+r'\{[^}]*\}', '', motion) - for name in ['float','flow','breathe','trace','scan','spark','wave','sweep','limb','layer','cursor']: + for name in ['float','flow','breathe','trace','scan','spark','wave','sweep','limb','layer','cursor','humanTurn','humanBody','armSwing','legSwing','humanLight','gaitShadow']: if f'animation:{name} ' not in motion: marker='@keyframes '+name+'{'; start=motion.find(marker) if start>=0: @@ -141,7 +162,7 @@ def frame(w,h,title,desc,body): manifest=[] def save(name,w,h,title,desc,body,target): - name+='-spatial-v5' if name in ['hero','feature-pose'] else '-spatial-v4' + name+='-spatial-v6' if name in ['hero','feature-pose'] else '-spatial-v4' s=frame(w,h,title,desc,body);raw=(s+'\n').encode('utf-8');parse_svg(raw);(OUT/(name+'.svg')).write_bytes(raw);manifest.append({'file':'assets/readme/'+name+'.svg','title':title,'target':target,'width':w,'height':h}) # Cinematic RF stage: authored projected planes, not a live measurement. s=text(48,45,'RUVIEW / SPATIAL INTELLIGENCE',12,C,extra='class="mono"')
Breathing and vital signals: open documentation and current limitations
Breathing and vital signals
Pose research and limitations: open documentation and current limitations
Pose research and limitations
Pose research and limitations: open documentation and current limitations
Pose research and limitations
Edge sensor mesh: open documentation and current limitations
Edge sensor mesh