fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / NodeCores / Groups / Misc / OSGBillboard.cpp
blob4ff8c41bc37c17cc6bc2dc0e65ff2413537d19ad
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
46 #include "OSGConfig.h"
48 #include "OSGGL.h"
50 #include "OSGBillboard.h"
51 #include "OSGIntersectAction.h"
52 #include "OSGRenderAction.h"
53 #include "OSGCamera.h"
54 #include "OSGNode.h"
55 #include "OSGQuaternion.h"
56 #include "OSGMatrix.h"
58 OSG_USING_NAMESPACE
60 // Documentation for this class is emited in the
61 // OSGBillboardBase.cpp file.
62 // To modify it, please change the .fcd file (OSGBillboard.fcd) and
63 // regenerate the base file.
65 /*----------------------- constructors & destructors ----------------------*/
67 //! Constructor
69 Billboard::Billboard(void) :
70 Inherited (),
71 _camTransform()
75 //! Copy Constructor
77 Billboard::Billboard(const Billboard &source) :
78 Inherited (source ),
79 _camTransform(source._camTransform)
83 //! Destructor
85 Billboard::~Billboard(void)
89 /*----------------------------- class specific ----------------------------*/
91 //! initialize the static features of the class, e.g. action callbacks
93 void Billboard::initMethod(InitPhase ePhase)
95 Inherited::initMethod(ePhase);
97 if(ePhase == TypeObject::SystemPost)
99 IntersectAction::registerEnterDefault(
100 getClassType(),
101 reinterpret_cast<Action::Callback>(&Billboard::intersectEnter));
103 IntersectAction::registerLeaveDefault(
104 getClassType(),
105 reinterpret_cast<Action::Callback>(&Billboard::intersectLeave));
108 RenderAction::registerEnterDefault(
109 Billboard::getClassType(),
110 reinterpret_cast<Action::Callback>(&Billboard::renderEnter));
112 RenderAction::registerLeaveDefault(
113 Billboard::getClassType(),
114 reinterpret_cast<Action::Callback>(&Billboard::renderLeave));
118 //! react to field changes
120 void Billboard::changed(ConstFieldMaskArg whichField,
121 UInt32 origin,
122 BitVector details)
124 Inherited::changed(whichField, origin, details);
127 //! output the instance for debug purposes
129 void Billboard::dump( UInt32 uiIndent,
130 const BitVector bvFlags ) const
132 Inherited::dump(uiIndent, bvFlags);
136 /*------------------------- volume update -------------------------------*/
138 void Billboard::adjustVolume( Volume & volume )
140 Inherited::adjustVolume(volume);
142 // enlarge the volume to adjust for rotations
143 // keep the center, but make it a cube big enough to contain the
144 // billboard in all orientations
146 Pnt3f min, max;
148 volume.getBounds(min, max);
150 Vec3f dia = max - min;
151 Pnt3f center = min + dia * .5;
152 Real32 extend = dia.maxValue();
154 dia.setValues(extend * Sqrt2, extend * Sqrt2, extend * Sqrt2);
156 volume.extendBy( center - dia );
157 volume.extendBy( center + dia );
160 void Billboard::accumulateMatrix(Matrix &result)
162 result.mult(_camTransform);
165 void Billboard::calcMatrix(const Matrix &camToWorld,
166 const Matrix &mToWorld,
167 Matrix &mResult)
169 Pnt3f eyepos(0.f, 0.f, 0.f);
170 Pnt3f objpos(0.f, 0.f, 0.f);
172 Vec3f vDir;
173 Vec3f n(0.f, 0.f, 1.f);
175 Quaternion q1;
177 mResult.invertFrom(mToWorld);
179 mToWorld.mult(n, n);
181 if(getAxisOfRotation() == Vec3f::Null)
183 if(_sfFocusOnCamera.getValue() == true)
185 Vec3f vUp;
186 Vec3f uW;
187 Vec3f vX;
189 camToWorld.mult(eyepos, eyepos);
190 mToWorld .mult(objpos, objpos);
192 vDir = eyepos - objpos;
194 vUp.setValue (camToWorld[0]);
196 vUp = vDir.cross(vUp);
198 vUp.normalize();
199 vDir.normalize();
201 Matrix mTr;
203 vX = vUp.cross(vDir);
204 vX.normalize();
206 mTr[0][0] = vX[0];
207 mTr[0][1] = vX[1];
208 mTr[0][2] = vX[2];
209 mTr[1][0] = vUp[0];
210 mTr[1][1] = vUp[1];
211 mTr[1][2] = vUp[2];
212 mTr[2][0] = vDir[0];
213 mTr[2][1] = vDir[1];
214 mTr[2][2] = vDir[2];
216 q1.setValue(mTr);
218 else
220 if(_sfAlignToScreen.getValue() == false)
222 Vec3f u (0.f, 1.f, 0.f);
223 Vec3f vUp;
224 Vec3f uW;
226 camToWorld.mult(eyepos, eyepos);
227 mToWorld .mult(objpos, objpos);
229 vDir = eyepos - objpos;
231 // vDir.setValue(camToWorld[2]);
233 vUp.setValue (camToWorld[1]);
235 Quaternion qN(n, vDir);
237 mToWorld.mult(u, u);
239 qN.multVec(u, uW);
241 q1.setValue(uW, vUp);
243 q1.mult(qN);
245 else
247 Vec3f u (0.f, 1.f, 0.f);
248 Vec3f vUp;
249 Vec3f uW;
251 vDir.setValue(camToWorld[2]);
253 vUp.setValue (camToWorld[1]);
255 Quaternion qN(n, vDir);
257 mToWorld.mult(u, u);
259 qN.multVec(u, uW);
261 q1.setValue(uW, vUp);
263 q1.mult(qN);
267 else
269 Vec3f wUp;
270 Vec3f s;
271 Vec3f tDir;
273 camToWorld.mult(eyepos, eyepos);
274 mToWorld .mult(objpos, objpos);
276 mToWorld .mult(getAxisOfRotation(), wUp);
278 vDir = eyepos - objpos;
280 s = vDir.cross(wUp);
281 tDir = wUp .cross(s );
283 n = getAxisOfRotation();
284 n[0] += n[1];
285 n[1] += n[2];
286 n[2] += n[0];
287 n -= n.dot(getAxisOfRotation())*getAxisOfRotation();
289 q1.setValue(n, tDir);
291 // clamp angle to [min; max]
292 Vec3f axis;
293 Real32 angle;
295 if(getMinAngle() <= getMaxAngle())
297 q1.getValueAsAxisRad(axis, angle);
299 if(angle < getMinAngle())
300 angle = getMinAngle();
302 if(angle > getMaxAngle())
303 angle = getMaxAngle();
305 q1.setValueAsAxisRad(axis, angle);
309 Matrix mTrans;
310 Matrix mMat;
312 mTrans[3][0] = mToWorld[3][0];
313 mTrans[3][1] = mToWorld[3][1];
314 mTrans[3][2] = mToWorld[3][2];
316 mMat.setTransform(q1);
318 mResult.mult(mTrans);
319 mResult.mult(mMat );
321 mTrans[3][0] = -mToWorld[3][0];
322 mTrans[3][1] = -mToWorld[3][1];
323 mTrans[3][2] = -mToWorld[3][2];
325 mResult.mult(mTrans);
326 mResult.mult(mToWorld);
328 _camTransform = mResult;
332 /*-------------------------------------------------------------------------*/
333 /* Intersect */
335 Action::ResultE Billboard::intersectEnter(Action *action)
337 IntersectAction *ia = dynamic_cast<IntersectAction *>(action);
338 Matrix m(_camTransform);
340 m.invert();
342 Pnt3f pos;
343 Vec3f dir;
345 m.multFull(ia->getLine().getPosition (), pos);
346 m.mult (ia->getLine().getDirection(), dir);
348 ia->setLine(Line(pos, dir), ia->getMaxDist());
349 ia->scale(dir.length());
351 return Action::Continue;
354 Action::ResultE Billboard::intersectLeave(Action *action)
356 IntersectAction *ia = dynamic_cast<IntersectAction *>(action);
357 Matrix m(_camTransform);
359 Pnt3f pos;
360 Vec3f dir;
362 m.multFull(ia->getLine().getPosition (), pos);
363 m.mult (ia->getLine().getDirection(), dir);
365 ia->setLine(Line(pos, dir), ia->getMaxDist());
366 ia->scale(dir.length());
368 return Action::Continue;
371 /*-------------------------------------------------------------------------*/
372 /* Render */
374 Action::ResultE Billboard::renderEnter(Action *action)
376 RenderAction *pAction =
377 dynamic_cast<RenderAction *>(action);
379 Matrix mMat;
380 Matrix cam_to_world =
381 pAction->getActivePartition()->getVPCameraToWorld();
383 this->calcMatrix(cam_to_world, pAction->topMatrix(), mMat);
385 pAction->pushMatrix(mMat);
387 // !!! can't use visibles, as ToWorld gives garbage leading to wrong culling
388 // pAction->selectVisibles();
390 return Action::Continue;
393 Action::ResultE Billboard::renderLeave(Action *action)
395 RenderAction *pAction =
396 dynamic_cast<RenderAction *>(action);
398 pAction->popMatrix();
400 return Action::Continue;