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 <cstdlib>
00044 #include <cstdio>
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
00060
00061
00062
00063 ProjectionCameraDecorator::ProjectionCameraDecorator(void) :
00064 Inherited()
00065 {
00066 }
00067
00068 ProjectionCameraDecorator::ProjectionCameraDecorator(
00069 const ProjectionCameraDecorator &source) :
00070
00071 Inherited(source)
00072 {
00073 }
00074
00075 ProjectionCameraDecorator::~ProjectionCameraDecorator(void)
00076 {
00077 }
00078
00079
00080
00081 void ProjectionCameraDecorator::initMethod(InitPhase ePhase)
00082 {
00083 Inherited::initMethod(ePhase);
00084 }
00085
00086 void ProjectionCameraDecorator::changed(ConstFieldMaskArg whichField,
00087 UInt32 origin,
00088 BitVector details)
00089 {
00090 Inherited::changed(whichField, origin, details);
00091
00092 if(whichField & SurfaceFieldMask)
00093 updateData();
00094 }
00095
00096 void ProjectionCameraDecorator::dump( UInt32 ,
00097 const BitVector ) const
00098 {
00099 SLOG << "Dump ProjectionCameraDecorator NI" << std::endl;
00100 }
00101
00104 void ProjectionCameraDecorator::updateData(void)
00105 {
00106 if(getMFSurface()->size() != 4)
00107 {
00108 FWARNING(("ProjectionCameraDecorator: only defined for 4 point "
00109 "surfaces!\n"));
00110 return;
00111 }
00112
00113 Pnt3f p0(getSurface(0));
00114 Vec3f d1,d2,n;
00115
00116 d1 = getSurface(1) - p0;
00117 d2 = getSurface(3) - p0;
00118
00119 n = d1.cross(d2);
00120
00121 if(n.isZero())
00122 {
00123 FWARNING(("ProjectionCameraDecorator: normal is zero, surface "
00124 "ill-defined!\n"));
00125 return;
00126 }
00127
00128 this->setLeft (Plane(d1,p0));
00129 this->setBottom(Plane(d2,p0));
00130 this->setNormal(Plane(n ,p0));
00131 this->setWidth (d1.length());
00132 this->setHeight(d2.length());
00133 }
00134
00135
00136 void ProjectionCameraDecorator::getViewing(Matrix &result,
00137 UInt32 OSG_CHECK_ARG(width ),
00138 UInt32 OSG_CHECK_ARG(height))
00139 {
00140 Node *pUser = getUser();
00141
00142 if(pUser == NULL)
00143 {
00144 FWARNING(("ProjectionCameraDecorator::getViewing: no user!\n"));
00145
00146 Camera *pCamera = getDecoratee();
00147
00148 if(pCamera == NULL)
00149 {
00150 result.setIdentity();
00151
00152 return;
00153 }
00154
00155 pCamera->getBeacon()->getToWorld(result);
00156
00157 result.invert();
00158 }
00159 else
00160 {
00161 pUser->getToWorld(result);
00162
00163 result.invert();
00164 }
00165 }
00166
00167 void ProjectionCameraDecorator::getProjection(Matrix &result,
00168 UInt32 OSG_CHECK_ARG(width ),
00169 UInt32 OSG_CHECK_ARG(height))
00170 {
00171 Camera *camera = getDecoratee();
00172 Node *pUser = getUser ();
00173
00174 if(camera == NULL)
00175 {
00176 FWARNING(("ProjectionCameraDecorator::getProjection: no "
00177 "decoratee!\n"));
00178
00179 result.setIdentity();
00180
00181 return;
00182 }
00183
00184
00185 Matrix cam,user;
00186
00187 camera->getBeacon()->getToWorld(cam);
00188
00189 if(pUser == NULL)
00190 {
00191 FWARNING(("ProjectionCameraDecorator::getProjection: no user!\n"));
00192
00193 user = cam;
00194 }
00195 else
00196 {
00197 pUser->getToWorld(user);
00198 }
00199
00200 cam.invert();
00201
00202 cam.mult(user);
00203
00204 Pnt3f viewer(cam[3]);
00205
00206 Real32 eyeFac;
00207
00208 if(getLeftEye())
00209 {
00210 eyeFac=-.5;
00211 }
00212 else
00213 {
00214 eyeFac=+.5;
00215 }
00216
00217 viewer += Vec3f(cam[0]) * eyeFac * getEyeSeparation();
00218
00219 Real32 dist = getNormal().distance(viewer),
00220 dl = getLeft ().distance(viewer),
00221 db = getBottom().distance(viewer),
00222 f = camera->getNear() / dist;
00223
00224 MatrixFrustum(result, -dl * f, (getWidth ()-dl) * f,
00225 -db * f, (getHeight()-db) * f,
00226 camera->getNear(), camera->getFar() );
00227 }
00228
00229
00230 void ProjectionCameraDecorator::getProjectionTranslation(
00231 Matrix &result,
00232 UInt32 OSG_CHECK_ARG(width ),
00233 UInt32 OSG_CHECK_ARG(height))
00234 {
00235 Camera *camera = getDecoratee();
00236 Node *pUser = getUser ();
00237
00238 if(camera == NULL)
00239 {
00240 FFATAL(("ProjectionCameraDecorator::getProjectionTranslation: "
00241 "no decoratee!\n"));
00242
00243 result.setIdentity();
00244
00245 return;
00246 }
00247
00248
00249 Matrix cam,user;
00250
00251 camera->getBeacon()->getToWorld(cam);
00252
00253 if(pUser == NULL)
00254 {
00255 FWARNING(("ProjectionCameraDecorator::getProjectionTranslation: "
00256 "no user!\n"));
00257
00258 user = cam;
00259 }
00260 else
00261 {
00262 pUser->getToWorld(user);
00263 }
00264
00265 cam.invert();
00266 cam.mult(user);
00267
00268 Vec3f dir(getNormal().getNormal()),
00269 up (getBottom().getNormal()),
00270 right;
00271 Vec3f pos(cam[3]);
00272
00273 Real32 eyeFac;
00274
00275 if(getLeftEye())
00276 {
00277 eyeFac=-.5;
00278 }
00279 else
00280 {
00281 eyeFac=+.5;
00282 }
00283
00284 pos += Vec3f(cam[0]) * eyeFac * getEyeSeparation();
00285
00286 right = up.cross(dir);
00287 up = dir.cross(right);
00288
00289 result.setIdentity();
00290 result.setValue(right, up, dir, pos);
00291 result.invert();
00292
00293 result.mult(cam);
00294 #if 0
00295 static bool hack = true;
00296 Quaternion q( getNormal().getNormal(), Vec3f(0,0,1));
00297
00298 Vec3f v;
00299 Real32 a;
00300 q.getValueAsAxisDeg(v,a);
00301
00302
00303 if(hack && a > 50)
00304 {
00305 q.getValue(result);
00306
00307 Real32 ang1 = 54.44;
00308 Real32 ang2 = 6.27;
00309
00310 if(v[1] < 0) ang1 = -ang1;
00311
00312 Quaternion q1,q2;
00313 Matrix m1,m2;
00314
00315 q1.setValueAsAxisDeg(0,1,0,ang1);
00316 q2.setValueAsAxisDeg(1,0,0,ang2);
00317
00318 q1.getValue(m1);
00319 q2.getValue(m2);
00320
00321 result = m2;
00322 result.mult(m1);
00323 }
00324 #endif
00325 }
00326