00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include <OSGConfig.h>
00047
00048 #include <OSGMatrixUtility.h>
00049 #include <OSGQuaternion.h>
00050 #include <OSGNode.h>
00051
00052 #include "OSGProjectionCameraDecorator.h"
00053
00054 OSG_USING_NAMESPACE
00055
00056
00057
00058
00059
00077
00078
00079 ProjectionCameraDecorator::ProjectionCameraDecorator(void) :
00080 Inherited()
00081 {
00082 }
00083
00084 ProjectionCameraDecorator::ProjectionCameraDecorator(const ProjectionCameraDecorator &source) :
00085 Inherited(source)
00086 {
00087 }
00088
00089 ProjectionCameraDecorator::~ProjectionCameraDecorator(void)
00090 {
00091 }
00092
00093
00094
00095 void ProjectionCameraDecorator::initMethod (void)
00096 {
00097 }
00098
00099 void ProjectionCameraDecorator::changed(BitVector whichField, UInt32 origin)
00100 {
00101 Inherited::changed(whichField, origin);
00102
00103 if(whichField & SurfaceFieldMask)
00104 updateData();
00105 }
00106
00107 void ProjectionCameraDecorator::dump( UInt32 ,
00108 const BitVector ) const
00109 {
00110 SLOG << "Dump ProjectionCameraDecorator NI" << std::endl;
00111 }
00112
00115 void ProjectionCameraDecorator::updateData(void)
00116 {
00117 if(getSurface().size() != 4)
00118 {
00119 FWARNING(("ProjectionCameraDecorator: only defined for 4 point "
00120 "surfaces!\n"));
00121 return;
00122 }
00123
00124 Pnt3f p0(getSurface()[0]);
00125 Vec3f d1,d2,n;
00126
00127 d1 = getSurface()[1] - p0;
00128 d2 = getSurface()[3] - p0;
00129
00130 n = d1.cross(d2);
00131 if(n.isZero())
00132 {
00133 FWARNING(("ProjectionCameraDecorator: normal is zero, surface "
00134 "ill-defined!\n"));
00135 return;
00136 }
00137
00138 ProjectionCameraDecoratorPtr ptr(this);
00139 beginEditCP(ptr, LeftFieldMask | BottomFieldMask | NormalFieldMask |
00140 WidthFieldMask | HeightFieldMask );
00141 ptr->setLeft (Plane(d1,p0));
00142 ptr->setBottom(Plane(d2,p0));
00143 ptr->setNormal(Plane(n ,p0));
00144 ptr->setWidth (d1.length());
00145 ptr->setHeight(d2.length());
00146 endEditCP (ptr, LeftFieldMask | BottomFieldMask | NormalFieldMask |
00147 WidthFieldMask | HeightFieldMask );
00148
00149 }
00150
00151
00152 void ProjectionCameraDecorator::getViewing(Matrix &result,
00153 UInt32 OSG_CHECK_ARG(width ),
00154 UInt32 OSG_CHECK_ARG(height))
00155 {
00156 if ( getUser() == NullFC )
00157 {
00158 FWARNING(("ProjectionCameraDecorator::getViewing: no user!"));
00159 result.setIdentity();
00160 return;
00161 }
00162
00163 getUser()->getToWorld( result );
00164 result.invert();
00165 }
00166
00167 void ProjectionCameraDecorator::getProjection(Matrix &result,
00168 UInt32 OSG_CHECK_ARG(width ),
00169 UInt32 OSG_CHECK_ARG(height))
00170 {
00171 CameraPtr camera = getDecoratee();
00172
00173 if(camera == NullFC)
00174 {
00175 FWARNING(("ProjectionCameraDecorator::getProjection: no decoratee!\n"));
00176 result.setIdentity();
00177 return;
00178 }
00179
00180 Matrix cam,user;
00181
00182 camera->getBeacon()->getToWorld(cam);
00183 getUser()->getToWorld(user);
00184 cam.invert();
00185
00186 cam.mult(user);
00187
00188 Pnt3f viewer(cam[3]);
00189
00190 Real32 eyeFac;
00191
00192 if(getLeftEye())
00193 {
00194 eyeFac=-.5;
00195 }
00196 else
00197 {
00198 eyeFac=+.5;
00199 }
00200
00201 viewer += Vec3f(cam[0]) * eyeFac * getEyeSeparation();
00202
00203 Real32 dist = getNormal().distance(viewer),
00204 dl = getLeft ().distance(viewer),
00205 db = getBottom().distance(viewer),
00206 f = camera->getNear() / dist;
00207
00208 MatrixFrustum(result, -dl * f, (getWidth ()-dl) * f,
00209 -db * f, (getHeight()-db) * f,
00210 camera->getNear(), camera->getFar() );
00211 }
00212
00213
00214 void ProjectionCameraDecorator::getProjectionTranslation(Matrix &result,
00215 UInt32 OSG_CHECK_ARG(width ),
00216 UInt32 OSG_CHECK_ARG(height))
00217 {
00218 CameraPtr camera = getDecoratee();
00219
00220 if(camera == NullFC)
00221 {
00222 FFATAL(("ProjectionCameraDecorator::getProjectionTranslation: "
00223 "no decoratee!\n"));
00224 result.setIdentity();
00225 return;
00226 }
00227
00228 Matrix cam,user;
00229
00230 camera->getBeacon()->getToWorld(cam);
00231 getUser()->getToWorld(user);
00232
00233 cam.invert();
00234 cam.mult(user);
00235
00236 Vec3f dir(getNormal().getNormal()),
00237 up (getBottom().getNormal()),
00238 right;
00239 Vec3f pos(cam[3]);
00240
00241 Real32 eyeFac;
00242
00243 if(getLeftEye())
00244 {
00245 eyeFac=-.5;
00246 }
00247 else
00248 {
00249 eyeFac=+.5;
00250 }
00251
00252 pos += Vec3f(cam[0]) * eyeFac * getEyeSeparation();
00253
00254 right = up.cross(dir);
00255 up = dir.cross(right);
00256
00257 result.setIdentity();
00258 result.setValue(right, up, dir, pos);
00259 result.invert();
00260
00261 result.mult(cam);
00262 #if 0
00263 static bool hack = true;
00264 Quaternion q( getNormal().getNormal(), Vec3f(0,0,1));
00265
00266 Vec3f v;
00267 Real32 a;
00268 q.getValueAsAxisDeg(v,a);
00269
00270
00271 if(hack && a > 50)
00272 {
00273 q.getValue(result);
00274
00275 Real32 ang1 = 54.44;
00276 Real32 ang2 = 6.27;
00277
00278 if(v[1] < 0) ang1 = -ang1;
00279
00280 Quaternion q1,q2;
00281 Matrix m1,m2;
00282
00283 q1.setValueAsAxisDeg(0,1,0,ang1);
00284 q2.setValueAsAxisDeg(1,0,0,ang2);
00285
00286 q1.getValue(m1);
00287 q2.getValue(m2);
00288
00289 result = m2;
00290 result.mult(m1);
00291 }
00292 #endif
00293 }
00294
00295
00296
00297
00298
00299 #ifdef __sgi
00300 #pragma set woff 1174
00301 #endif
00302
00303 #ifdef OSG_LINUX_ICC
00304 #pragma warning( disable : 177 )
00305 #endif
00306
00307 namespace
00308 {
00309 static char cvsid_cpp[] = "@(#)$Id: $";
00310 static char cvsid_hpp[] = OSGPROJECTIONCAMERADECORATOR_HEADER_CVSID;
00311 static char cvsid_inl[] = OSGPROJECTIONCAMERADECORATOR_INLINE_CVSID;
00312 }