frustumData.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "frustumData.h"
00019
00020 #include <eq/client/projection.h>
00021 #include <eq/client/wall.h>
00022
00023 #define DEG2RAD( angle ) ( (angle) * static_cast<float>(M_PI) / 180.f )
00024
00025 namespace eq
00026 {
00027 namespace server
00028 {
00029
00030 FrustumData::FrustumData()
00031 : _width(0.f)
00032 , _height(0.f)
00033 , _type( Wall::TYPE_FIXED )
00034 {
00035 }
00036
00037 void FrustumData::applyWall( const eq::Wall& wall )
00038 {
00039 Vector3f u = wall.bottomRight - wall.bottomLeft;
00040 Vector3f v = wall.topLeft - wall.bottomLeft;
00041 Vector3f w( u[1]*v[2] - u[2]*v[1],
00042 u[2]*v[0] - u[0]*v[2],
00043 u[0]*v[1] - u[1]*v[0] );
00044
00045 _type = wall.type;
00046 _width = u.normalize();
00047 _height = v.normalize();
00048 w.normalize();
00049
00050 _xfm.array[0] = u[0];
00051 _xfm.array[1] = v[0];
00052 _xfm.array[2] = w[0];
00053 _xfm.array[3] = 0.;
00054
00055 _xfm.array[4] = u[1];
00056 _xfm.array[5] = v[1];
00057 _xfm.array[6] = w[1];
00058 _xfm.array[7] = 0.;
00059
00060 _xfm.array[8] = u[2];
00061 _xfm.array[9] = v[2];
00062 _xfm.array[10] = w[2];
00063 _xfm.array[11] = 0.;
00064
00065 const Vector3f center((wall.bottomRight[0] + wall.topLeft[0]) * 0.5f,
00066 (wall.bottomRight[1] + wall.topLeft[1]) * 0.5f,
00067 (wall.bottomRight[2] + wall.topLeft[2]) * 0.5f);
00068
00069 _xfm.array[12] = -(u[0]*center[0] + u[1]*center[1] + u[2]*center[2]);
00070 _xfm.array[13] = -(v[0]*center[0] + v[1]*center[1] + v[2]*center[2]);
00071 _xfm.array[14] = -(w[0]*center[0] + w[1]*center[1] + w[2]*center[2]);
00072 _xfm.array[15] = 1.;
00073 }
00074
00075 void FrustumData::applyProjection( const eq::Projection& projection )
00076 {
00077 const float cosH = cosf( DEG2RAD( projection.hpr[0] ));
00078 const float sinH = sinf( DEG2RAD( projection.hpr[0] ));
00079 const float cosP = cosf( DEG2RAD( projection.hpr[1] ));
00080 const float sinP = sinf( DEG2RAD( projection.hpr[1] ));
00081 const float cosR = cosf( DEG2RAD( projection.hpr[2] ));
00082 const float sinR = sinf( DEG2RAD( projection.hpr[2] ));
00083
00084
00085 const float rot[9] =
00086 {
00087 sinR*sinP*sinH + cosR*cosH, cosR*sinP*sinH - sinR*cosH, cosP*sinH,
00088 cosP*sinR, cosP*cosR, -sinP,
00089 sinR*sinP*cosH - cosR*sinH, cosR*sinP*cosH + sinR*sinH, cosP*cosH
00090 };
00091
00092
00093 const Vector3f& origin = projection.origin;
00094 const float distance = projection.distance;
00095 const Vector3f trans(
00096 -( rot[0]*origin[0] + rot[3]*origin[1] + rot[6]*origin[2] ),
00097 -( rot[1]*origin[0] + rot[4]*origin[1] + rot[7]*origin[2] ),
00098 -( rot[2]*origin[0] + rot[5]*origin[1] + rot[8]*origin[2] ));
00099
00100 _xfm.array[0] = rot[0];
00101 _xfm.array[1] = rot[1];
00102 _xfm.array[2] = rot[2];
00103 _xfm.array[3] = 0.;
00104
00105 _xfm.array[4] = rot[3];
00106 _xfm.array[5] = rot[4];
00107 _xfm.array[6] = rot[5];
00108 _xfm.array[7] = 0.;
00109
00110 _xfm.array[8] = rot[6];
00111 _xfm.array[9] = rot[7];
00112 _xfm.array[10] = rot[8];
00113 _xfm.array[11] = 0.;
00114
00115 _xfm.array[12] = trans[0];
00116 _xfm.array[13] = trans[1];
00117 _xfm.array[14] = trans[2] + distance;
00118 _xfm.array[15] = 1.;
00119
00120 _width = distance * 2.f * tanf(DEG2RAD( .5f * projection.fov[0] ));
00121 _height = distance * 2.f * tanf(DEG2RAD( .5f * projection.fov[1] ));
00122 _type = Wall::TYPE_FIXED;
00123 }
00124
00125 std::ostream& operator << ( std::ostream& os, const FrustumData& frustumData )
00126 {
00127 os << "size: " << frustumData.getWidth() << "x" << frustumData.getHeight()
00128 << " xfm: " << frustumData.getTransform() << std::endl;
00129 return os;
00130 }
00131
00132 }
00133 }