1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: b3dtrans.cxx,v $
10 * $Revision: 1.10.42.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
33 #include "b3dtrans.hxx"
34 #include <tools/debug.hxx>
36 /*************************************************************************
38 |* Transformationen fuer alle 3D Ausgaben
40 \************************************************************************/
42 B3dTransformationSet::B3dTransformationSet()
47 B3dTransformationSet::~B3dTransformationSet()
51 void B3dTransformationSet::Orientation(basegfx::B3DHomMatrix
& rTarget
, basegfx::B3DPoint aVRP
, basegfx::B3DVector aVPN
, basegfx::B3DVector aVUP
)
53 rTarget
.translate( -aVRP
.getX(), -aVRP
.getY(), -aVRP
.getZ());
56 basegfx::B3DVector
aRx(aVUP
);
57 basegfx::B3DVector
aRy(aVPN
);
58 aRx
= aRx
.getPerpendicular(aRy
);
60 aRy
= aRy
.getPerpendicular(aRx
);
62 basegfx::B3DHomMatrix aTemp
;
63 aTemp
.set(0, 0, aRx
.getX());
64 aTemp
.set(0, 1, aRx
.getY());
65 aTemp
.set(0, 2, aRx
.getZ());
66 aTemp
.set(1, 0, aRy
.getX());
67 aTemp
.set(1, 1, aRy
.getY());
68 aTemp
.set(1, 2, aRy
.getZ());
69 aTemp
.set(2, 0, aVPN
.getX());
70 aTemp
.set(2, 1, aVPN
.getY());
71 aTemp
.set(2, 2, aVPN
.getZ());
75 void B3dTransformationSet::Frustum(basegfx::B3DHomMatrix
& rTarget
, double fLeft
, double fRight
, double fBottom
, double fTop
, double fNear
, double fFar
)
99 basegfx::B3DHomMatrix aTemp
;
101 aTemp
.set(0, 0, 2.0 * fNear
/ (fRight
- fLeft
));
102 aTemp
.set(1, 1, 2.0 * fNear
/ (fTop
- fBottom
));
103 aTemp
.set(0, 2, (fRight
+ fLeft
) / (fRight
- fLeft
));
104 aTemp
.set(1, 2, (fTop
+ fBottom
) / (fTop
- fBottom
));
105 aTemp
.set(2, 2, -1.0 * ((fFar
+ fNear
) / (fFar
- fNear
)));
106 aTemp
.set(3, 2, -1.0);
107 aTemp
.set(2, 3, -1.0 * ((2.0 * fFar
* fNear
) / (fFar
- fNear
)));
108 aTemp
.set(3, 3, 0.0);
113 void B3dTransformationSet::Ortho(basegfx::B3DHomMatrix
& rTarget
, double fLeft
, double fRight
, double fBottom
, double fTop
, double fNear
, double fFar
)
117 DBG_ERROR("Near and far clipping plane in Ortho definition are identical");
122 DBG_ERROR("Left and right in Ortho definition are identical");
128 DBG_ERROR("Top and bottom in Ortho definition are identical");
132 basegfx::B3DHomMatrix aTemp
;
134 aTemp
.set(0, 0, 2.0 / (fRight
- fLeft
));
135 aTemp
.set(1, 1, 2.0 / (fTop
- fBottom
));
136 aTemp
.set(2, 2, -1.0 * (2.0 / (fFar
- fNear
)));
137 aTemp
.set(0, 3, -1.0 * ((fRight
+ fLeft
) / (fRight
- fLeft
)));
138 aTemp
.set(1, 3, -1.0 * ((fTop
+ fBottom
) / (fTop
- fBottom
)));
139 aTemp
.set(2, 3, -1.0 * ((fFar
+ fNear
) / (fFar
- fNear
)));
144 /*************************************************************************
148 \************************************************************************/
150 void B3dTransformationSet::Reset()
152 // Matritzen auf Einheitsmatritzen
153 maObjectTrans
.identity();
154 PostSetObjectTrans();
156 Orientation(maOrientation
);
157 PostSetOrientation();
159 maTexture
.identity();
161 mfLeftBound
= mfBottomBound
= -1.0;
162 mfRightBound
= mfTopBound
= 1.0;
166 meRatio
= Base3DRatioGrow
;
169 maViewportRectangle
= Rectangle(-1, -1, 2, 2);
170 maVisibleRectangle
= maViewportRectangle
;
172 mbPerspective
= sal_True
;
174 mbProjectionValid
= sal_False
;
175 mbObjectToDeviceValid
= sal_False
;
176 mbWorldToViewValid
= sal_False
;
181 /*************************************************************************
183 |* Objekttransformation
185 \************************************************************************/
187 void B3dTransformationSet::SetObjectTrans(const basegfx::B3DHomMatrix
& rObj
)
189 maObjectTrans
= rObj
;
191 mbObjectToDeviceValid
= sal_False
;
192 mbInvTransObjectToEyeValid
= sal_False
;
194 PostSetObjectTrans();
197 void B3dTransformationSet::PostSetObjectTrans()
199 // Zuweisen und Inverse bestimmen
200 maInvObjectTrans
= maObjectTrans
;
201 maInvObjectTrans
.invert();
204 /*************************************************************************
206 |* Orientierungstransformation
208 \************************************************************************/
210 void B3dTransformationSet::SetOrientation( basegfx::B3DPoint aVRP
, basegfx::B3DVector aVPN
, basegfx::B3DVector aVUP
)
212 maOrientation
.identity();
213 Orientation(maOrientation
, aVRP
, aVPN
, aVUP
);
215 mbInvTransObjectToEyeValid
= sal_False
;
216 mbObjectToDeviceValid
= sal_False
;
217 mbWorldToViewValid
= sal_False
;
219 PostSetOrientation();
222 void B3dTransformationSet::SetOrientation(basegfx::B3DHomMatrix
& mOrient
)
224 maOrientation
= mOrient
;
226 mbInvTransObjectToEyeValid
= sal_False
;
227 mbObjectToDeviceValid
= sal_False
;
228 mbWorldToViewValid
= sal_False
;
230 PostSetOrientation();
233 void B3dTransformationSet::PostSetOrientation()
235 // Zuweisen und Inverse bestimmen
236 maInvOrientation
= maOrientation
;
237 maInvOrientation
.invert();
240 /*************************************************************************
242 |* Projektionstransformation
244 \************************************************************************/
246 void B3dTransformationSet::SetProjection(const basegfx::B3DHomMatrix
& mProject
)
248 maProjection
= mProject
;
252 const basegfx::B3DHomMatrix
& B3dTransformationSet::GetProjection()
254 if(!mbProjectionValid
)
259 const basegfx::B3DHomMatrix
& B3dTransformationSet::GetInvProjection()
261 if(!mbProjectionValid
)
263 return maInvProjection
;
266 void B3dTransformationSet::PostSetProjection()
268 // Zuweisen und Inverse bestimmen
269 maInvProjection
= GetProjection();
270 maInvProjection
.invert();
272 // Abhaengige Matritzen invalidieren
273 mbObjectToDeviceValid
= sal_False
;
274 mbWorldToViewValid
= sal_False
;
277 /*************************************************************************
279 |* Texturtransformation
281 \************************************************************************/
283 void B3dTransformationSet::SetTexture(const basegfx::B2DHomMatrix
& rTxt
)
289 void B3dTransformationSet::PostSetTexture()
293 /*************************************************************************
295 |* Viewport-Transformation
297 \************************************************************************/
299 void B3dTransformationSet::CalcViewport()
301 // Faktoren fuer die Projektion
302 double fLeft(mfLeftBound
);
303 double fRight(mfRightBound
);
304 double fBottom(mfBottomBound
);
305 double fTop(mfTopBound
);
307 // Soll das Seitenverhaeltnis Beachtung finden?
308 // Falls ja, Bereich der Projektion an Seitenverhaeltnis anpassen
309 if(GetRatio() != 0.0)
311 // Berechne aktuelles Seitenverhaeltnis der Bounds
312 double fBoundWidth
= (double)(maViewportRectangle
.GetWidth() + 1);
313 double fBoundHeight
= (double)(maViewportRectangle
.GetHeight() + 1);
314 double fActRatio
= 1;
317 if(fBoundWidth
!= 0.0)
318 fActRatio
= fBoundHeight
/ fBoundWidth
;
319 // FIXME else in this case has a lot of problems, should this return.
323 case Base3DRatioShrink
:
325 // Kleineren Teil vergroessern
326 if(fActRatio
> mfRatio
)
329 fFactor
= 1.0 / fActRatio
;
342 case Base3DRatioGrow
:
344 // GroesserenTeil verkleinern
345 if(fActRatio
> mfRatio
)
355 fFactor
= 1.0 / fActRatio
;
361 case Base3DRatioMiddle
:
364 fFactor
= ((1.0 / fActRatio
) + 1.0) / 2.0;
367 fFactor
= (fActRatio
+ 1.0) / 2.0;
375 // Ueberschneiden sich Darstellungsflaeche und Objektflaeche?
376 maSetBound
= maViewportRectangle
;
378 // Mit den neuen Werten Projektion und ViewPort setzen
379 basegfx::B3DHomMatrix aNewProjection
;
382 // OpenGL needs a little more rough additional size to not let
383 // the front face vanish. Changed from SMALL_DVALUE to 0.000001,
384 // which is 1/10000th, comared with 1/tenth of a million from SMALL_DVALUE.
385 const double fDistPart((mfFarBound
- mfNearBound
) * 0.0001);
387 // Near, Far etwas grosszuegiger setzen, um falsches,
388 // zu kritisches clippen zu verhindern
391 Frustum(aNewProjection
, fLeft
, fRight
, fBottom
, fTop
, mfNearBound
- fDistPart
, mfFarBound
+ fDistPart
);
395 Ortho(aNewProjection
, fLeft
, fRight
, fBottom
, fTop
, mfNearBound
- fDistPart
, mfFarBound
+ fDistPart
);
398 // jetzt schon auf gueltig setzen um Endlosschleife zu vermeiden
399 mbProjectionValid
= sal_True
;
401 // Neue Projektion setzen
402 SetProjection(aNewProjection
);
404 // fill parameters for ViewportTransformation
406 maTranslate
.setX((double)maSetBound
.Left() + ((maSetBound
.GetWidth() - 1L) / 2.0));
407 maTranslate
.setY((double)maSetBound
.Top() + ((maSetBound
.GetHeight() - 1L) / 2.0));
408 maTranslate
.setZ(ZBUFFER_DEPTH_RANGE
/ 2.0);
411 maScale
.setX((maSetBound
.GetWidth() - 1L) / 2.0);
412 maScale
.setY((maSetBound
.GetHeight() - 1L) / -2.0);
413 maScale
.setZ(ZBUFFER_DEPTH_RANGE
/ 2.0);
415 // Auf Veraenderung des ViewPorts reagieren
419 void B3dTransformationSet::SetRatio(double fNew
)
424 mbProjectionValid
= sal_False
;
425 mbObjectToDeviceValid
= sal_False
;
426 mbWorldToViewValid
= sal_False
;
430 void B3dTransformationSet::SetRatioMode(Base3DRatio eNew
)
435 mbProjectionValid
= sal_False
;
436 mbObjectToDeviceValid
= sal_False
;
437 mbWorldToViewValid
= sal_False
;
441 void B3dTransformationSet::SetDeviceRectangle(double fL
, double fR
, double fB
, double fT
,
442 sal_Bool bBroadCastChange
)
444 if(fL
!= mfLeftBound
|| fR
!= mfRightBound
|| fB
!= mfBottomBound
|| fT
!= mfTopBound
)
451 mbProjectionValid
= sal_False
;
452 mbObjectToDeviceValid
= sal_False
;
453 mbWorldToViewValid
= sal_False
;
455 // Aenderung bekanntmachen
457 DeviceRectangleChange();
461 void B3dTransformationSet::SetDeviceVolume(const basegfx::B3DRange
& rVol
, sal_Bool bBroadCastChange
)
463 SetDeviceRectangle(rVol
.getMinX(), rVol
.getMaxX(), rVol
.getMinY(), rVol
.getMaxY(), bBroadCastChange
);
464 SetFrontClippingPlane(rVol
.getMinZ());
465 SetBackClippingPlane(rVol
.getMaxZ());
468 void B3dTransformationSet::DeviceRectangleChange()
472 void B3dTransformationSet::GetDeviceRectangle(double &fL
, double &fR
, double& fB
, double& fT
)
479 mbProjectionValid
= sal_False
;
480 mbObjectToDeviceValid
= sal_False
;
481 mbWorldToViewValid
= sal_False
;
484 basegfx::B3DRange
B3dTransformationSet::GetDeviceVolume()
486 basegfx::B3DRange aRet
;
488 aRet
.expand(basegfx::B3DTuple(mfLeftBound
, mfBottomBound
, mfNearBound
));
489 aRet
.expand(basegfx::B3DTuple(mfRightBound
, mfTopBound
, mfFarBound
));
494 void B3dTransformationSet::SetFrontClippingPlane(double fF
)
496 if(mfNearBound
!= fF
)
499 mbProjectionValid
= sal_False
;
500 mbObjectToDeviceValid
= sal_False
;
501 mbWorldToViewValid
= sal_False
;
505 void B3dTransformationSet::SetBackClippingPlane(double fB
)
510 mbProjectionValid
= sal_False
;
511 mbObjectToDeviceValid
= sal_False
;
512 mbWorldToViewValid
= sal_False
;
516 void B3dTransformationSet::SetPerspective(sal_Bool bNew
)
518 if(mbPerspective
!= bNew
)
520 mbPerspective
= bNew
;
521 mbProjectionValid
= sal_False
;
522 mbObjectToDeviceValid
= sal_False
;
523 mbWorldToViewValid
= sal_False
;
527 void B3dTransformationSet::SetViewportRectangle(Rectangle
& rRect
, Rectangle
& rVisible
)
529 if(rRect
!= maViewportRectangle
|| rVisible
!= maVisibleRectangle
)
531 maViewportRectangle
= rRect
;
532 maVisibleRectangle
= rVisible
;
534 mbProjectionValid
= sal_False
;
535 mbObjectToDeviceValid
= sal_False
;
536 mbWorldToViewValid
= sal_False
;
540 void B3dTransformationSet::PostSetViewport()
544 const Rectangle
& B3dTransformationSet::GetLogicalViewportBounds()
546 if(!mbProjectionValid
)
551 const basegfx::B3DVector
& B3dTransformationSet::GetScale()
553 if(!mbProjectionValid
)
558 const basegfx::B3DVector
& B3dTransformationSet::GetTranslate()
560 if(!mbProjectionValid
)
565 /*************************************************************************
567 |* Hilfsmatrixberechnungsroutinen
569 \************************************************************************/
571 void B3dTransformationSet::CalcMatObjectToDevice()
573 // ObjectToDevice berechnen (Orientation * Projection * Object)
574 maObjectToDevice
= maObjectTrans
;
575 maObjectToDevice
*= maOrientation
;
576 maObjectToDevice
*= GetProjection();
578 // auf gueltig setzen
579 mbObjectToDeviceValid
= sal_True
;
582 const basegfx::B3DHomMatrix
& B3dTransformationSet::GetObjectToDevice()
584 if(!mbObjectToDeviceValid
)
585 CalcMatObjectToDevice();
586 return maObjectToDevice
;
589 void B3dTransformationSet::CalcMatInvTransObjectToEye()
591 maInvTransObjectToEye
= maObjectTrans
;
592 maInvTransObjectToEye
*= maOrientation
;
593 maInvTransObjectToEye
.invert();
594 maInvTransObjectToEye
.transpose();
596 // eventuelle Translationen rausschmeissen, da diese
597 // Matrix nur zur Transformation von Vektoren gedacht ist
598 maInvTransObjectToEye
.set(3, 0, 0.0);
599 maInvTransObjectToEye
.set(3, 1, 0.0);
600 maInvTransObjectToEye
.set(3, 2, 0.0);
601 maInvTransObjectToEye
.set(3, 3, 1.0);
603 // auf gueltig setzen
604 mbInvTransObjectToEyeValid
= sal_True
;
607 const basegfx::B3DHomMatrix
& B3dTransformationSet::GetInvTransObjectToEye()
609 if(!mbInvTransObjectToEyeValid
)
610 CalcMatInvTransObjectToEye();
611 return maInvTransObjectToEye
;
614 basegfx::B3DHomMatrix
B3dTransformationSet::GetMatFromObjectToView()
616 basegfx::B3DHomMatrix aFromObjectToView
= GetObjectToDevice();
618 const basegfx::B3DVector
& rScale(GetScale());
619 aFromObjectToView
.scale(rScale
.getX(), rScale
.getY(), rScale
.getZ());
620 const basegfx::B3DVector
& rTranslate(GetTranslate());
621 aFromObjectToView
.translate(rTranslate
.getX(), rTranslate
.getY(), rTranslate
.getZ());
623 return aFromObjectToView
;
626 void B3dTransformationSet::CalcMatFromWorldToView()
628 maMatFromWorldToView
= maOrientation
;
629 maMatFromWorldToView
*= GetProjection();
630 const basegfx::B3DVector
& rScale(GetScale());
631 maMatFromWorldToView
.scale(rScale
.getX(), rScale
.getY(), rScale
.getZ());
632 const basegfx::B3DVector
& rTranslate(GetTranslate());
633 maMatFromWorldToView
.translate(rTranslate
.getX(), rTranslate
.getY(), rTranslate
.getZ());
634 maInvMatFromWorldToView
= maMatFromWorldToView
;
635 maInvMatFromWorldToView
.invert();
638 mbWorldToViewValid
= sal_True
;
641 const basegfx::B3DHomMatrix
& B3dTransformationSet::GetMatFromWorldToView()
643 if(!mbWorldToViewValid
)
644 CalcMatFromWorldToView();
645 return maMatFromWorldToView
;
648 const basegfx::B3DHomMatrix
& B3dTransformationSet::GetInvMatFromWorldToView()
650 if(!mbWorldToViewValid
)
651 CalcMatFromWorldToView();
652 return maInvMatFromWorldToView
;
655 /*************************************************************************
657 |* Direkter Zugriff auf verschiedene Transformationen
659 \************************************************************************/
661 const basegfx::B3DPoint
B3dTransformationSet::WorldToEyeCoor(const basegfx::B3DPoint
& rVec
)
663 basegfx::B3DPoint
aVec(rVec
);
664 aVec
*= GetOrientation();
668 const basegfx::B3DPoint
B3dTransformationSet::EyeToWorldCoor(const basegfx::B3DPoint
& rVec
)
670 basegfx::B3DPoint
aVec(rVec
);
671 aVec
*= GetInvOrientation();
675 const basegfx::B3DPoint
B3dTransformationSet::EyeToViewCoor(const basegfx::B3DPoint
& rVec
)
677 basegfx::B3DPoint
aVec(rVec
);
678 aVec
*= GetProjection();
680 aVec
+= GetTranslate();
684 const basegfx::B3DPoint
B3dTransformationSet::ViewToEyeCoor(const basegfx::B3DPoint
& rVec
)
686 basegfx::B3DPoint
aVec(rVec
);
687 aVec
-= GetTranslate();
688 aVec
= aVec
/ GetScale();
689 aVec
*= GetInvProjection();
693 const basegfx::B3DPoint
B3dTransformationSet::WorldToViewCoor(const basegfx::B3DPoint
& rVec
)
695 basegfx::B3DPoint
aVec(rVec
);
696 aVec
*= GetMatFromWorldToView();
700 const basegfx::B3DPoint
B3dTransformationSet::ViewToWorldCoor(const basegfx::B3DPoint
& rVec
)
702 basegfx::B3DPoint
aVec(rVec
);
703 aVec
*= GetInvMatFromWorldToView();
707 const basegfx::B3DPoint
B3dTransformationSet::DeviceToViewCoor(const basegfx::B3DPoint
& rVec
)
709 basegfx::B3DPoint
aVec(rVec
);
711 aVec
+= GetTranslate();
715 const basegfx::B3DPoint
B3dTransformationSet::ViewToDeviceCoor(const basegfx::B3DPoint
& rVec
)
717 basegfx::B3DPoint
aVec(rVec
);
718 aVec
-= GetTranslate();
719 aVec
= aVec
/ GetScale();
723 const basegfx::B3DPoint
B3dTransformationSet::ObjectToWorldCoor(const basegfx::B3DPoint
& rVec
)
725 basegfx::B3DPoint
aVec(rVec
);
726 aVec
*= GetObjectTrans();
730 const basegfx::B3DPoint
B3dTransformationSet::WorldToObjectCoor(const basegfx::B3DPoint
& rVec
)
732 basegfx::B3DPoint
aVec(rVec
);
733 aVec
*= GetInvObjectTrans();
737 const basegfx::B3DPoint
B3dTransformationSet::ObjectToViewCoor(const basegfx::B3DPoint
& rVec
)
739 basegfx::B3DPoint
aVec(rVec
);
740 aVec
*= GetObjectTrans();
741 aVec
*= GetMatFromWorldToView();
745 const basegfx::B3DPoint
B3dTransformationSet::ViewToObjectCoor(const basegfx::B3DPoint
& rVec
)
747 basegfx::B3DPoint
aVec(rVec
);
748 aVec
*= GetInvMatFromWorldToView();
749 aVec
*= GetInvObjectTrans();
753 const basegfx::B3DPoint
B3dTransformationSet::ObjectToEyeCoor(const basegfx::B3DPoint
& rVec
)
755 basegfx::B3DPoint
aVec(rVec
);
756 aVec
*= GetObjectTrans();
757 aVec
*= GetOrientation();
761 const basegfx::B3DPoint
B3dTransformationSet::EyeToObjectCoor(const basegfx::B3DPoint
& rVec
)
763 basegfx::B3DPoint
aVec(rVec
);
764 aVec
*= GetInvOrientation();
765 aVec
*= GetInvObjectTrans();
769 const basegfx::B3DPoint
B3dTransformationSet::DeviceToEyeCoor(const basegfx::B3DPoint
& rVec
)
771 basegfx::B3DPoint
aVec(rVec
);
772 aVec
*= GetInvProjection();
776 const basegfx::B3DPoint
B3dTransformationSet::EyeToDeviceCoor(const basegfx::B3DPoint
& rVec
)
778 basegfx::B3DPoint
aVec(rVec
);
779 aVec
*= GetProjection();
783 const basegfx::B3DPoint
B3dTransformationSet::InvTransObjectToEye(const basegfx::B3DPoint
& rVec
)
785 basegfx::B3DPoint
aVec(rVec
);
786 aVec
*= GetInvTransObjectToEye();
790 const basegfx::B2DPoint
B3dTransformationSet::TransTextureCoor(const basegfx::B2DPoint
& rVec
)
792 basegfx::B2DPoint
aVec(rVec
);
793 aVec
*= GetTexture();
797 /*************************************************************************
799 |* Konstruktor B3dViewport
801 \************************************************************************/
803 B3dViewport::B3dViewport()
804 : B3dTransformationSet(),
812 B3dViewport::~B3dViewport()
816 void B3dViewport::SetVRP(const basegfx::B3DPoint
& rNewVRP
)
822 void B3dViewport::SetVPN(const basegfx::B3DVector
& rNewVPN
)
828 void B3dViewport::SetVUV(const basegfx::B3DVector
& rNewVUV
)
834 void B3dViewport::SetViewportValues(
835 const basegfx::B3DPoint
& rNewVRP
,
836 const basegfx::B3DVector
& rNewVPN
,
837 const basegfx::B3DVector
& rNewVUV
)
845 void B3dViewport::CalcOrientation()
847 SetOrientation(aVRP
, aVPN
, aVUV
);
850 /*************************************************************************
852 |* Konstruktor B3dViewport
854 \************************************************************************/
856 B3dCamera::B3dCamera(
857 const basegfx::B3DPoint
& rPos
, const basegfx::B3DVector
& rLkAt
,
858 double fFocLen
, double fBnkAng
, sal_Bool bUseFocLen
)
861 aCorrectedPosition(rPos
),
863 fFocalLength(fFocLen
),
865 bUseFocalLength(bUseFocLen
)
867 CalcNewViewportValues();
870 B3dCamera::~B3dCamera()
874 void B3dCamera::SetPosition(const basegfx::B3DPoint
& rNewPos
)
876 if(rNewPos
!= aPosition
)
879 aCorrectedPosition
= aPosition
= rNewPos
;
882 CalcNewViewportValues();
886 void B3dCamera::SetLookAt(const basegfx::B3DVector
& rNewLookAt
)
888 if(rNewLookAt
!= aLookAt
)
891 aLookAt
= rNewLookAt
;
894 CalcNewViewportValues();
898 void B3dCamera::SetPositionAndLookAt(const basegfx::B3DPoint
& rNewPos
, const basegfx::B3DVector
& rNewLookAt
)
900 if(rNewPos
!= aPosition
|| rNewLookAt
!= aLookAt
)
904 aLookAt
= rNewLookAt
;
907 CalcNewViewportValues();
911 void B3dCamera::SetFocalLength(double fLen
)
913 if(fLen
!= fFocalLength
)
921 CalcNewViewportValues();
925 void B3dCamera::SetBankAngle(double fAngle
)
927 if(fAngle
!= fBankAngle
)
933 CalcNewViewportValues();
937 void B3dCamera::SetUseFocalLength(sal_Bool bNew
)
939 if(bNew
!= (sal_Bool
)bUseFocalLength
)
942 bUseFocalLength
= bNew
;
945 CalcNewViewportValues();
949 void B3dCamera::DeviceRectangleChange()
952 B3dViewport::DeviceRectangleChange();
954 // Auf Aenderung reagieren
955 CalcNewViewportValues();
958 void B3dCamera::CalcNewViewportValues()
960 basegfx::B3DVector
aViewVector(aPosition
- aLookAt
);
961 basegfx::B3DVector
aNewVPN(aViewVector
);
963 basegfx::B3DVector
aNewVUV(0.0, 1.0, 0.0);
964 if(aNewVPN
.getLength() < aNewVPN
.getY())
970 basegfx::B3DVector aNewToTheRight
= aNewVPN
;
971 aNewToTheRight
= aNewToTheRight
.getPerpendicular(aNewVUV
);
972 aNewToTheRight
.normalize();
973 aNewVUV
= aNewToTheRight
.getPerpendicular(aNewVPN
);
976 SetViewportValues(aPosition
, aNewVPN
, aNewVUV
);
977 if(CalcFocalLength())
978 SetViewportValues(aCorrectedPosition
, aNewVPN
, aNewVUV
);
980 if(fBankAngle
!= 0.0)
982 basegfx::B3DHomMatrix aRotMat
;
983 aRotMat
.rotate(0.0, 0.0, fBankAngle
);
984 basegfx::B3DVector
aUp(0.0, 1.0, 0.0);
986 aUp
= EyeToWorldCoor(aUp
);
992 sal_Bool
B3dCamera::CalcFocalLength()
994 double fWidth
= GetDeviceRectangleWidth();
995 sal_Bool bRetval
= sal_False
;
999 // Position aufgrund der FocalLength korrigieren
1000 aCorrectedPosition
= basegfx::B3DPoint(0.0, 0.0, fFocalLength
* fWidth
/ 35.0);
1001 aCorrectedPosition
= EyeToWorldCoor(aCorrectedPosition
);
1006 // FocalLength anhand der Position anpassen
1007 basegfx::B3DPoint aOldPosition
;
1008 aOldPosition
= WorldToEyeCoor(aOldPosition
);
1010 fFocalLength
= aOldPosition
.getZ() / fWidth
* 35.0;
1011 if(fFocalLength
< 5.0)