(*Copyright 1990 Wolfram Research Inc. *)

(* :Title: Show Stereo Images *)

(* :Author: Larry Calmer *)

(* :Summary:

    Takes a Graphics3D image and creates a 
    stereoscopic pair of Graphic3D images
*)  


Options[ ShowStereo ] =
  {
   AngularSeperation     -> .06,
   StereoWindowSize      -> {1265,470},
   StereoWindowPlacement -> {{7,512},{7,-18}},
   SaveStereoPair        -> False
  }

BeginPackage["ShowStereo`", "Global`"]

ShowStereo::usage = "ShowStereo['Graphic3D'], Options:  AngularSeperation, \
SaveStereoPair, StereoWindowSize, StereoWindowPlacement"

AngularSeperation::usage = "StereoShow Option: Angular Seperation of the two \
view points in Radians. Default AngularSeperation -> .06"

StereoWindowSize::usage = "StereoShow Option: A list of 2 Integers specifying \
the width and height of an individual winodow of the stereo pair. Default \
StereoWindowSize -> {1265,470}"

StereoWindowPlacement::usage = "StereoShow Option: A list of 2 Integer pairs, \
specifying the placement of the upper left corner of the Left and Right views \
respectively. Default StereoWindowPlacement -> {{7,512},{7,-18}}"

SaveStereoPair::usage = "StereoShow Option: Setting SaveStereoPair to True \
will induce a prompt for the filename, which must be a string (use quotation \
marks if not a previously defined string). left.ps & right.ps will be \
appended to this filename to create the two filenames used.  Default \
SaveStereoPair -> False"

Begin["`Private`"]

StereoCrossProduct[v1_,v2_]:={
                               -(v1[[3]] v2[[2]]) + v1[[2]] v2[[3]] ,
                                 v1[[3]] v2[[1]]  - v1[[1]] v2[[3]] ,
                               -(v1[[2]] v2[[1]]) + v1[[1]] v2[[2]] 
                             };

