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 <OSGGL.h>
00049
00050 #include "OSGNodePtr.h"
00051 #include "OSGBillboard.h"
00052 #include "OSGDrawAction.h"
00053 #include "OSGIntersectAction.h"
00054 #include "OSGRenderAction.h"
00055 #include "OSGCamera.h"
00056 #include "OSGNode.h"
00057 #include "OSGQuaternion.h"
00058
00059 OSG_USING_NAMESPACE
00060
00065
00066
00068
00069 Billboard::Billboard(void) :
00070 Inherited(),
00071 _camTransform()
00072 {
00073 }
00074
00076
00077 Billboard::Billboard(const Billboard &source) :
00078 Inherited(source),
00079 _camTransform(source._camTransform)
00080 {
00081 }
00082
00084
00085 Billboard::~Billboard(void)
00086 {
00087 }
00088
00089
00090
00092
00093 void Billboard::initMethod (void)
00094 {
00095 DrawAction::registerEnterDefault(
00096 getClassType(),
00097 osgTypedMethodFunctor2BaseCPtrRef<
00098 Action::ResultE,
00099 BillboardPtr ,
00100 CNodePtr ,
00101 Action *>(&Billboard::drawEnter));
00102
00103 DrawAction::registerLeaveDefault(
00104 getClassType(),
00105 osgTypedMethodFunctor2BaseCPtrRef<
00106 Action::ResultE,
00107 BillboardPtr ,
00108 CNodePtr ,
00109 Action *>(&Billboard::drawLeave));
00110
00111
00112 IntersectAction::registerEnterDefault(
00113 getClassType(),
00114 osgTypedMethodFunctor2BaseCPtrRef<
00115 Action::ResultE,
00116 BillboardPtr ,
00117 CNodePtr ,
00118 Action *>(&Billboard::intersectEnter));
00119
00120 IntersectAction::registerLeaveDefault(
00121 getClassType(),
00122 osgTypedMethodFunctor2BaseCPtrRef<
00123 Action::ResultE,
00124 BillboardPtr ,
00125 CNodePtr ,
00126 Action *>(&Billboard::intersectLeave));
00127
00128
00129 RenderAction::registerEnterDefault(
00130 getClassType(),
00131 osgTypedMethodFunctor2BaseCPtrRef<
00132 Action::ResultE,
00133 BillboardPtr ,
00134 CNodePtr ,
00135 Action *>(&Billboard::renderEnter));
00136
00137 RenderAction::registerLeaveDefault(
00138 getClassType(),
00139 osgTypedMethodFunctor2BaseCPtrRef<
00140 Action::ResultE,
00141 BillboardPtr ,
00142 CNodePtr ,
00143 Action *>(&Billboard::renderLeave));
00144 }
00145
00147
00148 void Billboard::changed(BitVector whichField, UInt32 origin)
00149 {
00150 Inherited::changed(whichField, origin);
00151 }
00152
00154
00155 void Billboard::dump( UInt32 uiIndent,
00156 const BitVector bvFlags ) const
00157 {
00158 Inherited::dump(uiIndent, bvFlags);
00159 }
00160
00161
00162
00163
00164 void Billboard::adjustVolume( Volume & volume )
00165 {
00166 Inherited::adjustVolume(volume);
00167
00168
00169
00170
00171
00172 Pnt3f min, max;
00173
00174 volume.getBounds(min, max);
00175
00176 Vec3f dia = max - min;
00177 Pnt3f center = min + dia * .5;
00178 Real32 extend = dia.maxValue();
00179
00180 dia.setValues(extend * Sqrt2, extend * Sqrt2, extend * Sqrt2);
00181
00182 volume.extendBy( center - dia );
00183 volume.extendBy( center + dia );
00184 }
00185
00186 void Billboard::accumulateMatrix(Matrix &result)
00187 {
00188 result.mult(_camTransform);
00189 }
00190
00191 void Billboard::calcMatrix( DrawActionBase *pAction,
00192 const Matrix &mToWorld,
00193 Matrix &mResult)
00194 {
00195 Pnt3f eyepos(0.f, 0.f, 0.f);
00196 Pnt3f objpos(0.f, 0.f, 0.f);
00197
00198 Vec3f vDir;
00199 Vec3f n(0.f, 0.f, 1.f);
00200
00201 Quaternion q1;
00202
00203 Matrix mCamToWorld = pAction->getCameraToWorld();
00204
00205 mResult.invertFrom(mToWorld);
00206
00207 mToWorld.mult(n);
00208
00209 if(getAxisOfRotation() == Vec3f::Null)
00210 {
00211 if(_sfFocusOnCamera.getValue() == true)
00212 {
00213 Vec3f vUp;
00214 Vec3f uW;
00215 Vec3f vX;
00216
00217 mCamToWorld.mult(eyepos);
00218 mToWorld .mult(objpos);
00219
00220 vDir = eyepos - objpos;
00221
00222 vUp.setValue (mCamToWorld[0]);
00223
00224 vUp = vDir.cross(vUp);
00225
00226 vUp.normalize();
00227 vDir.normalize();
00228
00229 Matrix mTr;
00230
00231 vX = vUp.cross(vDir);
00232 vX.normalize();
00233
00234 mTr[0][0] = vX[0];
00235 mTr[0][1] = vX[1];
00236 mTr[0][2] = vX[2];
00237 mTr[1][0] = vUp[0];
00238 mTr[1][1] = vUp[1];
00239 mTr[1][2] = vUp[2];
00240 mTr[2][0] = vDir[0];
00241 mTr[2][1] = vDir[1];
00242 mTr[2][2] = vDir[2];
00243
00244 q1.setValue(mTr);
00245 }
00246 else
00247 {
00248 if(_sfAlignToScreen.getValue() == false)
00249 {
00250 Vec3f u (0.f, 1.f, 0.f);
00251 Vec3f vUp;
00252 Vec3f uW;
00253
00254 mCamToWorld.mult(eyepos);
00255 mToWorld .mult(objpos);
00256
00257 vDir = eyepos - objpos;
00258
00259
00260
00261 vUp.setValue (mCamToWorld[1]);
00262
00263 Quaternion qN(n, vDir);
00264
00265 mToWorld.mult(u);
00266
00267 qN.multVec(u, uW);
00268
00269 q1.setValue(uW, vUp);
00270
00271 q1.mult(qN);
00272 }
00273 else
00274 {
00275 Vec3f u (0.f, 1.f, 0.f);
00276 Vec3f vUp;
00277 Vec3f uW;
00278
00279 vDir.setValue(mCamToWorld[2]);
00280
00281 vUp.setValue (mCamToWorld[1]);
00282
00283 Quaternion qN(n, vDir);
00284
00285 mToWorld.mult(u);
00286
00287 qN.multVec(u, uW);
00288
00289 q1.setValue(uW, vUp);
00290
00291 q1.mult(qN);
00292 }
00293 }
00294 }
00295 else
00296 {
00297 Vec3f wUp;
00298 Vec3f s;
00299 Vec3f tDir;
00300
00301 mCamToWorld.mult(eyepos);
00302
00303 mToWorld.mult(objpos);
00304
00305 mToWorld.mult(getAxisOfRotation(), wUp);
00306
00307 vDir = eyepos - objpos;
00308
00309 s = vDir.cross(wUp);
00310 tDir = wUp .cross(s );
00311
00312 q1.setValue(n, tDir);
00313
00314
00315 Vec3f axis;
00316 Real32 angle;
00317
00318 if ( getMinAngle() <= getMaxAngle() ) {
00319 q1.getValueAsAxisRad(axis, angle);
00320
00321 if (angle < getMinAngle())
00322 angle = getMinAngle();
00323 if (angle > getMaxAngle())
00324 angle = getMaxAngle();
00325
00326 q1.setValueAsAxisRad(axis, angle);
00327 }
00328 }
00329
00330 Matrix mTrans;
00331 Matrix mMat;
00332
00333 mTrans[3][0] = mToWorld[3][0];
00334 mTrans[3][1] = mToWorld[3][1];
00335 mTrans[3][2] = mToWorld[3][2];
00336
00337 mMat.setTransform(q1);
00338
00339 mResult.mult(mTrans);
00340 mResult.mult(mMat );
00341
00342 mTrans[3][0] = -mToWorld[3][0];
00343 mTrans[3][1] = -mToWorld[3][1];
00344 mTrans[3][2] = -mToWorld[3][2];
00345
00346 mResult.mult(mTrans);
00347 mResult.mult(mToWorld);
00348
00349 _camTransform = mResult;
00350 }
00351
00352
00353
00354
00355 Action::ResultE Billboard::drawEnter(Action *action)
00356 {
00357 DrawAction *da = dynamic_cast<DrawAction *>(action);
00358
00359 Matrix mMat;
00360
00361 calcMatrix(da,
00362 da->getActNode()->getToWorld(),
00363 mMat);
00364
00365
00366 glPushMatrix ();
00367 glMultMatrixf(mMat.getValues());
00368
00369
00370
00371
00372 return Action::Continue;
00373 }
00374
00375 Action::ResultE Billboard::drawLeave(Action *)
00376 {
00377 glPopMatrix();
00378
00379 return Action::Continue;
00380 }
00381
00382
00383
00384
00385 Action::ResultE Billboard::intersectEnter(Action *action)
00386 {
00387 IntersectAction *ia = dynamic_cast<IntersectAction *>(action);
00388 Matrix m(_camTransform);
00389
00390 m.invert();
00391
00392 Pnt3f pos;
00393 Vec3f dir;
00394
00395 m.multFullMatrixPnt(ia->getLine().getPosition (), pos);
00396 m.multMatrixVec (ia->getLine().getDirection(), dir);
00397
00398 ia->setLine(Line(pos, dir), ia->getMaxDist());
00399 ia->scale(dir.length());
00400
00401 return Action::Continue;
00402 }
00403
00404 Action::ResultE Billboard::intersectLeave(Action *action)
00405 {
00406 IntersectAction *ia = dynamic_cast<IntersectAction *>(action);
00407 Matrix m(_camTransform);
00408
00409 Pnt3f pos;
00410 Vec3f dir;
00411
00412 m.multFullMatrixPnt(ia->getLine().getPosition (), pos);
00413 m.multMatrixVec (ia->getLine().getDirection(), dir);
00414
00415 ia->setLine(Line(pos, dir), ia->getMaxDist());
00416 ia->scale(dir.length());
00417
00418 return Action::Continue;
00419 }
00420
00421
00422
00423
00424 Action::ResultE Billboard::renderEnter(Action *action)
00425 {
00426 RenderAction *pAction = dynamic_cast<RenderAction *>(action);
00427
00428 Matrix mMat;
00429
00430 calcMatrix(pAction, pAction->top_matrix(), mMat);
00431
00432 pAction->push_matrix(mMat);
00433
00434
00435
00436
00437 return Action::Continue;
00438 }
00439
00440 Action::ResultE Billboard::renderLeave(Action *action)
00441 {
00442 RenderAction *pAction = dynamic_cast<RenderAction *>(action);
00443
00444 pAction->pop_matrix();
00445
00446 return Action::Continue;
00447 }
00448
00449
00450
00451
00452
00453 #ifdef __sgi
00454 #pragma set woff 1174
00455 #endif
00456
00457 #ifdef OSG_LINUX_ICC
00458 #pragma warning( disable : 177 )
00459 #endif
00460
00461 namespace
00462 {
00463 static char cvsid_cpp[] = "@(#)$Id: $";
00464 static char cvsid_hpp[] = OSGBILLBOARD_HEADER_CVSID;
00465 static char cvsid_inl[] = OSGBILLBOARD_INLINE_CVSID;
00466 }