00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "frustrum.h"
00021
00022 #include <QtGui/QMatrix4x4>
00023
00024 using namespace GluonGraphics;
00025
00026 class Frustrum::FrustrumPrivate
00027 {
00028 public:
00029 FrustrumPrivate()
00030 {
00031 mode = FM_ORTHO;
00032 }
00033 FrustrumPrivate( const FrustrumPrivate& other )
00034 : matrix( other.matrix )
00035 {
00036
00037 }
00038
00039 enum Mode
00040 {
00041 FM_ORTHO,
00042 FM_ADJUSTED_ORTHO,
00043 FM_PERSPECTIVE
00044 };
00045
00046 Mode mode;
00047
00048 QMatrix4x4 matrix;
00049
00050 QRectF viewPlane;
00051 float nearPlane;
00052 float farPlane;
00053 float fov;
00054 };
00055
00056 Frustrum::Frustrum()
00057 : d( new FrustrumPrivate )
00058 {
00059 d->matrix.ortho( -50, 50, -50, 50, 1, 100 );
00060 }
00061
00062 Frustrum::Frustrum( const GluonGraphics::Frustrum& other )
00063 : d( other.d )
00064 {
00065
00066 }
00067
00068 Frustrum& Frustrum::operator=( const GluonGraphics::Frustrum& other )
00069 {
00070 d->matrix = other.d->matrix;
00071
00072 return *this;
00073 }
00074
00075
00076 Frustrum::~Frustrum()
00077 {
00078 delete d;
00079 }
00080
00081 QMatrix4x4
00082 Frustrum::projectionMatrix()
00083 {
00084 return d->matrix;
00085 }
00086
00087 bool
00088 Frustrum::containsPoint( const QVector3D& point )
00089 {
00090 return false;
00091 }
00092
00093 bool
00094 Frustrum::containsSphere( const QVector3D& point, float radius )
00095 {
00096 return false;
00097 }
00098
00099 float Frustrum::nearPlane()
00100 {
00101 return d->nearPlane;
00102 }
00103
00104 float Frustrum::farPlane()
00105 {
00106 return d->farPlane;
00107 }
00108
00109 QRectF Frustrum::viewPlane()
00110 {
00111 return d->viewPlane;
00112 }
00113
00114 void
00115 Frustrum::setOrthographic( float left, float right, float bottom, float top, float near, float far )
00116 {
00117 d->matrix.setToIdentity();
00118 d->matrix.ortho( left, right, bottom, top, near, far );
00119
00120 d->nearPlane = near;
00121 d->farPlane = far;
00122
00123 d->viewPlane.setCoords( left, top, right, bottom );
00124
00125 d->mode = FrustrumPrivate::FM_ORTHO;
00126 }
00127
00128 void
00129 Frustrum::setOrthoAdjusted( const QSizeF& area, float aspect, float near, float far )
00130 {
00131 float visibleWidth = area.width();
00132 float visibleHeight = area.height();
00133
00134 if( aspect > 1.f )
00135 {
00136 visibleWidth = visibleWidth * aspect;
00137 }
00138 else
00139 {
00140 visibleHeight = visibleHeight * ( 1 / aspect );
00141 }
00142
00143 d->matrix.setToIdentity();
00144 d->matrix.ortho( -( visibleWidth / 2 ), visibleWidth / 2, -( visibleHeight / 2 ), visibleHeight / 2, near, far );
00145
00146 d->nearPlane = near;
00147 d->farPlane = far;
00148
00149 d->viewPlane.setCoords( -( area.width() / 2 ), -( area.height() / 2 ), area.width() / 2, area.height() / 2 );
00150
00151 d->mode = FrustrumPrivate::FM_ADJUSTED_ORTHO;
00152 }
00153
00154 void
00155 Frustrum::setPerspective( float fov, float aspect, float near, float far )
00156 {
00157 d->matrix.setToIdentity();
00158 d->matrix.perspective( fov, aspect, near, far );
00159
00160 d->nearPlane = near;
00161 d->farPlane = far;
00162 d->fov = fov;
00163
00164
00165
00166 d->mode = FrustrumPrivate::FM_PERSPECTIVE;
00167 }
00168
00169 void Frustrum::updateFrustrum( float aspect )
00170 {
00171 switch( d->mode )
00172 {
00173 case FrustrumPrivate::FM_ORTHO:
00174 break;
00175 case FrustrumPrivate::FM_ADJUSTED_ORTHO:
00176 setOrthoAdjusted( d->viewPlane.size(), aspect, d->nearPlane, d->farPlane );
00177 break;
00178 case FrustrumPrivate::FM_PERSPECTIVE:
00179 setPerspective( d->fov, aspect, d->nearPlane, d->farPlane );
00180 break;
00181 }
00182 }
00183
00184
00185
00186
00187
00188
00189
00190