ShowStereo[the3DGraphic_,opts___Rule] := 
Module[{angsep, swinds, swindp, swindl, swindr, sspair, viewline, viewdist,
        viewcenterleft, viewcenterright, viewpointleft, viewpointright,
        viewvertical, viewpoint, filename, tempDisplay, ropts, tp},

angsep = AngularSeperation/2   /. {opts} /. Options[ShowStereo];
swinds = StereoWindowSize      /. {opts} /. Options[ShowStereo];
swindp = StereoWindowPlacement /. {opts} /. Options[ShowStereo]; 
sspair = SaveStereoPair        /. {opts} /. Options[ShowStereo];

swindl = {swindp[[1]],{swinds[[1]]+swindp[[1,1]],swinds[[2]]+swindp[[1,2]]}};
swindr = {swindp[[2]],{swinds[[1]]+swindp[[2,1]],swinds[[2]]+swindp[[2,2]]}};

ropts = {opts};

tp=Position[ropts,AngularSeperation];
If[tp =!= {},ropts = Delete[ropts,tp[[1,1]]]];
tp=Position[ropts,StereoWindowPlacement];
If[tp =!= {},ropts = Delete[ropts,tp[[1,1]]]];
tp=Position[ropts,StereoWindowSize];
If[tp =!= {},ropts = Delete[ropts,tp[[1,1]]]];
tp=Position[ropts,SaveStereoPair];
If[tp =!= {},ropts = Delete[ropts,tp[[1,1]]]];


viewpoint    = ViewPoint    /. {opts} /. Options[the3DGraphic,ViewPoint] /. 
                              Options[Graphics3D,ViewPoint];
viewvertical = ViewVertical /. {opts} /. Options[the3DGraphic,ViewVertical] \
/.
                              Options[Graphics3D,ViewVertical];

viewline = StereoCrossProduct[viewpoint,viewvertical];
viewline = viewline/Sqrt[viewline[[1]]^2 + viewline[[2]]^2 + \
viewline[[3]]^2];
	   (* Normalize viewline *)
viewdist = Sqrt[viewpoint[[1]]^2 + viewpoint[[2]]^2 + viewpoint[[3]]^2];
viewcenterleft  = viewline *  Tan[angsep] * viewdist ;
viewcenterright = viewline * -Tan[angsep] * viewdist ; 
viewvertical = StereoCrossProduct[viewline,viewpoint];
viewpointleft  = viewpoint + viewcenterleft;
viewpointright = viewpoint + viewcenterright;

If[sspair,
Print["Saving File"];
filename=Input["Name of File to Save? "];
sspair=!Input["Show Stereo Image on Screen? (True/False) "];

tempDisplay = $Display;

$Display  = StringJoin[filename,"right.ps"];

pp1=Show[the3DGraphic,ViewPoint->viewpointright,
        ViewVertical->viewvertical,ViewCenter->viewcenterright,
        SphericalRegion->True, ropts ,DisplayFunction->Identity];

$Display  = StringJoin[filename,"left.ps"];

pp2=Show[the3DGraphic,ViewPoint->viewpointleft, 
        ViewVertical->viewvertical,ViewCenter->viewcenterleft,
        SphericalRegion->True, ropts ,DisplayFunction->Identity];
Show[GraphicsArray[{pp1,pp2}]];

$Display = tempDisplay
];

If[!sspair,
$DisplayWidth=swindr[[2,1]]-swindr[[1,1]];
$DisplayY=swindr[[2,2]];
$DisplayX=swindr[[1,1]];
$DisplayHeight=swindr[[1,2]]-swindr[[2,2]];

pp1=Show[the3DGraphic,ViewPoint->viewpointright, ViewVertical->viewvertical,
     ViewCenter->viewcenterright, SphericalRegion->True,ropts ,DisplayFunction->Identity];

$DisplayWidth=swindl[[2,1]]-swindl[[1,1]]; 
$DisplayY=swindl[[2,2]];
$DisplayX=swindl[[1,1]]; 
$DisplayHeight=swindl[[1,2]]-swindl[[2,2]]; 

pp2=Show[the3DGraphic,ViewPoint->viewpointleft, ViewVertical->viewvertical,
     ViewCenter->viewcenterleft, SphericalRegion->True,ropts ,DisplayFunction->Identity];
     
     Show[GraphicsArray[{pp1,pp2}]];
]
]
End[]
EndPackage[]

Print ["-- ShowStereo Function Loaded --"]


(*
\!\(\*FormBox[
  RowBox[{"{", 
    RowBox[{\(AngularSeperation -> 0.06`\), ",", \(StereoWindowSize -> {1265, 470}\), ",", 
      RowBox[{"StereoWindowPlacement", "->", 
        RowBox[{"(", "\[NoBreak]", GridBox[{
              {"7", "512"},
              {"7", \(-18\)}
              },
            ColumnAlignments->{Decimal}], "\[NoBreak]", ")"}]}], ",", \(SaveStereoPair -> False\)}], "}"}], TraditionalForm]\)
*)
(*
ShowStereo`
*)
(*
ShowStereo['Graphic3D'], Options:  AngularSeperation, SaveStereoPair, StereoWindowSize, StereoWindowPlacement
\
*)
(*
StereoShow Option: Angular Seperation of the two view points in Radians. Default AngularSeperation -> .06
\
*)
(*
StereoShow Option: A list of 2 Integers specifying the width and height of an individual winodow of the stereo pair. Default StereoWindowSize -> {1265,470}
\
*)
(*
StereoShow Option: A list of 2 Integer pairs, specifying the placement of the upper left corner of the Left and Right views respectively. Default StereoWindowPlacement -> {{7,512},{7,-18}}
\
*)
(*
StereoShow Option: Setting SaveStereoPair to True will induce a prompt for the filename, which must be a string (use quotation marks if not a previously defined string). left.ps & right.ps will be appended to this filename to create the two filenames used.  Default SaveStereoPair -> False
\
*)
(*
ShowStereo`Private`
*)
(*
ShowStereo`Private`
*)
(*
-- ShowStereo Function Loaded --
*)
