root / PyOpenGLDemo / proesch / stereo / stereoCamera.py @ 1
History  View  Annotate  Download (3.9 kB)
1 
# helper class for stereo visualisation using OpenGL


2 
# The underlying equations and their implementation are by courtesy of

3 
# Paul Bourke, http://local.wasp.uwa.edu.au/~pbourke/projection/stereorender/

4 
#

5 
# Copyright (C) 2007 "Peter Roesch" <Peter.Roesch@fhaugsburg.de>

6 
#

7 
# This code is licensed under the PyOpenGL License.

8 
# Details are given in the file license.txt included in this distribution.

9  
10 
import sys 
11 
import math 
12  
13 
try:

14 
from OpenGL.GLUT import * 
15 
from OpenGL.GL import * 
16 
from OpenGL.GLU import * 
17 
except:

18 
print ''' Error: PyOpenGL not installed properly !!''' 
19 
sys.exit( ) 
20  
21 
class StereoCamera( object ): 
22 
"""Helper class for stereo frustum calculation.

23 

24 
Frustum settings for left and right camera are

25 
calculated according to parameters e.g. eye

26 
separtion"""

27 
DEG2RAD = math.pi / 180.0

28  
29 
def __init__( self ): 
30 
self.centerPosition = [ 0, 0, 10 ] 
31 
self.viewingDirection = [ 0, 0, 1 ] 
32 
self.upVector = [ 0, 1, 0 ] 
33 
self.near, self.far, self.focalLength = 0.1, 100.0, 10.0 
34 
self.whRatio = 4.0/3.0 
35 
self.aperture = 60.0 
36 
self.eyeSeparation = self.focalLength / 20.0 
37 
self.eyePositionLeft, self.eyePositionRight = [ ], [ ] 
38 
self.frustumLeft = ( )

39 
self.frustumRight = ( )

40 
self.lookAtRight = ( )

41 
self.lookAtLeft = ( )

42  
43 
def difference( self, a, b): 
44 
"""Calculate difference vector."""

45 
if not (len( a ) == len ( b )): 
46 
print ''' Error: different vector length in sub''' 
47 
sys.exit( ) 
48 
c=[ 0 for i in range( len( a ) ) ] 
49 
for i in range( len( a )): 
50 
c[i] = a[i]b[i] 
51 
return c

52  
53 
def sum( self, a, b ): 
54 
"""Calculate sum vector."""

55 
if not (len( a ) == len ( b )): 
56 
print ''' Error: different vector length in add''' 
57 
sys.exit( ) 
58 
c=[ 0 for i in range( len( a ) ) ] 
59 
for i in range( len( a ) ): 
60 
c[i] = a[i]+b[i] 
61 
return c

62  
63 
def scale( self, a, f ): 
64 
"""Scale a vector."""

65 
for i in range( len( a ) ): 
66 
a[i] = a[i]*f 
67  
68 
def crossProduct( self, a, b ): 
69 
"""Cross product of two 3D vectors."""

70 
if len( a ) != 3 or len( b ) != 3: 
71 
print ''' Error: cross product needs 3D vectors as input''' 
72 
sys.exit( ) 
73 
c=[ 0, 0, 0 ] 
74 
c[0] = a[1]*b[2]a[2]*b[1] 
75 
c[1] = a[2]*b[0]a[0]*b[2] 
76 
c[2] = a[0]*b[1]a[1]*b[0] 
77 
return c

78  
79 
def update( self ): 
80 
"""Calculate left and right frustum."""

81 
betweenTheEyes = self.crossProduct( self.viewingDirection, self.upVector ) 
82 
self.scale( betweenTheEyes, self.eyeSeparation/2.0 ) 
83 
self.eyePositionLeft = self.difference( self.centerPosition, 
84 
betweenTheEyes ) 
85 
self.eyePositionRight = self.sum( self.centerPosition, betweenTheEyes ) 
86 
self.lookAtLeft = (

87 
self.eyePositionLeft[0], 
88 
self.eyePositionLeft[1], 
89 
self.eyePositionLeft[2], 
90 
self.eyePositionLeft[0]+self.viewingDirection[0], 
91 
self.eyePositionLeft[1]+self.viewingDirection[1], 
92 
self.eyePositionLeft[2]+self.viewingDirection[2], 
93 
self.upVector[0], self.upVector[1], self.upVector[2] ) 
94 
self.lookAtRight = (

95 
self.eyePositionRight[0], 
96 
self.eyePositionRight[1], 
97 
self.eyePositionRight[2], 
98 
self.eyePositionRight[0]+self.viewingDirection[0], 
99 
self.eyePositionRight[1]+self.viewingDirection[1], 
100 
self.eyePositionRight[2]+self.viewingDirection[2], 
101 
self.upVector[0], self.upVector[1], self.upVector[2] ) 
102 
perpDelta = self.near * math.tan( self.aperture*StereoCamera.DEG2RAD/2.0 ) 
103 
parallaxCorrection = self.near/self.focalLength; 
104 
self.frustumLeft = (

105 
self.whRatio*perpDelta+self.eyeSeparation/2.0*parallaxCorrection, 
106 
self.whRatio*perpDelta+self.eyeSeparation/2.0*parallaxCorrection, 
107 
perpDelta, perpDelta, self.near, self.far ) 
108 
self.frustumRight = (

109 
self.whRatio*perpDeltaself.eyeSeparation/2.0*parallaxCorrection, 
110 
self.whRatio*perpDeltaself.eyeSeparation/2.0*parallaxCorrection, 
111 
perpDelta, perpDelta, self.near, self.far ) 
112  
113 
# test program

114 
if __name__ == '__main__' : 
115 
sC = StereoCamera( ) 
116 
a=[1,0,0] 
117 
b=[0,0,1] 
118 
print sC.crossProduct( a, b )

119 
sC.update( ) 
120 
print sC.lookAtLeft

121 
print sC.frustumLeft

122 
print sC.lookAtRight

123 
print sC.frustumRight
