@@ -316,6 +316,7 @@ <h1>Arena 3D Viewer</h1>
316316 </ div >
317317
318318 < button class ="btn " id ="reset-view "> Reset Camera View</ button >
319+ < button class ="btn " id ="fly-view "> Fly View (From Center)</ button >
319320 < button class ="btn secondary " id ="toggle-rotation "> Toggle Auto-Rotate</ button >
320321 </ div >
321322
@@ -417,7 +418,7 @@ <h3>Resolution</h3>
417418 controls = new THREE . OrbitControls ( camera , renderer . domElement ) ;
418419 controls . enableDamping = true ;
419420 controls . dampingFactor = 0.05 ;
420- controls . minDistance = 3 ;
421+ controls . minDistance = 0.1 ; // Allow getting close to center for fly view
421422 controls . maxDistance = 50 ;
422423
423424 // Lighting
@@ -517,6 +518,15 @@ <h3>Resolution</h3>
517518 controls . update ( ) ;
518519 } ) ;
519520
521+ // Fly view - camera at center looking outward
522+ document . getElementById ( 'fly-view' ) . addEventListener ( 'click' , ( ) => {
523+ // Position camera at center of arena, slightly elevated
524+ camera . position . set ( 0 , 0 , 0 ) ;
525+ // Look outward toward a panel (along positive Z)
526+ controls . target . set ( 0 , 0 , 5 ) ;
527+ controls . update ( ) ;
528+ } ) ;
529+
520530 // Auto-rotate toggle
521531 document . getElementById ( 'toggle-rotation' ) . addEventListener ( 'click' , ( ) => {
522532 autoRotate = ! autoRotate ;
@@ -583,14 +593,43 @@ <h3>Resolution</h3>
583593 function createPanelWithLEDs ( specs , width , height , depth , angle ) {
584594 const group = new THREE . Group ( ) ;
585595
586- // Panel background (black)
596+ // Panel is positioned at radius, facing inward (toward center)
597+ // The panel's local +Z axis should point toward center (inward)
598+
599+ // Panel background (black) - thin box representing the panel PCB
587600 const panelGeom = new THREE . BoxGeometry ( width , height , depth * 0.1 ) ;
588601 const panelMat = new THREE . MeshLambertMaterial ( { color : 0x111111 } ) ;
589602 const panel = new THREE . Mesh ( panelGeom , panelMat ) ;
590- panel . rotation . y = - angle + Math . PI / 2 ;
603+ // Rotate panel so its front face points toward center
604+ // Panel is at angle, needs to face inward (toward origin)
605+ panel . rotation . y = angle + Math . PI ;
591606 group . add ( panel ) ;
592607
593- // LED dots
608+ // Panel border lines (thin grey)
609+ const borderMat = new THREE . LineBasicMaterial ( { color : 0x4a5568 } ) ;
610+ const halfW = width / 2 ;
611+ const halfH = height / 2 ;
612+ const borderOffset = depth * 0.06 ; // slightly in front of panel
613+
614+ // Create border as line segments on the inner face
615+ const borderGeom = new THREE . BufferGeometry ( ) ;
616+ const borderVertices = new Float32Array ( [
617+ // Rectangle on the panel face (in local coords before rotation)
618+ - halfW , - halfH , borderOffset ,
619+ halfW , - halfH , borderOffset ,
620+ halfW , - halfH , borderOffset ,
621+ halfW , halfH , borderOffset ,
622+ halfW , halfH , borderOffset ,
623+ - halfW , halfH , borderOffset ,
624+ - halfW , halfH , borderOffset ,
625+ - halfW , - halfH , borderOffset
626+ ] ) ;
627+ borderGeom . setAttribute ( 'position' , new THREE . BufferAttribute ( borderVertices , 3 ) ) ;
628+ const border = new THREE . LineSegments ( borderGeom , borderMat ) ;
629+ border . rotation . y = angle + Math . PI ;
630+ group . add ( border ) ;
631+
632+ // LED dots - positioned on the inner face of the panel
594633 const ledRadius = Math . min ( width , height ) / ( specs . pixels_horizontal * 3 ) ;
595634 const ledSpacingX = width / specs . pixels_horizontal ;
596635 const ledSpacingY = height / specs . pixels_vertical ;
@@ -603,18 +642,16 @@ <h3>Resolution</h3>
603642 const ledGeom = new THREE . CircleGeometry ( ledRadius , 8 ) ;
604643 const led = new THREE . Mesh ( ledGeom , ledMat ) ;
605644
606- // Position LED on panel face
645+ // LED position in panel's local coordinate space
646+ // Center the grid of LEDs, offset slightly toward center (inner face)
607647 const localX = ( px - ( specs . pixels_horizontal - 1 ) / 2 ) * ledSpacingX ;
608648 const localY = ( py - ( specs . pixels_vertical - 1 ) / 2 ) * ledSpacingY ;
649+ const localZ = depth * 0.06 ; // small offset toward center
650+
651+ led . position . set ( localX , localY , localZ ) ;
609652
610- // Rotate and offset to face inward
611- const offsetDist = depth * 0.06 ;
612- led . position . set (
613- - Math . sin ( angle ) * offsetDist + localX * Math . cos ( angle ) ,
614- localY ,
615- Math . cos ( angle ) * offsetDist + localX * Math . sin ( angle )
616- ) ;
617- led . rotation . y = - angle + Math . PI / 2 ;
653+ // LED circle faces inward (toward center) - same as panel rotation
654+ led . rotation . y = angle + Math . PI ;
618655
619656 group . add ( led ) ;
620657 }
0 commit comments