1 /*
2  * StereoViewApp.cpp
3  *
4  * Copyright (C) 2003 J. "MUFTI" Scheurich
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program (see the file "COPYING" for details); if
18  * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19  * Cambridge, MA 02139, USA.
20  */
21 
22 #include <errno.h>
23 #include "stdafx.h"
24 #include "math.h"
25 
26 #include "DuneApp.h"
27 #include "StereoViewApp.h"
28 
StereoViewApp()29 StereoViewApp::StereoViewApp()
30    {
31    m_eyeMode = EM_NONE;
32    m_useStereo = false;
33    m_canStereo = false;
34    m_canQuadBufferStereo = false;
35    m_canAnaglyphStereo = false;
36    m_stereoType = NO_STEREO;
37    m_wantStereo = false;
38    StereoViewSetDefaults();
39    }
40 
41 void
StereoViewSetDefaults()42 StereoViewApp::StereoViewSetDefaults()
43    {
44    m_eyeHalfDist = 0.06/2.0;
45    m_eyeScreenDist = 0.8;
46    /* inexact, repair when fieldofview in Viewpoint is working */
47    /* 18.0 fieldofview of human eye */
48    /* 45.0 default fieldofview of VRML97 */
49    m_fixFieldOfView = -1;
50    m_eyeAngleFactor = 18.0/45.0;
51    accountEyeAngle();
52    m_stereoHandleSizeMult = 2.0;
53    m_cursor3dMode = CM_3DCURSOR_ALWAYS;
54    m_cursor3dWidth = 1.0;
55    m_cursor3dLength = 0.001;
56    }
57 
isAnaglyph(int stereoType)58 static bool isAnaglyph(int stereoType)
59    {
60    switch (stereoType)
61       {
62       case RED_GREEN_ANAGLYPH_STEREO:
63       case GREEN_RED_ANAGLYPH_STEREO:
64       case RED_BLUE_ANAGLYPH_STEREO:
65       case BLUE_RED_ANAGLYPH_STEREO:
66       case RED_CYAN_ANAGLYPH_STEREO:
67       case CYAN_RED_ANAGLYPH_STEREO:
68          return true;
69       }
70    return false;
71    }
72 
73 bool
canStereo(int stereoType)74 StereoViewApp::canStereo(int stereoType)
75    {
76    if (stereoType == QUAD_BUFFER_STEREO)
77        return m_canQuadBufferStereo;
78    if (isAnaglyph(stereoType))
79        return m_canAnaglyphStereo;
80    return false;
81    }
82 
83 
84 bool
isAnaglyphStereo(void)85 StereoViewApp::isAnaglyphStereo(void)
86    {
87    if (isAnaglyph(m_stereoType))
88        return true;
89    return false;
90    }
91 
92 
93 void
setStereoType(int value)94 StereoViewApp::setStereoType(int value)
95    {
96    m_stereoType = value;
97    if (value != NO_STEREO)
98        {
99        m_canStereo = true;
100        setWantStereo(true);
101        }
102    if (isAnaglyph(value))
103       m_canAnaglyphStereo = true;
104    else if (value == QUAD_BUFFER_STEREO)
105       m_canQuadBufferStereo = true;
106 }
107 
108 void
accountEyeAngle()109 StereoViewApp::accountEyeAngle()
110    {
111    m_eyeAngle=RAD2DEG(atan2(m_eyeHalfDist,m_eyeScreenDist))*m_eyeAngleFactor;
112    }
113 
114 void
StereoViewLoadPreferences()115 StereoViewApp::StereoViewLoadPreferences()
116    {
117    assert(TheApp != NULL);
118 
119    char buf[128];
120    const char* buf2;
121 
122    StereoViewSetDefaults();
123 
124    m_stereoType = TheApp->GetIntPreference("StereoType", QUAD_BUFFER_STEREO);
125    m_wantStereo = TheApp->GetBoolPreference("WantStereo", false);
126 
127    mysnprintf(buf, 128, "%f", 2 * m_eyeHalfDist);
128    buf2 = TheApp->GetPreference("EyeDistance", buf);
129    m_eyeHalfDist = atof(buf2) * 0.5;
130 
131    mysnprintf(buf, 128, "%f", m_eyeScreenDist);
132    buf2 = TheApp->GetPreference("EyeScreenDistance", buf);
133    m_eyeScreenDist = atof(buf2);
134 
135    mysnprintf(buf, 128, "%f", m_fixFieldOfView);
136    buf2 = TheApp->GetPreference("FixFieldOfView", buf);
137    m_fixFieldOfView = atof(buf2);
138 
139 
140    mysnprintf(buf, 128, "%f", m_eyeAngleFactor);
141    buf2 = TheApp->GetPreference("EyeAngleFactor", buf);
142    m_eyeAngleFactor = atof(buf2);
143 
144    mysnprintf(buf, 128, "%f", m_stereoHandleSizeMult);
145    buf2 = TheApp->GetPreference("StereoViewHandleSizeMult", buf);
146    m_stereoHandleSizeMult = atof(buf2);
147 
148 
149    m_cursor3dMode = (Cursor3dMode) TheApp->GetIntPreference("Cursor3Mode",
150                                                             m_cursor3dMode);
151 
152    mysnprintf(buf, 128, "%f", m_cursor3dWidth);
153    buf2 = TheApp->GetPreference("Cursor3dWidth", buf);
154    m_cursor3dWidth = atof(buf2);
155 
156    mysnprintf(buf, 128, "%f", m_cursor3dLength);
157    buf2 = TheApp->GetPreference("Cursor3dLength", buf);
158    m_cursor3dLength = atof(buf2);
159 
160 
161    accountEyeAngle();
162    }
163 
164 void
StereoViewSavePreferences()165 StereoViewApp::StereoViewSavePreferences()
166    {
167    assert(TheApp != NULL);
168 
169    char buf[128];
170 
171    TheApp->SetIntPreference("StereoType", m_stereoType);
172    TheApp->SetBoolPreference("WantStereo", m_wantStereo);
173 
174    mysnprintf(buf, 128, "%f", 2 * m_eyeHalfDist);
175    TheApp->SetPreference("EyeDistance", buf);
176 
177    mysnprintf(buf, 128, "%f", m_eyeScreenDist);
178    TheApp->SetPreference("EyeScreenDistance", buf);
179 
180    mysnprintf(buf, 128, "%f", m_fixFieldOfView);
181    TheApp->SetPreference("FixFieldOfView", buf);
182 
183 
184    mysnprintf(buf, 128, "%f", m_eyeAngleFactor);
185    TheApp->SetPreference("EyeAngleFactor", buf);
186 
187    mysnprintf(buf, 128, "%f", m_stereoHandleSizeMult);
188    TheApp->SetPreference("StereoViewHandleSizeMult", buf);
189 
190 
191    TheApp->SetIntPreference("Cursor3Mode", m_cursor3dMode);
192 
193    mysnprintf(buf, 128, "%f", m_cursor3dWidth);
194    TheApp->SetPreference("Cursor3dWidth", buf);
195 
196    mysnprintf(buf, 128, "%f", m_cursor3dLength);
197    TheApp->SetPreference("Cursor3dLength", buf);
198    }
199 
parseCommandlineArgumentStereoView(int & i,int argc,char ** argv)200 bool parseCommandlineArgumentStereoView(int & i,int argc, char** argv)
201    {
202    bool found = true;
203    if (strcmp(argv[i],"-nostereo")==0)
204       return found;
205    else if (strcmp(argv[i],"-eyedist")==0)
206       {
207       float eyedist;
208       if (i++>=argc) return found;
209       if (sscanf(argv[i],"%f",&eyedist)==1)
210          TheApp->setEyeDist(eyedist);
211       }
212    else if (strcmp(argv[i],"-screendist")==0)
213       {
214       float screendist;
215       if (i++>=argc) return found;
216       if (sscanf(argv[i],"%f",&screendist)==1)
217          TheApp->setEyeScreenDist(screendist);
218       }
219    else if (strcmp(argv[i],"-anaglyph")==0)
220       {
221       if (i++>=argc) return found;
222       }
223    else
224       return false;
225    return found;
226 }
227 
228 float
getEyePosition(void)229 StereoViewApp::getEyePosition(void)
230 {
231     float eyeposition=0;
232 
233     if (TheApp->useStereo())
234        {
235        // inexact "toe in" stereo method
236        if (TheApp->getEyeMode()==EM_RIGHT)
237           eyeposition= - TheApp->getEyeHalfDist();
238        else if (TheApp->getEyeMode()==EM_LEFT)
239           eyeposition= + TheApp->getEyeHalfDist();
240        }
241     return eyeposition;
242 }
243 
244