@@ -31,7 +31,10 @@ import {
3131 LinearSRGBColorSpace ,
3232 SRGBColorSpace ,
3333 FrontSide ,
34- DoubleSide
34+ DoubleSide ,
35+ SphereGeometry ,
36+ MeshBasicMaterial ,
37+ Mesh
3538} from "three" ;
3639
3740import { RoomEnvironment , pxlEffects } from "pxlNav" ;
@@ -119,6 +122,25 @@ export class SaltFlatsEnvironment extends RoomEnvironment{
119122 'releaseTime' :0 ,
120123 } ;
121124
125+ // Calculated Camera Space NDC locations
126+ // Updated on Resize
127+ this . toRadians = Math . PI / 180 ;
128+ this . ndcPositions = {
129+ 'inspectorPosition' : {
130+ basePosition : new Vector3 ( - 0.662 , - .6 , 28 ) ,
131+ ndcPosition : null
132+ } ,
133+ 'leftHoodooPosition' : {
134+ basePosition : new Vector3 ( - .9 , 0.5 , 200 ) ,
135+ ndcPosition : null
136+ } ,
137+ 'rightHoodooPosition' : {
138+ basePosition : new Vector3 ( .9 , 0.5 , 200 ) ,
139+ ndcPosition : null
140+ } ,
141+ } ;
142+
143+ this . precalculations = { } ;
122144
123145 }
124146
@@ -175,6 +197,8 @@ export class SaltFlatsEnvironment extends RoomEnvironment{
175197 coreCanvas . addEventListener ( "mousedown" , ( e ) => { this . mapOnDown ( e ) ; } , false ) ;
176198 coreCanvas . addEventListener ( "mousemove" , ( e ) => { this . mapOnMove ( e ) ; } , false ) ;
177199 coreCanvas . addEventListener ( "mouseup" , ( e ) => { this . mapOnUp ( e ) ; } , false ) ;
200+
201+ setTimeout ( ( ) => { this . setCameraSpaceNDC ( ) ; } , 0 ) ;
178202 }
179203
180204 stop ( ) {
@@ -186,6 +210,97 @@ export class SaltFlatsEnvironment extends RoomEnvironment{
186210
187211 // -- -- -- -- -- -- -- --
188212
213+ preCalculateCameraData ( sw = null , sh = null ) {
214+ if ( sw === null ) sw = this . pxlDevice . sW || window . innerWidth ;
215+ if ( sh === null ) sh = this . pxlDevice . sH || window . innerHeight ;
216+
217+ // Pre-calculate half-height for the current camera FOV
218+ let camera = this . pxlCamera . camera ;
219+ let fov = camera . fov * this . toRadians ; // Convert to radians
220+ this . precalculations [ "fovTanHalfHeight_" + fov ] = Math . tan ( fov * 0.5 ) ; // Using a default depth of 150
221+
222+ this . texelRatio . set ( 1 / sw , 1 / sh ) ;
223+
224+ // Let the camera resolve, wait to next update
225+ setTimeout ( ( ) => {
226+ this . setCameraSpaceNDC ( sw , sh ) ;
227+ this . setInspectMarkerPos ( ) ;
228+ this . checkInspectorUpdate ( ) ;
229+ } , 0 ) ;
230+ }
231+
232+ // Find Camera Space positions to place specific objects in the scene
233+ setCameraSpaceNDC ( sw = null , sh = null ) {
234+ if ( sw === null ) sw = this . pxlDevice . sW || window . innerWidth ;
235+ if ( sh === null ) sh = this . pxlDevice . sH || window . innerHeight ;
236+
237+ let aspect = sw / sh ;
238+ // Using Three.js PerspectiveCamera - this.pxlCamera.camera
239+ let camera = this . pxlCamera . camera ;
240+ let fov = camera . fov * this . toRadians ; // Convert to radians
241+
242+ // Offsets in camera space -- ( x: -1 left to 1 right, y: -1 bottom to 1 top, z: distance from camera in units )
243+ // Tweak these while testing marker placements
244+ let leftHoodooOffset = this . ndcPositions . leftHoodooPosition . basePosition . clone ( ) ;
245+ let rightHoodooOffset = this . ndcPositions . rightHoodooPosition . basePosition . clone ( ) ;
246+ let inspectOffset = this . ndcPositions . inspectorPosition . basePosition . clone ( ) ;
247+
248+ // Find Left and Right Hoodoo locations
249+ // Left Hoodoo Position
250+ this . ndcPositions . leftHoodooPosition . ndcPosition = this . cameraOffsetToWorld ( camera , fov , aspect , leftHoodooOffset ) ;
251+
252+ // Right Hoodoo Position
253+ this . ndcPositions . rightHoodooPosition . ndcPosition = this . cameraOffsetToWorld ( camera , fov , aspect , rightHoodooOffset ) ;
254+
255+ // Inspect Rabbit Druid Position
256+ this . ndcPositions . inspectorPosition . ndcPosition = this . cameraOffsetToWorld ( camera , fov , aspect , inspectOffset ) ;
257+
258+ //this.debugPlaceMarkers();
259+ }
260+
261+
262+ cameraOffsetToWorld ( camera , fov , aspect , offset ) {
263+ let depth = Math . abs ( offset . z ) ;
264+ let tanHalfFov = 0 ;
265+
266+ if ( this . precalculations . hasOwnProperty ( "fovTanHalfHeight_" + fov ) ) {
267+ tanHalfFov = this . precalculations [ "fovTanHalfHeight_" + fov ] ;
268+ } else {
269+ tanHalfFov = Math . tan ( fov * 0.5 ) ;
270+ this . precalculations [ "fovTanHalfHeight_" + fov ] = tanHalfFov ;
271+ }
272+
273+ // Actual half-height/width of the frustum at this depth
274+ let halfHeight = depth * tanHalfFov ;
275+ let halfWidth = halfHeight * aspect ;
276+
277+ let localPos = new Vector3 ( offset . x * halfWidth , offset . y * halfHeight , - depth ) ;
278+ return camera . localToWorld ( localPos ) ;
279+ }
280+
281+ // Temp visual markers to verify calculated NDC placements in-scene
282+ debugPlaceMarkers ( ) {
283+ if ( ! this . scene ) return ;
284+
285+ let markerColors = { 'leftHoodooPosition' :0xff0000 , 'rightHoodooPosition' :0x0000ff , 'inspectorPosition' :0x00ff00 } ;
286+ let markerGeo = null ;
287+
288+ for ( let key in this . ndcPositions ) {
289+ let entry = this . ndcPositions [ key ] ;
290+ if ( ! entry . ndcPosition ) continue ;
291+
292+ if ( ! entry . marker ) {
293+ if ( ! markerGeo ) markerGeo = new SphereGeometry ( 5 , 12 , 12 ) ;
294+ entry . marker = new Mesh ( markerGeo , new MeshBasicMaterial ( { color :markerColors [ key ] } ) ) ;
295+ this . scene . add ( entry . marker ) ;
296+ }
297+
298+ entry . marker . position . copy ( entry . ndcPosition ) ;
299+ }
300+ }
301+
302+ // -- -- -- -- -- -- -- --
303+
189304
190305 mapOnDown ( e ) {
191306 //let target= e.path ? e.path[0] : e.target; // Chrome or Firefox
@@ -313,18 +428,27 @@ export class SaltFlatsEnvironment extends RoomEnvironment{
313428 console.log(this.inspectController.matrixWorld.elements)
314429 console.log(this.inspectController.matrix[12],this.inspectController.matrix[13],this.inspectController.matrix[14])
315430 console.log(this.inspectorBasePos)*/
431+ this . setCameraSpaceNDC ( this . pxlDevice . sW , this . pxlDevice . sH ) ;
316432 this . setInspectMarkerPos ( ) ;
317433 }
318434
319435 setInspectMarkerPos ( ) {
436+ this . inspectMarkerPos . copy ( this . ndcPositions . inspectorPosition . ndcPosition ) ;
437+ return ;
320438 let targetInspectPos = new Vector3 ( ) ;
321439 targetInspectPos . x = 105 ;
322440 targetInspectPos . y = 14 ;
323441
324- let screenRatio = this . pxlDevice . sW / this . pxlDevice . sH ;
325- targetInspectPos . z = 2.1 + 3.00 * ( screenRatio * screenRatio ) ;
326-
442+ let screenRatio = 0 ; // this.pxlDevice.sW / this.pxlDevice.sH;
327443
444+ // Use predetermined position if it exists
445+ // It should exist, but who knows, maybe the environment doesn't load propperly or changes in the future.
446+ if ( this . ndcPositions . inspectorPosition . ndcPosition ) {
447+ targetInspectPos . copy ( this . ndcPositions . inspectorPosition . ndcPosition ) ;
448+ } else {
449+ screenRatio = this . pxlDevice . sW / this . pxlDevice . sH ;
450+ targetInspectPos . z = 2.1 + 3.00 * ( screenRatio * screenRatio ) ;
451+ }
328452 this . inspectMarkerPos . copy ( targetInspectPos ) ;
329453 }
330454
@@ -351,7 +475,8 @@ export class SaltFlatsEnvironment extends RoomEnvironment{
351475 this . inspectMode = this . inspectToMode ;
352476 this . inspectBlend . x = this . inspectMode ? 1 : 0 ;
353477
354- let targetPos = this . inspectMode ? this . inspectMarkerPos : this . inspectorBasePos ;
478+ //let targetPos = this.inspectMode ? this.inspectMarkerPos : this.inspectorBasePos;
479+ let targetPos = this . inspectMode ? this . ndcPositions . inspectorPosition . ndcPosition : this . inspectorBasePos ;
355480 this . inspectController . position . copy ( targetPos ) ;
356481
357482 if ( ! this . inspectToMode ) {
@@ -366,18 +491,18 @@ export class SaltFlatsEnvironment extends RoomEnvironment{
366491 this . inspectBlend . x = this . inspectToMode ? inspectProgress : 1 - inspectProgress ;
367492
368493 let targetPos = new Vector3 ( ) . copy ( this . inspectController . position ) ;
369- let blendPos = this . inspectToMode ? this . inspectMarkerPos : this . inspectorBasePos ;
494+ //let blendPos = this.inspectToMode ? this.inspectMarkerPos : this.inspectorBasePos;
495+ let blendPos = this . inspectToMode ? this . ndcPositions . inspectorPosition . ndcPosition : this . inspectorBasePos ;
370496 targetPos . lerp ( blendPos , inspectProgress ) ;
371497 this . inspectController . position . copy ( targetPos ) ;
372-
373498 }
374-
375499 }
376500 }
377501
378502 checkInspectorUpdate ( ) {
379503 if ( ! this . inspectTransition && this . inspectMode ) {
380- this . inspectController . position . copy ( this . inspectMarkerPos ) ;
504+ //this.inspectController.position.copy( this.inspectMarkerPos );
505+ this . inspectController . position . copy ( this . ndcPositions . inspectorPosition . ndcPosition ) ;
381506 }
382507 }
383508
@@ -408,9 +533,12 @@ export class SaltFlatsEnvironment extends RoomEnvironment{
408533 // -- -- --
409534
410535 resize ( sw , sh ) {
411- this . setInspectMarkerPos ( ) ;
412- this . checkInspectorUpdate ( ) ;
413- this . texelRatio . set ( 1 / this . pxlDevice . sW , 1 / this . pxlDevice . sH ) ;
536+ this . preCalculateCameraData ( sw , sh ) ;
537+ if ( this . inspectToMode && this . inspectController && this . ndcPositions . inspectorPosition . ndcPosition ) {
538+ setTimeout ( ( ) => {
539+ this . inspectController . position . copy ( this . ndcPositions . inspectorPosition . ndcPosition ) ;
540+ } ) ;
541+ }
414542 super . resize ( sw , sh ) ;
415543 }
416544
0 commit comments