@@ -630,23 +630,22 @@ <h1>
630630 </ button >
631631 < button id ="btn-stl " class ="btn-secondary " style ="grid-column: span 2 "> Export STL</ button >
632632 </ div >
633- < div class ="panel-header "> Immersive (WebXR)</ div >
634- < div class ="button-group ">
635- < button id ="btn-vr " class ="btn-secondary " disabled > Enter VR</ button >
636- < button id ="btn-ar " class ="btn-secondary " disabled > Enter AR</ button >
637- < div
638- id ="xr-status "
639- style ="
640- grid-column: span 2;
641- font-size: 0.6rem;
642- color: var(--text-muted);
643- font-family: var(--font-mono);
644- "
645- >
646- Checking WebXR support...
647- </ div >
648- </ div >
649-
633+ < div class ="panel-header "> Immersive (WebXR)</ div >
634+ < div class ="button-group ">
635+ < button id ="btn-vr " class ="btn-secondary " disabled > Enter VR</ button >
636+ < button id ="btn-ar " class ="btn-secondary " disabled > Enter AR</ button >
637+ < div
638+ id ="xr-status "
639+ style ="
640+ grid-column: span 2;
641+ font-size: 0.6rem;
642+ color: var(--text-muted);
643+ font-family: var(--font-mono);
644+ "
645+ >
646+ Checking WebXR support...
647+ </ div >
648+ </ div >
650649
651650 < div class ="math-block ">
652651 < strong > Gram Matrix Input:</ strong > < br />
692691 import { OptimizerLbfgs } from './js/optimizer-lbfgs.js' ;
693692 import { OptimizerAdam } from './js/optimizer-adam.js' ;
694693 import { OptimizerQQN } from './js/optimizer-qqn.js' ;
695- import { WebXRViewer } from './js/webxr.js' ;
694+ import { WebXRViewer } from './js/webxr.js' ;
696695
697696 /**
698697 * Spherical Gram Entropy - Interactive Demo
781780 stlControls : document . getElementById ( 'stl-controls' ) ,
782781 torusControls : document . getElementById ( 'torus-controls' ) ,
783782 stlFile : document . getElementById ( 'stl-file' ) ,
784- btnVr : document . getElementById ( 'btn-vr' ) ,
785- btnAr : document . getElementById ( 'btn-ar' ) ,
786- xrStatus : document . getElementById ( 'xr-status' ) ,
783+ btnVr : document . getElementById ( 'btn-vr' ) ,
784+ btnAr : document . getElementById ( 'btn-ar' ) ,
785+ xrStatus : document . getElementById ( 'xr-status' ) ,
787786 } ;
788787
789788 const ctx = els . canvas . getContext ( '2d' ) ;
@@ -1572,68 +1571,67 @@ <h1>
15721571 }
15731572 return new OptimizerLbfgs ( state . params . lr ) ;
15741573 }
1575- // --- WebXR Setup ---
1576- let xrViewer = null ;
1577- async function setupWebXR ( ) {
1578- if ( ! WebXRViewer . isSupported ( ) ) {
1579- els . xrStatus . textContent = 'WebXR not available in this browser.' ;
1580- return ;
1581- }
1582- // Provide the viewer with a live snapshot of the current scene.
1583- xrViewer = new WebXRViewer ( ( ) => {
1584- let triangles = null ;
1585- if (
1586- ( state . showTriangulation || state . showSolidFill ) &&
1587- state . points &&
1588- state . params . geometry === 'sphere'
1589- ) {
1590- try {
1591- triangles = getTriangles ( state . points . dataSync ( ) ) ;
1592- } catch ( e ) {
1593- triangles = null ;
1594- }
1595- }
1596- return {
1597- points : state . points ,
1598- densities : state . metrics . densities ,
1599- geometry : state . params . geometry ,
1600- triangles,
1601- } ;
1602- } ) ;
1603- xrViewer . onEnd ( ( ) => {
1604- els . btnVr . textContent = 'Enter VR' ;
1605- els . btnAr . textContent = 'Enter AR' ;
1606- } ) ;
1607- const { vr, ar } = await xrViewer . checkSessionSupport ( ) ;
1608- if ( vr ) {
1609- els . btnVr . disabled = false ;
1610- }
1611- if ( ar ) {
1612- els . btnAr . disabled = false ;
1613- }
1614- if ( vr || ar ) {
1615- els . xrStatus . textContent =
1616- 'Ready: ' + [ vr ? 'VR' : null , ar ? 'AR' : null ] . filter ( Boolean ) . join ( ' & ' ) ;
1617- } else {
1618- els . xrStatus . textContent = 'No immersive VR/AR devices detected.' ;
1619- }
1620- const enter = async ( mode , btn ) => {
1621- if ( xrViewer . session ) {
1622- await xrViewer . end ( ) ;
1623- return ;
1624- }
1625- try {
1626- await xrViewer . start ( mode ) ;
1627- btn . textContent = mode === 'immersive-ar' ? 'Exit AR' : 'Exit VR' ;
1628- } catch ( err ) {
1629- console . error ( err ) ;
1630- els . xrStatus . textContent = 'Failed to start session: ' + err . message ;
1631- }
1632- } ;
1633- els . btnVr . addEventListener ( 'click' , ( ) => enter ( 'immersive-vr' , els . btnVr ) ) ;
1634- els . btnAr . addEventListener ( 'click' , ( ) => enter ( 'immersive-ar' , els . btnAr ) ) ;
1635- }
1636-
1574+ // --- WebXR Setup ---
1575+ let xrViewer = null ;
1576+ async function setupWebXR ( ) {
1577+ if ( ! WebXRViewer . isSupported ( ) ) {
1578+ els . xrStatus . textContent = 'WebXR not available in this browser.' ;
1579+ return ;
1580+ }
1581+ // Provide the viewer with a live snapshot of the current scene.
1582+ xrViewer = new WebXRViewer ( ( ) => {
1583+ let triangles = null ;
1584+ if (
1585+ ( state . showTriangulation || state . showSolidFill ) &&
1586+ state . points &&
1587+ state . params . geometry === 'sphere'
1588+ ) {
1589+ try {
1590+ triangles = getTriangles ( state . points . dataSync ( ) ) ;
1591+ } catch ( e ) {
1592+ triangles = null ;
1593+ }
1594+ }
1595+ return {
1596+ points : state . points ,
1597+ densities : state . metrics . densities ,
1598+ geometry : state . params . geometry ,
1599+ triangles,
1600+ } ;
1601+ } ) ;
1602+ xrViewer . onEnd ( ( ) => {
1603+ els . btnVr . textContent = 'Enter VR' ;
1604+ els . btnAr . textContent = 'Enter AR' ;
1605+ } ) ;
1606+ const { vr, ar } = await xrViewer . checkSessionSupport ( ) ;
1607+ if ( vr ) {
1608+ els . btnVr . disabled = false ;
1609+ }
1610+ if ( ar ) {
1611+ els . btnAr . disabled = false ;
1612+ }
1613+ if ( vr || ar ) {
1614+ els . xrStatus . textContent =
1615+ 'Ready: ' + [ vr ? 'VR' : null , ar ? 'AR' : null ] . filter ( Boolean ) . join ( ' & ' ) ;
1616+ } else {
1617+ els . xrStatus . textContent = 'No immersive VR/AR devices detected.' ;
1618+ }
1619+ const enter = async ( mode , btn ) => {
1620+ if ( xrViewer . session ) {
1621+ await xrViewer . end ( ) ;
1622+ return ;
1623+ }
1624+ try {
1625+ await xrViewer . start ( mode ) ;
1626+ btn . textContent = mode === 'immersive-ar' ? 'Exit AR' : 'Exit VR' ;
1627+ } catch ( err ) {
1628+ console . error ( err ) ;
1629+ els . xrStatus . textContent = 'Failed to start session: ' + err . message ;
1630+ }
1631+ } ;
1632+ els . btnVr . addEventListener ( 'click' , ( ) => enter ( 'immersive-vr' , els . btnVr ) ) ;
1633+ els . btnAr . addEventListener ( 'click' , ( ) => enter ( 'immersive-ar' , els . btnAr ) ) ;
1634+ }
16371635
16381636 function resetPoints ( ) {
16391637 if ( state . points ) state . points . dispose ( ) ;
@@ -2000,7 +1998,7 @@ <h1>
20001998 setupEventListeners ( ) ;
20011999 resetPoints ( ) ;
20022000 resizeCanvas ( ) ;
2003- setupWebXR ( ) ;
2001+ setupWebXR ( ) ;
20042002 animate ( ) ;
20052003 } catch ( err ) {
20062004 console . error ( err ) ;
@@ -2011,4 +2009,4 @@ <h1>
20112009 init ( ) ;
20122010 </ script >
20132011 </ body >
2014- </ html >
2012+ </ html >
0 commit comments