;+ ; NAME: ; RemoteView_StereoStates ; PURPOSE: ; Takes a single viewing state and splits it up into two states ; representing a stereo pair ; CATEGORY: ; Number strangling ; CALLING SEQUENCE: FUNCTION RemoteView_StereoStates, nView, TT, Loc, Dir, Fov, Tilt, stereo=Stereo, degrees=degrees ; INPUTS: ; TT[n], Loc[3,n], Dir[2,n], Fov[n], Tilt[n] ; arrays describing n viewing states (see RemoteView) ; /stereo ; stereo=[Angle,Distance] ; /stereo if set, stereo pairs are produced using default ; settings for stereo angle (6 degrees) and ; distance (Sun-viewer distance) ; stereo=[Angle, Distance] ; if specified as a two-element array, the first ; element is used as stereo angle, the second as ; stereo distance. If the distance is set to zero ; then the viewer-origin distance Loc[2,*] is used. ; OPTIONAL INPUT PARAMETERS: ; /degrees if set, all angles are in degrees (default: radians) ; OUTPUTS: ; R scalar; type: integer ; 0 if no stereo states were calculated ; 1 if stereo states were calculate ; ; OPTIONAL OUTPUT PARAMETERS: ; (Only calculated if return value R = 1) ; TT[2*n], Loc[3,2*n], Dir[2,2*n], Fov[2,2*n], Tilt[2*n] ; The stereo pairs for the n input states are stored as ; TT[2*i ] right eye view for state i=0,n-1 ; TT[2*i+1] left eye view for state i=0,n-1 ; (Note that TT, Fov and Tilt values will be the ; same for left and right view; Loc and Dir will be ; slightly different from the input Loc and Dir) ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; ToRadians, SuperArray, EulerRotate ; PROCEDURE: ; > Called by href=RemoteView= to set up stereo pairs ; In stereo mode each state is split into a stereo pair. ; > Coordinate systems are defined in document SkyGrid.doc (probably in D:\work\doc). ; > The stereo pair states are defined in the X,Y,Z coordinate system (+Y is the ; horizontal direction toward the right). In this coordinate system the viewer ; location is at the origin and the viewing direction is the positive Z-axis. ; > The stereo pair is defined by two viewing locations close to the origin and ; two viewing direction close to the +Z axis. ; Take a point P on the +Z axis at distance StereoDist. Take viewing locations ; R on the +Y axis and L on -Y axis at equal distance to the origin such that ; the lines RP and YP connecting these points to P make an angle StereoAngle ; L and R are the positions of left and right eye, respectively. ; LP and RP are the viewing directions from left and right eye, respectively. ; The separation LR is 2*Dist*tan(StereoAngle/2.) ; MODIFICATION HISTORY: ; FEB-1998, Paul Hick (UCSD/CASS) ; MAY-2000, Paul Hick (UCSD/CASS, pphick@ucsd.edu); converted from procedure to function ;- IF n_elements(Stereo) NE 2 AND NOT keyword_set(Stereo) THEN RETURN, 0B n = Stereo IF n_elements(n) NE 2 THEN IF degrees THEN n = [6.0,0.0] ELSE n = [6.0/!radeg,0.0] StereoAngle = n[0] StereoDist = n[1] rpm = ToRadians(degrees=degrees) n = nView ; # input states n2 = n*2 ; # output states (left/right pairs) IF nView GT 1 THEN BEGIN IF n_elements(TT ) EQ 1 THEN TT = replicate (TT , n) IF n_elements(Loc ) EQ 3 THEN TT = SuperArray(Loc , n, /trail) IF n_elements(Dir ) EQ 2 THEN TT = SuperArray(Dir , n, /trail) IF n_elements(Fov ) EQ 2 THEN Fov = SuperArray(Fov , n, /trail) IF n_elements(Tilt) EQ 1 THEN Tilt = replicate (Tilt, n) ENDIF ; Convert Loc from spherical to Cartesian coordinates Loc = cv_coord(from_sphere=Loc, /to_rect, degrees=degrees) ; Double the state arrays by interleaving states for left and right views TT = reform([TT] ,1,n) Tilt = reform([Tilt],1,n) TT = reform( [TT , TT ] , n2) Loc = reform( [Loc , Loc ], 3, n2) Dir = reform( [Dir , Dir ], 2, n2) Fov = reform( [Fov , Fov ], 2, n2) Tilt = reform( [Tilt, Tilt] , n2) tanAngle = tan(StereoAngle/2.*rpm) FOR i=0,n-1 DO BEGIN i2 = i*2 ; Use viewer-origin distance for stereo distance IF StereoDist GT 0 THEN Dist = StereoDist ELSE Dist = sqrt(total(Loc[*,i2]*Loc[*,i2])) dOff = Dist*tanAngle ; Right view Left view Off = [ [0.0, dOff, 0.0], [0.0,-dOff, 0.0] ,$ ; Positions R,L on +Y/-Y axis [0.0,-dOff,Dist], [0.0, dOff,Dist] ] ; Viewing directions RP, LP in YZ plane ; The Euler angles ABG transform the vectors Off defined in the X,Y,Z ; coordinate system to the x',y',z' coordinate system. A rotation over ; -Tilt transforms from X,Y,Z system to x'',y'',z'' system Off = EulerRotate([-Tilt[i2]*rpm, !pi/2.0-Dir[1,i2]*rpm, !pi-Dir[0,i2]*rpm], Off, /rectangular) Loc[*,i2:i2+1] += Off[*,0:1] ; Positions R,L in x,y,z coordinate system ; (at this point Loc contains Cartesian coordinates) ; Convert viewing directions RP, LP to spherical coordinates Off = cv_coord(from_rect=Off[*,2:3], /to_sphere, degrees=degrees) Dir[*,i2:i2+1] = Off[0:1,*] ; Store the direction angles back into Dir ENDFOR Loc = cv_coord(from_rect=Loc, /to_sphere, degrees=degrees) ; Convert Loc back to spherical coordinates RETURN, 1B & END