1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2006 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include <OSGConfig.h>
48 #include "OSGScreenTransform.h"
49 #include "OSGVolume.h"
51 #include "OSGIntersectAction.h"
53 #include "OSGRenderAction.h"
57 // Documentation for this class is emitted in the
58 // OSGScreenTransformBase.cpp file.
59 // To modify it, please change the .fcd file (OSGScreenTransform.fcd) and
60 // regenerate the base file.
62 /***************************************************************************\
64 \***************************************************************************/
66 /***************************************************************************\
68 \***************************************************************************/
70 void ScreenTransform::initMethod(InitPhase ePhase
)
72 Inherited::initMethod(ePhase
);
74 if(ePhase
== TypeObject::SystemPost
)
76 IntersectAction::registerEnterDefault(
78 reinterpret_cast<Action::Callback
>(
79 &ScreenTransform::intersectEnter
));
81 IntersectAction::registerLeaveDefault(
83 reinterpret_cast<Action::Callback
>(
84 &ScreenTransform::intersectLeave
));
86 RenderAction::registerEnterDefault(
87 ScreenTransform::getClassType(),
88 reinterpret_cast<Action::Callback
>(&ScreenTransform::renderEnter
));
90 RenderAction::registerLeaveDefault(
91 ScreenTransform::getClassType(),
92 reinterpret_cast<Action::Callback
>(&ScreenTransform::renderLeave
));
98 /***************************************************************************\
100 \***************************************************************************/
102 void ScreenTransform::calcMatrix(const Matrix
&toWorld
,
105 //Get the local to world transformation
106 Matrix mBeaconToWorld
;
108 if(getBeacon() != NULL
)
110 mBeaconToWorld
= getBeacon()->getToWorld();
114 mBeaconToWorld
.setIdentity();
118 //Get the Viewport Camera
119 CameraUnrecPtr ViewportCamera
= theViewport
->getCamera();
121 //Get the World to View transformation
122 ViewportCamera
->getViewing(WorldToView
, theViewport
->getPixelWidth(), theViewport
->getPixelHeight());
125 Matrix mWorldToView
= oEnv
.getVPCameraViewing();
127 //Store the previous value
128 Matrix mPrevValue
= _mTransform
;
130 //Invert the current Model Transformation
131 if(getInvertWorldTransform())
133 _mTransform
.invertFrom(toWorld
);
137 _mTransform
.setIdentity();
140 //Invert the current View Transformation
141 if(getInvertViewTransform())
145 mViewToWorld
.invertFrom(mWorldToView
);
147 _mTransform
.mult(mViewToWorld
);
150 //Setup a new view transformation
151 _mTransform
.mult(getView());
154 //Setup a new Model Transformation, transform such that the screen
155 //position of the origin of the beacon
156 //node and the screen position of the origin of child nodes are the same.
157 if(getApplyBeaconScreenTranslation())
160 //The Screen Pos should now be projected to the near plane
161 Matrix proj
, projtrans
;
163 ViewportCamera
->getProjection(proj
,
164 theViewport
->getPixelWidth(),
165 theViewport
->getPixelHeight());
167 ViewportCamera
->getProjectionTranslation(projtrans
,
168 theViewport
->getPixelWidth(),
169 theViewport
->getPixelHeight());
172 Matrix proj
= oEnv
.getVPCameraProjection ();
173 Matrix projtrans
= oEnv
.getVPCameraProjectionTrans();
175 Matrix wctocc
= proj
;
177 wctocc
.mult(projtrans
);
181 cctowc
.invertFrom(wctocc
);
185 Pnt3f vBeaconScreenPos
= mBeaconToWorld
* Pnt3f(0.0f
,0.0f
,0.0f
);
188 //Get the World to Screen transformation
189 Matrix mWorldToScreen
= oEnv
.getVPWorldToScreen();
190 // ViewportCamera->getWorldToScreen(WorldToScreen, *theViewport);
192 mWorldToScreen
.multFull(vBeaconScreenPos
, vBeaconScreenPos
);
194 cctowc
.multFull(Pnt3f(vBeaconScreenPos
.x(),
195 vBeaconScreenPos
.y(), -1), from
);
197 cctowc
.multFull(Pnt3f(vBeaconScreenPos
.x(),
198 vBeaconScreenPos
.y(), 1), at
);
200 Vec3f dir
= at
- from
;
203 line
.setValue(from
, dir
);
205 Vec3f
vPlaneNormal(0.0f
, 0.0f
, 1.0f
);
206 Pnt3f
vPlanePoint (0.0f
, 0.0f
, 0.0f
);
208 getView().mult(vPlaneNormal
, vPlaneNormal
);
209 getView().mult(vPlanePoint
, vPlanePoint
);
211 Plane
p(vPlaneNormal
, vPlanePoint
);
217 Pnt3f vTransformedPoint
= line
.getPosition() + line
.getDirection() * t
;
219 Matrix mTranslateMat
;
221 mTranslateMat
.setIdentity();
223 mTranslateMat
.setTranslate(Vec3f(vTransformedPoint
.x(),
224 vTransformedPoint
.y(),
227 _mTransform
.mult(mTranslateMat
);
230 //The new model transformation should be rotated by the Beacons rotation
231 if(getApplyBeaconRotation())
233 Matrix mBeaconToView
= mBeaconToWorld
;
235 if(getInvertViewTransform())
237 mBeaconToView
.multLeft(mWorldToView
);
240 Vec3f vTranslation
; // for matrix decomposition
241 Quaternion qBeaconRot
;
243 Quaternion qScaleOrientation
;
245 mBeaconToView
.getTransform(vTranslation
,
252 mRotMat
.setRotate(qBeaconRot
);
254 _mTransform
.mult(mRotMat
);
257 if(_mTransform
!= mPrevValue
)
263 void ScreenTransform::accumulateMatrix(Matrix
&result
)
265 result
.mult(_mTransform
);
268 void ScreenTransform::adjustVolume(Volume
&volume
)
270 volume
.transform(_mTransform
);
273 /*-------------------------------------------------------------------------*/
276 Action::ResultE
ScreenTransform::renderEnter(Action
*action
)
278 RenderAction
*pAction
=
279 dynamic_cast<RenderAction
*>(action
);
281 calcMatrix(pAction
->topMatrix(),
282 pAction
->getActivePartition()->getDrawEnv());
284 pAction
->pushVisibility();
286 pAction
->pushMatrix(_mTransform
);
288 return Action::Continue
;
291 Action::ResultE
ScreenTransform::renderLeave(Action
*action
)
293 RenderAction
*pAction
=
294 dynamic_cast<RenderAction
*>(action
);
296 pAction
->popVisibility();
298 pAction
->popMatrix();
300 return Action::Continue
;
303 /*-------------------------------------------------------------------------*/
306 Action::ResultE
ScreenTransform::intersectEnter(Action
*action
)
308 IntersectAction
*ia
= dynamic_cast<IntersectAction
*>(action
);
309 Matrix m
= _mTransform
;
316 m
.multFull(ia
->getLine().getPosition (), pos
);
317 m
.mult (ia
->getLine().getDirection(), dir
);
319 ia
->setLine(Line(pos
, dir
), ia
->getMaxDist());
320 ia
->scale(dir
.length());
322 return Action::Continue
;
325 Action::ResultE
ScreenTransform::intersectLeave(Action
*action
)
327 IntersectAction
*ia
= dynamic_cast<IntersectAction
*>(action
);
328 Matrix m
= _mTransform
;
333 m
.multFull(ia
->getLine().getPosition (), pos
);
334 m
.mult (ia
->getLine().getDirection(), dir
);
336 ia
->setLine(Line(pos
, dir
), ia
->getMaxDist());
337 ia
->scale(dir
.length());
339 return Action::Continue
;
342 /*-------------------------------------------------------------------------*\
344 \*-------------------------------------------------------------------------*/
346 /*----------------------- constructors & destructors ----------------------*/
348 ScreenTransform::ScreenTransform(void) :
354 ScreenTransform::ScreenTransform(const ScreenTransform
&source
) :
356 _mTransform(source
._mTransform
)
360 ScreenTransform::~ScreenTransform(void)
364 /*----------------------------- class specific ----------------------------*/
366 void ScreenTransform::changed(ConstFieldMaskArg whichField
,
370 Inherited::changed(whichField
, origin
, details
);
372 if(whichField
& BeaconFieldMask
)
378 void ScreenTransform::dump( UInt32
,
379 const BitVector
) const
381 SLOG
<< "Dump ScreenTransform NI" << std::endl
;