merge the formfield patch from ooo-build
[ooovba.git] / goodies / source / base3d / b3dtrans.cxx
blob3de2098700fc840f62993b79f5c8dee36e3c21d0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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()
44 Reset();
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());
54 aVUP.normalize();
55 aVPN.normalize();
56 basegfx::B3DVector aRx(aVUP);
57 basegfx::B3DVector aRy(aVPN);
58 aRx = aRx.getPerpendicular(aRy);
59 aRx.normalize();
60 aRy = aRy.getPerpendicular(aRx);
61 aRy.normalize();
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());
72 rTarget *= aTemp;
75 void B3dTransformationSet::Frustum(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
77 if(!(fNear > 0.0))
79 fNear = 0.001;
81 if(!(fFar > 0.0))
83 fFar = 1.0;
85 if(fNear == fFar)
87 fFar = fNear + 1.0;
89 if(fLeft == fRight)
91 fLeft -= 1.0;
92 fRight += 1.0;
94 if(fTop == fBottom)
96 fBottom -= 1.0;
97 fTop += 1.0;
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);
110 rTarget *= aTemp;
113 void B3dTransformationSet::Ortho(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
115 if(fNear == fFar)
117 DBG_ERROR("Near and far clipping plane in Ortho definition are identical");
118 fFar = fNear + 1.0;
120 if(fLeft == fRight)
122 DBG_ERROR("Left and right in Ortho definition are identical");
123 fLeft -= 1.0;
124 fRight += 1.0;
126 if(fTop == fBottom)
128 DBG_ERROR("Top and bottom in Ortho definition are identical");
129 fBottom -= 1.0;
130 fTop += 1.0;
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)));
141 rTarget *= aTemp;
144 /*************************************************************************
146 |* Reset der Werte
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;
163 mfNearBound = 0.001;
164 mfFarBound = 1.001;
166 meRatio = Base3DRatioGrow;
167 mfRatio = 0.0;
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;
178 CalcViewport();
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;
249 PostSetProjection();
252 const basegfx::B3DHomMatrix& B3dTransformationSet::GetProjection()
254 if(!mbProjectionValid)
255 CalcViewport();
256 return maProjection;
259 const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvProjection()
261 if(!mbProjectionValid)
262 CalcViewport();
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)
285 maTexture = rTxt;
286 PostSetTexture();
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;
315 double fFactor;
317 if(fBoundWidth != 0.0)
318 fActRatio = fBoundHeight / fBoundWidth;
319 // FIXME else in this case has a lot of problems, should this return.
321 switch(meRatio)
323 case Base3DRatioShrink :
325 // Kleineren Teil vergroessern
326 if(fActRatio > mfRatio)
328 // X vergroessern
329 fFactor = 1.0 / fActRatio;
330 fRight *= fFactor;
331 fLeft *= fFactor;
333 else
335 // Y vergroessern
336 fFactor = fActRatio;
337 fTop *= fFactor;
338 fBottom *= fFactor;
340 break;
342 case Base3DRatioGrow :
344 // GroesserenTeil verkleinern
345 if(fActRatio > mfRatio)
347 // Y verkleinern
348 fFactor = fActRatio;
349 fTop *= fFactor;
350 fBottom *= fFactor;
352 else
354 // X verkleinern
355 fFactor = 1.0 / fActRatio;
356 fRight *= fFactor;
357 fLeft *= fFactor;
359 break;
361 case Base3DRatioMiddle :
363 // Mitteln
364 fFactor = ((1.0 / fActRatio) + 1.0) / 2.0;
365 fRight *= fFactor;
366 fLeft *= fFactor;
367 fFactor = (fActRatio + 1.0) / 2.0;
368 fTop *= fFactor;
369 fBottom *= fFactor;
370 break;
375 // Ueberschneiden sich Darstellungsflaeche und Objektflaeche?
376 maSetBound = maViewportRectangle;
378 // Mit den neuen Werten Projektion und ViewPort setzen
379 basegfx::B3DHomMatrix aNewProjection;
381 // #i36281#
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
389 if(mbPerspective)
391 Frustum(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart);
393 else
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
405 // Translation
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);
410 // Skalierung
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
416 PostSetViewport();
419 void B3dTransformationSet::SetRatio(double fNew)
421 if(mfRatio != fNew)
423 mfRatio = fNew;
424 mbProjectionValid = sal_False;
425 mbObjectToDeviceValid = sal_False;
426 mbWorldToViewValid = sal_False;
430 void B3dTransformationSet::SetRatioMode(Base3DRatio eNew)
432 if(meRatio != eNew)
434 meRatio = 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)
446 mfLeftBound = fL;
447 mfRightBound = fR;
448 mfBottomBound = fB;
449 mfTopBound = fT;
451 mbProjectionValid = sal_False;
452 mbObjectToDeviceValid = sal_False;
453 mbWorldToViewValid = sal_False;
455 // Aenderung bekanntmachen
456 if(bBroadCastChange)
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)
474 fL = mfLeftBound;
475 fR = mfRightBound;
476 fB = mfBottomBound;
477 fT = mfTopBound;
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));
491 return aRet;
494 void B3dTransformationSet::SetFrontClippingPlane(double fF)
496 if(mfNearBound != fF)
498 mfNearBound = fF;
499 mbProjectionValid = sal_False;
500 mbObjectToDeviceValid = sal_False;
501 mbWorldToViewValid = sal_False;
505 void B3dTransformationSet::SetBackClippingPlane(double fB)
507 if(mfFarBound != fB)
509 mfFarBound = 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)
547 CalcViewport();
548 return maSetBound;
551 const basegfx::B3DVector& B3dTransformationSet::GetScale()
553 if(!mbProjectionValid)
554 CalcViewport();
555 return maScale;
558 const basegfx::B3DVector& B3dTransformationSet::GetTranslate()
560 if(!mbProjectionValid)
561 CalcViewport();
562 return maTranslate;
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();
637 // gueltig setzen
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();
665 return aVec;
668 const basegfx::B3DPoint B3dTransformationSet::EyeToWorldCoor(const basegfx::B3DPoint& rVec)
670 basegfx::B3DPoint aVec(rVec);
671 aVec *= GetInvOrientation();
672 return aVec;
675 const basegfx::B3DPoint B3dTransformationSet::EyeToViewCoor(const basegfx::B3DPoint& rVec)
677 basegfx::B3DPoint aVec(rVec);
678 aVec *= GetProjection();
679 aVec *= GetScale();
680 aVec += GetTranslate();
681 return aVec;
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();
690 return aVec;
693 const basegfx::B3DPoint B3dTransformationSet::WorldToViewCoor(const basegfx::B3DPoint& rVec)
695 basegfx::B3DPoint aVec(rVec);
696 aVec *= GetMatFromWorldToView();
697 return aVec;
700 const basegfx::B3DPoint B3dTransformationSet::ViewToWorldCoor(const basegfx::B3DPoint& rVec)
702 basegfx::B3DPoint aVec(rVec);
703 aVec *= GetInvMatFromWorldToView();
704 return aVec;
707 const basegfx::B3DPoint B3dTransformationSet::DeviceToViewCoor(const basegfx::B3DPoint& rVec)
709 basegfx::B3DPoint aVec(rVec);
710 aVec *= GetScale();
711 aVec += GetTranslate();
712 return aVec;
715 const basegfx::B3DPoint B3dTransformationSet::ViewToDeviceCoor(const basegfx::B3DPoint& rVec)
717 basegfx::B3DPoint aVec(rVec);
718 aVec -= GetTranslate();
719 aVec = aVec / GetScale();
720 return aVec;
723 const basegfx::B3DPoint B3dTransformationSet::ObjectToWorldCoor(const basegfx::B3DPoint& rVec)
725 basegfx::B3DPoint aVec(rVec);
726 aVec *= GetObjectTrans();
727 return aVec;
730 const basegfx::B3DPoint B3dTransformationSet::WorldToObjectCoor(const basegfx::B3DPoint& rVec)
732 basegfx::B3DPoint aVec(rVec);
733 aVec *= GetInvObjectTrans();
734 return aVec;
737 const basegfx::B3DPoint B3dTransformationSet::ObjectToViewCoor(const basegfx::B3DPoint& rVec)
739 basegfx::B3DPoint aVec(rVec);
740 aVec *= GetObjectTrans();
741 aVec *= GetMatFromWorldToView();
742 return aVec;
745 const basegfx::B3DPoint B3dTransformationSet::ViewToObjectCoor(const basegfx::B3DPoint& rVec)
747 basegfx::B3DPoint aVec(rVec);
748 aVec *= GetInvMatFromWorldToView();
749 aVec *= GetInvObjectTrans();
750 return aVec;
753 const basegfx::B3DPoint B3dTransformationSet::ObjectToEyeCoor(const basegfx::B3DPoint& rVec)
755 basegfx::B3DPoint aVec(rVec);
756 aVec *= GetObjectTrans();
757 aVec *= GetOrientation();
758 return aVec;
761 const basegfx::B3DPoint B3dTransformationSet::EyeToObjectCoor(const basegfx::B3DPoint& rVec)
763 basegfx::B3DPoint aVec(rVec);
764 aVec *= GetInvOrientation();
765 aVec *= GetInvObjectTrans();
766 return aVec;
769 const basegfx::B3DPoint B3dTransformationSet::DeviceToEyeCoor(const basegfx::B3DPoint& rVec)
771 basegfx::B3DPoint aVec(rVec);
772 aVec *= GetInvProjection();
773 return aVec;
776 const basegfx::B3DPoint B3dTransformationSet::EyeToDeviceCoor(const basegfx::B3DPoint& rVec)
778 basegfx::B3DPoint aVec(rVec);
779 aVec *= GetProjection();
780 return aVec;
783 const basegfx::B3DPoint B3dTransformationSet::InvTransObjectToEye(const basegfx::B3DPoint& rVec)
785 basegfx::B3DPoint aVec(rVec);
786 aVec *= GetInvTransObjectToEye();
787 return aVec;
790 const basegfx::B2DPoint B3dTransformationSet::TransTextureCoor(const basegfx::B2DPoint& rVec)
792 basegfx::B2DPoint aVec(rVec);
793 aVec *= GetTexture();
794 return aVec;
797 /*************************************************************************
799 |* Konstruktor B3dViewport
801 \************************************************************************/
803 B3dViewport::B3dViewport()
804 : B3dTransformationSet(),
805 aVRP(0, 0, 0),
806 aVPN(0, 0, 1),
807 aVUV(0, 1, 0)
809 CalcOrientation();
812 B3dViewport::~B3dViewport()
816 void B3dViewport::SetVRP(const basegfx::B3DPoint& rNewVRP)
818 aVRP = rNewVRP;
819 CalcOrientation();
822 void B3dViewport::SetVPN(const basegfx::B3DVector& rNewVPN)
824 aVPN = rNewVPN;
825 CalcOrientation();
828 void B3dViewport::SetVUV(const basegfx::B3DVector& rNewVUV)
830 aVUV = rNewVUV;
831 CalcOrientation();
834 void B3dViewport::SetViewportValues(
835 const basegfx::B3DPoint& rNewVRP,
836 const basegfx::B3DVector& rNewVPN,
837 const basegfx::B3DVector& rNewVUV)
839 aVRP = rNewVRP;
840 aVPN = rNewVPN;
841 aVUV = rNewVUV;
842 CalcOrientation();
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)
859 : B3dViewport(),
860 aPosition(rPos),
861 aCorrectedPosition(rPos),
862 aLookAt(rLkAt),
863 fFocalLength(fFocLen),
864 fBankAngle(fBnkAng),
865 bUseFocalLength(bUseFocLen)
867 CalcNewViewportValues();
870 B3dCamera::~B3dCamera()
874 void B3dCamera::SetPosition(const basegfx::B3DPoint& rNewPos)
876 if(rNewPos != aPosition)
878 // Zuweisen
879 aCorrectedPosition = aPosition = rNewPos;
881 // Neuberechnung
882 CalcNewViewportValues();
886 void B3dCamera::SetLookAt(const basegfx::B3DVector& rNewLookAt)
888 if(rNewLookAt != aLookAt)
890 // Zuweisen
891 aLookAt = rNewLookAt;
893 // Neuberechnung
894 CalcNewViewportValues();
898 void B3dCamera::SetPositionAndLookAt(const basegfx::B3DPoint& rNewPos, const basegfx::B3DVector& rNewLookAt)
900 if(rNewPos != aPosition || rNewLookAt != aLookAt)
902 // Zuweisen
903 aPosition = rNewPos;
904 aLookAt = rNewLookAt;
906 // Neuberechnung
907 CalcNewViewportValues();
911 void B3dCamera::SetFocalLength(double fLen)
913 if(fLen != fFocalLength)
915 // Zuweisen
916 if(fLen < 5.0)
917 fLen = 5.0;
918 fFocalLength = fLen;
920 // Neuberechnung
921 CalcNewViewportValues();
925 void B3dCamera::SetBankAngle(double fAngle)
927 if(fAngle != fBankAngle)
929 // Zuweisen
930 fBankAngle = fAngle;
932 // Neuberechnung
933 CalcNewViewportValues();
937 void B3dCamera::SetUseFocalLength(sal_Bool bNew)
939 if(bNew != (sal_Bool)bUseFocalLength)
941 // Zuweisen
942 bUseFocalLength = bNew;
944 // Neuberechnung
945 CalcNewViewportValues();
949 void B3dCamera::DeviceRectangleChange()
951 // call parent
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())
965 aNewVUV.setX(0.5);
967 aNewVUV.normalize();
968 aNewVPN.normalize();
970 basegfx::B3DVector aNewToTheRight = aNewVPN;
971 aNewToTheRight = aNewToTheRight.getPerpendicular(aNewVUV);
972 aNewToTheRight.normalize();
973 aNewVUV = aNewToTheRight.getPerpendicular(aNewVPN);
974 aNewVUV.normalize();
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);
985 aUp *= aRotMat;
986 aUp = EyeToWorldCoor(aUp);
987 aUp.normalize();
988 SetVUV(aUp);
992 sal_Bool B3dCamera::CalcFocalLength()
994 double fWidth = GetDeviceRectangleWidth();
995 sal_Bool bRetval = sal_False;
997 if(bUseFocalLength)
999 // Position aufgrund der FocalLength korrigieren
1000 aCorrectedPosition = basegfx::B3DPoint(0.0, 0.0, fFocalLength * fWidth / 35.0);
1001 aCorrectedPosition = EyeToWorldCoor(aCorrectedPosition);
1002 bRetval = sal_True;
1004 else
1006 // FocalLength anhand der Position anpassen
1007 basegfx::B3DPoint aOldPosition;
1008 aOldPosition = WorldToEyeCoor(aOldPosition);
1009 if(fWidth != 0.0)
1010 fFocalLength = aOldPosition.getZ() / fWidth * 35.0;
1011 if(fFocalLength < 5.0)
1012 fFocalLength = 5.0;
1014 return bRetval;
1017 // eof