pixelViewport.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef EQ_PIXELVIEWPORT_H
00019 #define EQ_PIXELVIEWPORT_H
00020
00021 #include <eq/client/viewport.h>
00022 #include <eq/client/pixel.h>
00023 #include <eq/client/zoom.h>
00024 #include <eq/client/types.h>
00025
00026 #include <eq/base/base.h>
00027 #include <eq/base/debug.h>
00028
00029
00030 #include <limits>
00031
00032 namespace eq
00033 {
00037 class PixelViewport
00038 {
00039 public:
00044 PixelViewport() : x(0), y(0), w(-1), h(-1) {}
00045
00046 PixelViewport( const int32_t x_, const int32_t y_,
00047 const int32_t w_, const int32_t h_ )
00048 : x(x_), y(y_), w(w_), h(h_) {}
00050
00054 void invalidate() { x = 0; y = 0; w = -1; h = -1; }
00055
00060 bool isValid() const { return (w>=0 && h>=0); }
00061
00066 bool hasArea() const { return (w>0 && h>0); }
00067
00069 uint32_t getArea() const { return w * h; }
00070
00075 void apply( const Viewport& rhs )
00076 {
00077
00078 const int32_t xEnd = x + static_cast<int32_t>((rhs.x+rhs.w)*w);
00079 const int32_t yEnd = y + static_cast<int32_t>((rhs.y+rhs.h)*h);
00080
00081 x += static_cast<int32_t>( w * rhs.x );
00082 y += static_cast<int32_t>( h * rhs.y );
00083 w = xEnd - x;
00084 h = yEnd - y;
00085 }
00086
00087 void apply( const Pixel& pixel )
00088 {
00089 if( pixel.w > 1 )
00090 {
00091 int32_t newWidth = w / pixel.w;
00092
00093
00094
00095 if( w - ( newWidth * pixel.w ) != 0 )
00096 ++newWidth;
00097
00098 w = newWidth;
00099 }
00100 if( pixel.h > 1 )
00101 {
00102 int32_t newHeight = h / pixel.h;
00103
00104
00105
00106 if( h - ( newHeight * pixel.h ) != 0 )
00107 ++newHeight;
00108
00109 h = newHeight;
00110 }
00111 }
00112
00113 void apply( const Zoom& zoom )
00114 {
00115 if( zoom == Zoom::NONE )
00116 return;
00117
00118 x = static_cast< int32_t >( x * zoom.x() + .5f );
00119 y = static_cast< int32_t >( y * zoom.y() + .5f );
00120 w = static_cast< int32_t >( w * zoom.x() + .5f );
00121 h = static_cast< int32_t >( h * zoom.y() + .5f );
00122 }
00123
00124 const PixelViewport getSubPVP( const Viewport& rhs ) const
00125 {
00126 if( rhs == Viewport::FULL )
00127 return *this;
00128
00129 PixelViewport result;
00130
00131
00132 const int32_t xEnd = x + static_cast<int32_t>((rhs.x+rhs.w)*w);
00133 const int32_t yEnd = y + static_cast<int32_t>((rhs.y+rhs.h)*h);
00134
00135 result.x = x + static_cast<int32_t>( w * rhs.x );
00136 result.y = y + static_cast<int32_t>( h * rhs.y );
00137 result.w = xEnd - result.x;
00138 result.h = yEnd - result.y;
00139
00140 return result;
00141 }
00142
00143 const Viewport getSubVP( const PixelViewport& rhs ) const
00144 {
00145 if( *this == rhs )
00146 return Viewport::FULL;
00147
00148 if( !rhs.hasArea( ))
00149 return Viewport( static_cast<float>( x ),
00150 static_cast<float>( y ), 0.f, 0.f );
00151
00152 return Viewport( ( x - rhs.x )/ static_cast<float>( rhs.w ),
00153 ( y - rhs.y )/ static_cast<float>( rhs.h ),
00154 ( w )/ static_cast<float>( rhs.w ),
00155 ( h )/ static_cast<float>( rhs.h ));
00156 }
00157
00158 const Zoom getZoom( const PixelViewport& rhs ) const
00159 {
00160 if( *this == rhs )
00161 return Zoom::NONE;
00162
00163 if( !rhs.hasArea( ))
00164 return Zoom( std::numeric_limits< float >::max(),
00165 std::numeric_limits< float >::max( ));
00166
00167 return Zoom( w / static_cast<float>( rhs.w ),
00168 h / static_cast<float>( rhs.h ));
00169 }
00170
00172 int32_t getXEnd() const { return x+w; }
00173
00175 int32_t getYEnd() const { return y+h; }
00176
00177 const PixelViewport operator + ( const Vector2i& offset ) const
00178 {
00179 return PixelViewport( x+offset.x(), y+offset.y(), w, h );
00180 }
00181
00182 const PixelViewport operator * ( const eq::Pixel& pixel ) const
00183 {
00184 return PixelViewport( x, y, w * pixel.w, h * pixel.h );
00185 }
00186 PixelViewport& operator *= ( const eq::Pixel& pixel )
00187 {
00188 w *= pixel.w;
00189 h *= pixel.h;
00190 x += pixel.x;
00191 y += pixel.y;
00192 return *this;
00193 }
00194
00195 bool operator == ( const PixelViewport& rhs ) const
00196 {
00197 return ( x==rhs.x && y==rhs.y && w==rhs.w && h==rhs.h );
00198 }
00199 bool operator != ( const PixelViewport& rhs ) const
00200 {
00201 return ( x!=rhs.x || y!=rhs.y || w!=rhs.w || h!=rhs.h );
00202 }
00203
00205 void merge( const PixelViewport& rhs )
00206 {
00207 if( *this == rhs || !rhs.hasArea() )
00208 return;
00209
00210 if( !hasArea() )
00211 {
00212 *this = rhs;
00213 return;
00214 }
00215
00216 const int32_t sEx = x + w;
00217 const int32_t sEy = y + h;
00218 const int32_t dEx = rhs.x + rhs.w;
00219 const int32_t dEy = rhs.y + rhs.h;
00220
00221 x = EQ_MIN( x, rhs.x );
00222 y = EQ_MIN( y, rhs.y );
00223 w = EQ_MAX( sEx, dEx ) - x;
00224 h = EQ_MAX( sEy, dEy ) - y;
00225 }
00226
00228 void intersect( const PixelViewport& rhs )
00229 {
00230 if( *this == rhs )
00231 return;
00232
00233 if( !rhs.isValid() || !isValid() )
00234 {
00235 invalidate();
00236 return;
00237 }
00238
00239 if( !rhs.hasArea() || !hasArea() )
00240 {
00241 x = 0;
00242 y = 0;
00243 w = 0;
00244 h = 0;
00245 return;
00246 }
00247
00248 const int32_t sEx = x + w;
00249 const int32_t sEy = y + h;
00250 const int32_t dEx = rhs.x + rhs.w;
00251 const int32_t dEy = rhs.y + rhs.h;
00252
00253 x = EQ_MAX( x, rhs.x );
00254 y = EQ_MAX( y, rhs.y );
00255 w = EQ_MIN( sEx, dEx ) - x;
00256 h = EQ_MIN( sEy, dEy ) - y;
00257 }
00258
00260
00266 bool isPointInside( const int32_t pX, const int32_t pY ) const
00267 {
00268 if( pX < x || pY < y || pX > (x+w) || pY > (y+h) )
00269 return false;
00270 return true;
00271 }
00272
00273 int32_t x;
00274 int32_t y;
00275 int32_t w;
00276 int32_t h;
00277 };
00278
00279 inline std::ostream& operator << ( std::ostream& os,
00280 const PixelViewport& pvp )
00281 {
00282 os << "[ " << pvp.x << " " << pvp.y << " " << pvp.w << " " << pvp.h
00283 <<" ]";
00284 return os;
00285 }
00286 }
00287
00288 #endif // EQ_PIXELVIEWPORT_H