Line data Source code
1 :
2 : /* Copyright (c) 2006-2011, Stefan Eilemann <eile@equalizergraphics.com>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #include "frustumData.h"
19 :
20 : #include <eq/fabric/projection.h>
21 : #include <eq/fabric/wall.h>
22 :
23 : #ifndef M_PI
24 : # define M_PI 3.14159265358979323846264338327
25 : #endif
26 : #define DEG2RAD( angle ) ( (angle) * static_cast<float>(M_PI) / 180.f )
27 :
28 : namespace eq
29 : {
30 : namespace server
31 : {
32 :
33 7366 : FrustumData::FrustumData()
34 : : _width(0.f)
35 : , _height(0.f)
36 7366 : , _type( Wall::TYPE_FIXED )
37 : {
38 7366 : }
39 :
40 86 : void FrustumData::applyWall( const fabric::Wall& wall )
41 : {
42 86 : Vector3f u = wall.bottomRight - wall.bottomLeft;
43 86 : Vector3f v = wall.topLeft - wall.bottomLeft;
44 86 : Vector3f w = u.cross( v );
45 :
46 86 : _type = wall.type;
47 86 : _width = u.normalize();
48 86 : _height = v.normalize();
49 86 : w.normalize();
50 :
51 86 : _xfm.array[0] = u[0];
52 86 : _xfm.array[1] = v[0];
53 86 : _xfm.array[2] = w[0];
54 86 : _xfm.array[3] = 0.;
55 :
56 86 : _xfm.array[4] = u[1];
57 86 : _xfm.array[5] = v[1];
58 86 : _xfm.array[6] = w[1];
59 86 : _xfm.array[7] = 0.;
60 :
61 86 : _xfm.array[8] = u[2];
62 86 : _xfm.array[9] = v[2];
63 86 : _xfm.array[10] = w[2];
64 86 : _xfm.array[11] = 0.;
65 :
66 86 : const Vector3f center = (wall.bottomRight + wall.topLeft) * 0.5f;
67 86 : _xfm.array[12] = -u.dot( center );
68 86 : _xfm.array[13] = -v.dot( center );
69 86 : _xfm.array[14] = -w.dot( center );
70 86 : _xfm.array[15] = 1.;
71 86 : }
72 :
73 0 : void FrustumData::applyProjection( const fabric::Projection& projection )
74 : {
75 0 : const float cosH = cosf( DEG2RAD( projection.hpr[0] ));
76 0 : const float sinH = sinf( DEG2RAD( projection.hpr[0] ));
77 0 : const float cosP = cosf( DEG2RAD( projection.hpr[1] ));
78 0 : const float sinP = sinf( DEG2RAD( projection.hpr[1] ));
79 0 : const float cosR = cosf( DEG2RAD( projection.hpr[2] ));
80 0 : const float sinR = sinf( DEG2RAD( projection.hpr[2] ));
81 :
82 : // HPR Matrix = -roll[z-axis] * -pitch[x-axis] * -head[y-axis]
83 : const float rot[9] =
84 : {
85 0 : sinR*sinP*sinH + cosR*cosH, cosR*sinP*sinH - sinR*cosH, cosP*sinH,
86 0 : cosP*sinR, cosP*cosR, -sinP,
87 0 : sinR*sinP*cosH - cosR*sinH, cosR*sinP*cosH + sinR*sinH, cosP*cosH
88 0 : };
89 :
90 : // translation = HPR x -origin
91 0 : const Vector3f& origin = projection.origin;
92 0 : const float distance = projection.distance;
93 : const Vector3f trans(
94 0 : -( rot[0]*origin[0] + rot[3]*origin[1] + rot[6]*origin[2] ),
95 0 : -( rot[1]*origin[0] + rot[4]*origin[1] + rot[7]*origin[2] ),
96 0 : -( rot[2]*origin[0] + rot[5]*origin[1] + rot[8]*origin[2] ));
97 :
98 0 : _xfm.array[0] = rot[0];
99 0 : _xfm.array[1] = rot[1];
100 0 : _xfm.array[2] = rot[2];
101 0 : _xfm.array[3] = 0.;
102 :
103 0 : _xfm.array[4] = rot[3];
104 0 : _xfm.array[5] = rot[4];
105 0 : _xfm.array[6] = rot[5];
106 0 : _xfm.array[7] = 0.;
107 :
108 0 : _xfm.array[8] = rot[6];
109 0 : _xfm.array[9] = rot[7];
110 0 : _xfm.array[10] = rot[8];
111 0 : _xfm.array[11] = 0.;
112 :
113 0 : _xfm.array[12] = trans[0];
114 0 : _xfm.array[13] = trans[1];
115 0 : _xfm.array[14] = trans[2] + distance;
116 0 : _xfm.array[15] = 1.;
117 :
118 0 : _width = distance * 2.f * tanf(DEG2RAD( .5f * projection.fov[0] ));
119 0 : _height = distance * 2.f * tanf(DEG2RAD( .5f * projection.fov[1] ));
120 0 : _type = Wall::TYPE_FIXED;
121 0 : }
122 :
123 0 : std::ostream& operator << ( std::ostream& os, const FrustumData& frustumData )
124 : {
125 0 : os << "size: " << frustumData.getWidth() << "x" << frustumData.getHeight()
126 0 : << " xfm: " << frustumData.getTransform() << std::endl;
127 0 : return os;
128 : }
129 :
130 : }
131 27 : }
|