xref: /AOO41X/main/tools/source/generic/b3dtrans.cxx (revision 89b56da77b74925c286b3e777681ba8dda16bf41)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_tools.hxx"
26 #include <tools/b3dtrans.hxx>
27 #include <tools/debug.hxx>
28 
29 /*************************************************************************
30 |*
31 |* Transformationen fuer alle 3D Ausgaben
32 |*
33 \************************************************************************/
34 
B3dTransformationSet()35 B3dTransformationSet::B3dTransformationSet()
36 {
37     Reset();
38 }
39 
~B3dTransformationSet()40 B3dTransformationSet::~B3dTransformationSet()
41 {
42 }
43 
Orientation(basegfx::B3DHomMatrix & rTarget,basegfx::B3DPoint aVRP,basegfx::B3DVector aVPN,basegfx::B3DVector aVUP)44 void B3dTransformationSet::Orientation(basegfx::B3DHomMatrix& rTarget, basegfx::B3DPoint aVRP, basegfx::B3DVector aVPN, basegfx::B3DVector aVUP)
45 {
46     rTarget.translate( -aVRP.getX(), -aVRP.getY(), -aVRP.getZ());
47     aVUP.normalize();
48     aVPN.normalize();
49     basegfx::B3DVector aRx(aVUP);
50     basegfx::B3DVector aRy(aVPN);
51     aRx = aRx.getPerpendicular(aRy);
52     aRx.normalize();
53     aRy = aRy.getPerpendicular(aRx);
54     aRy.normalize();
55     basegfx::B3DHomMatrix aTemp;
56     aTemp.set(0, 0, aRx.getX());
57     aTemp.set(0, 1, aRx.getY());
58     aTemp.set(0, 2, aRx.getZ());
59     aTemp.set(1, 0, aRy.getX());
60     aTemp.set(1, 1, aRy.getY());
61     aTemp.set(1, 2, aRy.getZ());
62     aTemp.set(2, 0, aVPN.getX());
63     aTemp.set(2, 1, aVPN.getY());
64     aTemp.set(2, 2, aVPN.getZ());
65     rTarget *= aTemp;
66 }
67 
Frustum(basegfx::B3DHomMatrix & rTarget,double fLeft,double fRight,double fBottom,double fTop,double fNear,double fFar)68 void B3dTransformationSet::Frustum(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
69 {
70     if(!(fNear > 0.0))
71     {
72         fNear = 0.001;
73     }
74     if(!(fFar > 0.0))
75     {
76         fFar = 1.0;
77     }
78     if(fNear == fFar)
79     {
80         fFar = fNear + 1.0;
81     }
82     if(fLeft == fRight)
83     {
84         fLeft -= 1.0;
85         fRight += 1.0;
86     }
87     if(fTop == fBottom)
88     {
89         fBottom -= 1.0;
90         fTop += 1.0;
91     }
92     basegfx::B3DHomMatrix aTemp;
93 
94     aTemp.set(0, 0, 2.0 * fNear / (fRight - fLeft));
95     aTemp.set(1, 1, 2.0 * fNear / (fTop - fBottom));
96     aTemp.set(0, 2, (fRight + fLeft) / (fRight - fLeft));
97     aTemp.set(1, 2, (fTop + fBottom) / (fTop - fBottom));
98     aTemp.set(2, 2, -1.0 * ((fFar + fNear) / (fFar - fNear)));
99     aTemp.set(3, 2, -1.0);
100     aTemp.set(2, 3, -1.0 * ((2.0 * fFar * fNear) / (fFar - fNear)));
101     aTemp.set(3, 3, 0.0);
102 
103     rTarget *= aTemp;
104 }
105 
Ortho(basegfx::B3DHomMatrix & rTarget,double fLeft,double fRight,double fBottom,double fTop,double fNear,double fFar)106 void B3dTransformationSet::Ortho(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
107 {
108     if(fNear == fFar)
109     {
110         DBG_ERROR("Near and far clipping plane in Ortho definition are identical");
111         fFar = fNear + 1.0;
112     }
113     if(fLeft == fRight)
114     {
115         DBG_ERROR("Left and right in Ortho definition are identical");
116         fLeft -= 1.0;
117         fRight += 1.0;
118     }
119     if(fTop == fBottom)
120     {
121         DBG_ERROR("Top and bottom in Ortho definition are identical");
122         fBottom -= 1.0;
123         fTop += 1.0;
124     }
125     basegfx::B3DHomMatrix aTemp;
126 
127     aTemp.set(0, 0, 2.0 / (fRight - fLeft));
128     aTemp.set(1, 1, 2.0 / (fTop - fBottom));
129     aTemp.set(2, 2, -1.0 * (2.0 / (fFar - fNear)));
130     aTemp.set(0, 3, -1.0 * ((fRight + fLeft) / (fRight - fLeft)));
131     aTemp.set(1, 3, -1.0 * ((fTop + fBottom) / (fTop - fBottom)));
132     aTemp.set(2, 3, -1.0 * ((fFar + fNear) / (fFar - fNear)));
133 
134     rTarget *= aTemp;
135 }
136 
137 /*************************************************************************
138 |*
139 |* Reset der Werte
140 |*
141 \************************************************************************/
142 
Reset()143 void B3dTransformationSet::Reset()
144 {
145     // Matritzen auf Einheitsmatritzen
146     maObjectTrans.identity();
147     PostSetObjectTrans();
148 
149     Orientation(maOrientation);
150     PostSetOrientation();
151 
152     maTexture.identity();
153 
154     mfLeftBound = mfBottomBound = -1.0;
155     mfRightBound = mfTopBound = 1.0;
156     mfNearBound = 0.001;
157     mfFarBound = 1.001;
158 
159     meRatio = Base3DRatioGrow;
160     mfRatio = 0.0;
161 
162     maViewportRectangle = Rectangle(-1, -1, 2, 2);
163     maVisibleRectangle = maViewportRectangle;
164 
165     mbPerspective = sal_True;
166 
167     mbProjectionValid = sal_False;
168     mbObjectToDeviceValid = sal_False;
169     mbWorldToViewValid = sal_False;
170 
171     CalcViewport();
172 }
173 
174 /*************************************************************************
175 |*
176 |* Objekttransformation
177 |*
178 \************************************************************************/
179 
SetObjectTrans(const basegfx::B3DHomMatrix & rObj)180 void B3dTransformationSet::SetObjectTrans(const basegfx::B3DHomMatrix& rObj)
181 {
182     maObjectTrans = rObj;
183 
184     mbObjectToDeviceValid = sal_False;
185     mbInvTransObjectToEyeValid = sal_False;
186 
187     PostSetObjectTrans();
188 }
189 
PostSetObjectTrans()190 void B3dTransformationSet::PostSetObjectTrans()
191 {
192     // Zuweisen und Inverse bestimmen
193     maInvObjectTrans = maObjectTrans;
194     maInvObjectTrans.invert();
195 }
196 
197 /*************************************************************************
198 |*
199 |* Orientierungstransformation
200 |*
201 \************************************************************************/
202 
SetOrientation(basegfx::B3DPoint aVRP,basegfx::B3DVector aVPN,basegfx::B3DVector aVUP)203 void B3dTransformationSet::SetOrientation( basegfx::B3DPoint aVRP, basegfx::B3DVector aVPN, basegfx::B3DVector aVUP)
204 {
205     maOrientation.identity();
206     Orientation(maOrientation, aVRP, aVPN, aVUP);
207 
208     mbInvTransObjectToEyeValid = sal_False;
209     mbObjectToDeviceValid = sal_False;
210     mbWorldToViewValid = sal_False;
211 
212     PostSetOrientation();
213 }
214 
SetOrientation(basegfx::B3DHomMatrix & mOrient)215 void B3dTransformationSet::SetOrientation(basegfx::B3DHomMatrix& mOrient)
216 {
217     maOrientation = mOrient;
218 
219     mbInvTransObjectToEyeValid = sal_False;
220     mbObjectToDeviceValid = sal_False;
221     mbWorldToViewValid = sal_False;
222 
223     PostSetOrientation();
224 }
225 
PostSetOrientation()226 void B3dTransformationSet::PostSetOrientation()
227 {
228     // Zuweisen und Inverse bestimmen
229     maInvOrientation = maOrientation;
230     maInvOrientation.invert();
231 }
232 
233 /*************************************************************************
234 |*
235 |* Projektionstransformation
236 |*
237 \************************************************************************/
238 
SetProjection(const basegfx::B3DHomMatrix & mProject)239 void B3dTransformationSet::SetProjection(const basegfx::B3DHomMatrix& mProject)
240 {
241     maProjection = mProject;
242     PostSetProjection();
243 }
244 
GetProjection()245 const basegfx::B3DHomMatrix& B3dTransformationSet::GetProjection()
246 {
247     if(!mbProjectionValid)
248         CalcViewport();
249     return maProjection;
250 }
251 
GetInvProjection()252 const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvProjection()
253 {
254     if(!mbProjectionValid)
255         CalcViewport();
256     return maInvProjection;
257 }
258 
PostSetProjection()259 void B3dTransformationSet::PostSetProjection()
260 {
261     // Zuweisen und Inverse bestimmen
262     maInvProjection = GetProjection();
263     maInvProjection.invert();
264 
265     // Abhaengige Matritzen invalidieren
266     mbObjectToDeviceValid = sal_False;
267     mbWorldToViewValid = sal_False;
268 }
269 
270 /*************************************************************************
271 |*
272 |* Texturtransformation
273 |*
274 \************************************************************************/
275 
SetTexture(const basegfx::B2DHomMatrix & rTxt)276 void B3dTransformationSet::SetTexture(const basegfx::B2DHomMatrix& rTxt)
277 {
278     maTexture = rTxt;
279     PostSetTexture();
280 }
281 
PostSetTexture()282 void B3dTransformationSet::PostSetTexture()
283 {
284 }
285 
286 /*************************************************************************
287 |*
288 |* Viewport-Transformation
289 |*
290 \************************************************************************/
291 
CalcViewport()292 void B3dTransformationSet::CalcViewport()
293 {
294     // Faktoren fuer die Projektion
295     double fLeft(mfLeftBound);
296     double fRight(mfRightBound);
297     double fBottom(mfBottomBound);
298     double fTop(mfTopBound);
299 
300     // Soll das Seitenverhaeltnis Beachtung finden?
301     // Falls ja, Bereich der Projektion an Seitenverhaeltnis anpassen
302     if(GetRatio() != 0.0)
303     {
304         // Berechne aktuelles Seitenverhaeltnis der Bounds
305         double fBoundWidth = (double)(maViewportRectangle.GetWidth() + 1);
306         double fBoundHeight = (double)(maViewportRectangle.GetHeight() + 1);
307         double fActRatio = 1;
308         double fFactor;
309 
310         if(fBoundWidth != 0.0)
311             fActRatio = fBoundHeight / fBoundWidth;
312         // FIXME   else in this case has a lot of problems,  should this return.
313 
314         switch(meRatio)
315         {
316             case Base3DRatioShrink :
317             {
318                 // Kleineren Teil vergroessern
319                 if(fActRatio > mfRatio)
320                 {
321                     // X vergroessern
322                     fFactor = 1.0 / fActRatio;
323                     fRight  *= fFactor;
324                     fLeft *= fFactor;
325                 }
326                 else
327                 {
328                     // Y vergroessern
329                     fFactor = fActRatio;
330                     fTop *= fFactor;
331                     fBottom *= fFactor;
332                 }
333                 break;
334             }
335             case Base3DRatioGrow :
336             {
337                 // GroesserenTeil verkleinern
338                 if(fActRatio > mfRatio)
339                 {
340                     // Y verkleinern
341                     fFactor = fActRatio;
342                     fTop *= fFactor;
343                     fBottom *= fFactor;
344                 }
345                 else
346                 {
347                     // X verkleinern
348                     fFactor = 1.0 / fActRatio;
349                     fRight  *= fFactor;
350                     fLeft *= fFactor;
351                 }
352                 break;
353             }
354             case Base3DRatioMiddle :
355             {
356                 // Mitteln
357                 fFactor = ((1.0 / fActRatio) + 1.0) / 2.0;
358                 fRight *= fFactor;
359                 fLeft *= fFactor;
360                 fFactor = (fActRatio + 1.0) / 2.0;
361                 fTop *= fFactor;
362                 fBottom *= fFactor;
363                 break;
364             }
365         }
366     }
367 
368     // Ueberschneiden sich Darstellungsflaeche und Objektflaeche?
369     maSetBound = maViewportRectangle;
370 
371     // Mit den neuen Werten Projektion und ViewPort setzen
372     basegfx::B3DHomMatrix aNewProjection;
373 
374     // #i36281#
375     // OpenGL needs a little more rough additional size to not let
376     // the front face vanish. Changed from SMALL_DVALUE to 0.000001,
377     // which is 1/10000th, comared with 1/tenth of a million from SMALL_DVALUE.
378     const double fDistPart((mfFarBound - mfNearBound) * 0.0001);
379 
380     // Near, Far etwas grosszuegiger setzen, um falsches,
381     // zu kritisches clippen zu verhindern
382     if(mbPerspective)
383     {
384         Frustum(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart);
385     }
386     else
387     {
388         Ortho(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart);
389     }
390 
391     // jetzt schon auf gueltig setzen um Endlosschleife zu vermeiden
392     mbProjectionValid = sal_True;
393 
394     // Neue Projektion setzen
395     SetProjection(aNewProjection);
396 
397     // fill parameters for ViewportTransformation
398     // Translation
399     maTranslate.setX((double)maSetBound.Left() + ((maSetBound.GetWidth() - 1L) / 2.0));
400     maTranslate.setY((double)maSetBound.Top() + ((maSetBound.GetHeight() - 1L) / 2.0));
401     maTranslate.setZ(ZBUFFER_DEPTH_RANGE / 2.0);
402 
403     // Skalierung
404     maScale.setX((maSetBound.GetWidth() - 1L) / 2.0);
405     maScale.setY((maSetBound.GetHeight() - 1L) / -2.0);
406     maScale.setZ(ZBUFFER_DEPTH_RANGE / 2.0);
407 
408     // Auf Veraenderung des ViewPorts reagieren
409     PostSetViewport();
410 }
411 
SetRatio(double fNew)412 void B3dTransformationSet::SetRatio(double fNew)
413 {
414     if(mfRatio != fNew)
415     {
416         mfRatio = fNew;
417         mbProjectionValid = sal_False;
418         mbObjectToDeviceValid = sal_False;
419         mbWorldToViewValid = sal_False;
420     }
421 }
422 
SetRatioMode(Base3DRatio eNew)423 void B3dTransformationSet::SetRatioMode(Base3DRatio eNew)
424 {
425     if(meRatio != eNew)
426     {
427         meRatio = eNew;
428         mbProjectionValid = sal_False;
429         mbObjectToDeviceValid = sal_False;
430         mbWorldToViewValid = sal_False;
431     }
432 }
433 
SetDeviceRectangle(double fL,double fR,double fB,double fT,sal_Bool bBroadCastChange)434 void B3dTransformationSet::SetDeviceRectangle(double fL, double fR, double fB, double fT,
435     sal_Bool bBroadCastChange)
436 {
437     if(fL != mfLeftBound || fR != mfRightBound || fB != mfBottomBound || fT != mfTopBound)
438     {
439         mfLeftBound = fL;
440         mfRightBound = fR;
441         mfBottomBound = fB;
442         mfTopBound = fT;
443 
444         mbProjectionValid = sal_False;
445         mbObjectToDeviceValid = sal_False;
446         mbWorldToViewValid = sal_False;
447 
448         // Aenderung bekanntmachen
449         if(bBroadCastChange)
450             DeviceRectangleChange();
451     }
452 }
453 
SetDeviceVolume(const basegfx::B3DRange & rVol,sal_Bool bBroadCastChange)454 void B3dTransformationSet::SetDeviceVolume(const basegfx::B3DRange& rVol, sal_Bool bBroadCastChange)
455 {
456     SetDeviceRectangle(rVol.getMinX(), rVol.getMaxX(), rVol.getMinY(), rVol.getMaxY(), bBroadCastChange);
457     SetFrontClippingPlane(rVol.getMinZ());
458     SetBackClippingPlane(rVol.getMaxZ());
459 }
460 
DeviceRectangleChange()461 void B3dTransformationSet::DeviceRectangleChange()
462 {
463 }
464 
GetDeviceRectangle(double & fL,double & fR,double & fB,double & fT)465 void B3dTransformationSet::GetDeviceRectangle(double &fL, double &fR, double& fB, double& fT)
466 {
467     fL = mfLeftBound;
468     fR = mfRightBound;
469     fB = mfBottomBound;
470     fT = mfTopBound;
471 
472     mbProjectionValid = sal_False;
473     mbObjectToDeviceValid = sal_False;
474     mbWorldToViewValid = sal_False;
475 }
476 
GetDeviceVolume()477 basegfx::B3DRange B3dTransformationSet::GetDeviceVolume()
478 {
479     basegfx::B3DRange aRet;
480 
481     aRet.expand(basegfx::B3DTuple(mfLeftBound, mfBottomBound, mfNearBound));
482     aRet.expand(basegfx::B3DTuple(mfRightBound, mfTopBound, mfFarBound));
483 
484     return aRet;
485 }
486 
SetFrontClippingPlane(double fF)487 void B3dTransformationSet::SetFrontClippingPlane(double fF)
488 {
489     if(mfNearBound != fF)
490     {
491         mfNearBound = fF;
492         mbProjectionValid = sal_False;
493         mbObjectToDeviceValid = sal_False;
494         mbWorldToViewValid = sal_False;
495     }
496 }
497 
SetBackClippingPlane(double fB)498 void B3dTransformationSet::SetBackClippingPlane(double fB)
499 {
500     if(mfFarBound != fB)
501     {
502         mfFarBound = fB;
503         mbProjectionValid = sal_False;
504         mbObjectToDeviceValid = sal_False;
505         mbWorldToViewValid = sal_False;
506     }
507 }
508 
SetPerspective(sal_Bool bNew)509 void B3dTransformationSet::SetPerspective(sal_Bool bNew)
510 {
511     if(mbPerspective != bNew)
512     {
513         mbPerspective = bNew;
514         mbProjectionValid = sal_False;
515         mbObjectToDeviceValid = sal_False;
516         mbWorldToViewValid = sal_False;
517     }
518 }
519 
SetViewportRectangle(Rectangle & rRect,Rectangle & rVisible)520 void B3dTransformationSet::SetViewportRectangle(Rectangle& rRect, Rectangle& rVisible)
521 {
522     if(rRect != maViewportRectangle || rVisible != maVisibleRectangle)
523     {
524         maViewportRectangle = rRect;
525         maVisibleRectangle = rVisible;
526 
527         mbProjectionValid = sal_False;
528         mbObjectToDeviceValid = sal_False;
529         mbWorldToViewValid = sal_False;
530     }
531 }
532 
PostSetViewport()533 void B3dTransformationSet::PostSetViewport()
534 {
535 }
536 
GetLogicalViewportBounds()537 const Rectangle& B3dTransformationSet::GetLogicalViewportBounds()
538 {
539     if(!mbProjectionValid)
540         CalcViewport();
541     return maSetBound;
542 }
543 
GetScale()544 const basegfx::B3DVector& B3dTransformationSet::GetScale()
545 {
546     if(!mbProjectionValid)
547         CalcViewport();
548     return maScale;
549 }
550 
GetTranslate()551 const basegfx::B3DVector& B3dTransformationSet::GetTranslate()
552 {
553     if(!mbProjectionValid)
554         CalcViewport();
555     return maTranslate;
556 }
557 
558 /*************************************************************************
559 |*
560 |* Hilfsmatrixberechnungsroutinen
561 |*
562 \************************************************************************/
563 
CalcMatObjectToDevice()564 void B3dTransformationSet::CalcMatObjectToDevice()
565 {
566     // ObjectToDevice berechnen (Orientation * Projection * Object)
567     maObjectToDevice = maObjectTrans;
568     maObjectToDevice *= maOrientation;
569     maObjectToDevice *= GetProjection();
570 
571     // auf gueltig setzen
572     mbObjectToDeviceValid = sal_True;
573 }
574 
GetObjectToDevice()575 const basegfx::B3DHomMatrix& B3dTransformationSet::GetObjectToDevice()
576 {
577     if(!mbObjectToDeviceValid)
578         CalcMatObjectToDevice();
579     return maObjectToDevice;
580 }
581 
CalcMatInvTransObjectToEye()582 void B3dTransformationSet::CalcMatInvTransObjectToEye()
583 {
584     maInvTransObjectToEye = maObjectTrans;
585     maInvTransObjectToEye *= maOrientation;
586     maInvTransObjectToEye.invert();
587     maInvTransObjectToEye.transpose();
588 
589     // eventuelle Translationen rausschmeissen, da diese
590     // Matrix nur zur Transformation von Vektoren gedacht ist
591     maInvTransObjectToEye.set(3, 0, 0.0);
592     maInvTransObjectToEye.set(3, 1, 0.0);
593     maInvTransObjectToEye.set(3, 2, 0.0);
594     maInvTransObjectToEye.set(3, 3, 1.0);
595 
596     // auf gueltig setzen
597     mbInvTransObjectToEyeValid = sal_True;
598 }
599 
GetInvTransObjectToEye()600 const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvTransObjectToEye()
601 {
602     if(!mbInvTransObjectToEyeValid)
603         CalcMatInvTransObjectToEye();
604     return maInvTransObjectToEye;
605 }
606 
GetMatFromObjectToView()607 basegfx::B3DHomMatrix B3dTransformationSet::GetMatFromObjectToView()
608 {
609     basegfx::B3DHomMatrix aFromObjectToView = GetObjectToDevice();
610 
611     const basegfx::B3DVector& rScale(GetScale());
612     aFromObjectToView.scale(rScale.getX(), rScale.getY(), rScale.getZ());
613     const basegfx::B3DVector& rTranslate(GetTranslate());
614     aFromObjectToView.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
615 
616     return aFromObjectToView;
617 }
618 
CalcMatFromWorldToView()619 void B3dTransformationSet::CalcMatFromWorldToView()
620 {
621     maMatFromWorldToView = maOrientation;
622     maMatFromWorldToView *= GetProjection();
623     const basegfx::B3DVector& rScale(GetScale());
624     maMatFromWorldToView.scale(rScale.getX(), rScale.getY(), rScale.getZ());
625     const basegfx::B3DVector& rTranslate(GetTranslate());
626     maMatFromWorldToView.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
627     maInvMatFromWorldToView = maMatFromWorldToView;
628     maInvMatFromWorldToView.invert();
629 
630     // gueltig setzen
631     mbWorldToViewValid = sal_True;
632 }
633 
GetMatFromWorldToView()634 const basegfx::B3DHomMatrix& B3dTransformationSet::GetMatFromWorldToView()
635 {
636     if(!mbWorldToViewValid)
637         CalcMatFromWorldToView();
638     return maMatFromWorldToView;
639 }
640 
GetInvMatFromWorldToView()641 const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvMatFromWorldToView()
642 {
643     if(!mbWorldToViewValid)
644         CalcMatFromWorldToView();
645     return maInvMatFromWorldToView;
646 }
647 
648 /*************************************************************************
649 |*
650 |* Direkter Zugriff auf verschiedene Transformationen
651 |*
652 \************************************************************************/
653 
WorldToEyeCoor(const basegfx::B3DPoint & rVec)654 const basegfx::B3DPoint B3dTransformationSet::WorldToEyeCoor(const basegfx::B3DPoint& rVec)
655 {
656     basegfx::B3DPoint aVec(rVec);
657     aVec *= GetOrientation();
658     return aVec;
659 }
660 
EyeToWorldCoor(const basegfx::B3DPoint & rVec)661 const basegfx::B3DPoint B3dTransformationSet::EyeToWorldCoor(const basegfx::B3DPoint& rVec)
662 {
663     basegfx::B3DPoint aVec(rVec);
664     aVec *= GetInvOrientation();
665     return aVec;
666 }
667 
EyeToViewCoor(const basegfx::B3DPoint & rVec)668 const basegfx::B3DPoint B3dTransformationSet::EyeToViewCoor(const basegfx::B3DPoint& rVec)
669 {
670     basegfx::B3DPoint aVec(rVec);
671     aVec *= GetProjection();
672     aVec *= GetScale();
673     aVec += GetTranslate();
674     return aVec;
675 }
676 
ViewToEyeCoor(const basegfx::B3DPoint & rVec)677 const basegfx::B3DPoint B3dTransformationSet::ViewToEyeCoor(const basegfx::B3DPoint& rVec)
678 {
679     basegfx::B3DPoint aVec(rVec);
680     aVec -= GetTranslate();
681     aVec = aVec / GetScale();
682     aVec *= GetInvProjection();
683     return aVec;
684 }
685 
WorldToViewCoor(const basegfx::B3DPoint & rVec)686 const basegfx::B3DPoint B3dTransformationSet::WorldToViewCoor(const basegfx::B3DPoint& rVec)
687 {
688     basegfx::B3DPoint aVec(rVec);
689     aVec *= GetMatFromWorldToView();
690     return aVec;
691 }
692 
ViewToWorldCoor(const basegfx::B3DPoint & rVec)693 const basegfx::B3DPoint B3dTransformationSet::ViewToWorldCoor(const basegfx::B3DPoint& rVec)
694 {
695     basegfx::B3DPoint aVec(rVec);
696     aVec *= GetInvMatFromWorldToView();
697     return aVec;
698 }
699 
DeviceToViewCoor(const basegfx::B3DPoint & rVec)700 const basegfx::B3DPoint B3dTransformationSet::DeviceToViewCoor(const basegfx::B3DPoint& rVec)
701 {
702     basegfx::B3DPoint aVec(rVec);
703     aVec *= GetScale();
704     aVec += GetTranslate();
705     return aVec;
706 }
707 
ViewToDeviceCoor(const basegfx::B3DPoint & rVec)708 const basegfx::B3DPoint B3dTransformationSet::ViewToDeviceCoor(const basegfx::B3DPoint& rVec)
709 {
710     basegfx::B3DPoint aVec(rVec);
711     aVec -= GetTranslate();
712     aVec = aVec / GetScale();
713     return aVec;
714 }
715 
ObjectToWorldCoor(const basegfx::B3DPoint & rVec)716 const basegfx::B3DPoint B3dTransformationSet::ObjectToWorldCoor(const basegfx::B3DPoint& rVec)
717 {
718     basegfx::B3DPoint aVec(rVec);
719     aVec *= GetObjectTrans();
720     return aVec;
721 }
722 
WorldToObjectCoor(const basegfx::B3DPoint & rVec)723 const basegfx::B3DPoint B3dTransformationSet::WorldToObjectCoor(const basegfx::B3DPoint& rVec)
724 {
725     basegfx::B3DPoint aVec(rVec);
726     aVec *= GetInvObjectTrans();
727     return aVec;
728 }
729 
ObjectToViewCoor(const basegfx::B3DPoint & rVec)730 const basegfx::B3DPoint B3dTransformationSet::ObjectToViewCoor(const basegfx::B3DPoint& rVec)
731 {
732     basegfx::B3DPoint aVec(rVec);
733     aVec *= GetObjectTrans();
734     aVec *= GetMatFromWorldToView();
735     return aVec;
736 }
737 
ViewToObjectCoor(const basegfx::B3DPoint & rVec)738 const basegfx::B3DPoint B3dTransformationSet::ViewToObjectCoor(const basegfx::B3DPoint& rVec)
739 {
740     basegfx::B3DPoint aVec(rVec);
741     aVec *= GetInvMatFromWorldToView();
742     aVec *= GetInvObjectTrans();
743     return aVec;
744 }
745 
ObjectToEyeCoor(const basegfx::B3DPoint & rVec)746 const basegfx::B3DPoint B3dTransformationSet::ObjectToEyeCoor(const basegfx::B3DPoint& rVec)
747 {
748     basegfx::B3DPoint aVec(rVec);
749     aVec *= GetObjectTrans();
750     aVec *= GetOrientation();
751     return aVec;
752 }
753 
EyeToObjectCoor(const basegfx::B3DPoint & rVec)754 const basegfx::B3DPoint B3dTransformationSet::EyeToObjectCoor(const basegfx::B3DPoint& rVec)
755 {
756     basegfx::B3DPoint aVec(rVec);
757     aVec *= GetInvOrientation();
758     aVec *= GetInvObjectTrans();
759     return aVec;
760 }
761 
DeviceToEyeCoor(const basegfx::B3DPoint & rVec)762 const basegfx::B3DPoint B3dTransformationSet::DeviceToEyeCoor(const basegfx::B3DPoint& rVec)
763 {
764     basegfx::B3DPoint aVec(rVec);
765     aVec *= GetInvProjection();
766     return aVec;
767 }
768 
EyeToDeviceCoor(const basegfx::B3DPoint & rVec)769 const basegfx::B3DPoint B3dTransformationSet::EyeToDeviceCoor(const basegfx::B3DPoint& rVec)
770 {
771     basegfx::B3DPoint aVec(rVec);
772     aVec *= GetProjection();
773     return aVec;
774 }
775 
InvTransObjectToEye(const basegfx::B3DPoint & rVec)776 const basegfx::B3DPoint B3dTransformationSet::InvTransObjectToEye(const basegfx::B3DPoint& rVec)
777 {
778     basegfx::B3DPoint aVec(rVec);
779     aVec *= GetInvTransObjectToEye();
780     return aVec;
781 }
782 
TransTextureCoor(const basegfx::B2DPoint & rVec)783 const basegfx::B2DPoint B3dTransformationSet::TransTextureCoor(const basegfx::B2DPoint& rVec)
784 {
785     basegfx::B2DPoint aVec(rVec);
786     aVec *= GetTexture();
787     return aVec;
788 }
789 
790 /*************************************************************************
791 |*
792 |* Konstruktor B3dViewport
793 |*
794 \************************************************************************/
795 
B3dViewport()796 B3dViewport::B3dViewport()
797 :   B3dTransformationSet(),
798     aVRP(0, 0, 0),
799     aVPN(0, 0, 1),
800     aVUV(0, 1, 0)
801 {
802     CalcOrientation();
803 }
804 
~B3dViewport()805 B3dViewport::~B3dViewport()
806 {
807 }
808 
SetVRP(const basegfx::B3DPoint & rNewVRP)809 void B3dViewport::SetVRP(const basegfx::B3DPoint& rNewVRP)
810 {
811     aVRP = rNewVRP;
812     CalcOrientation();
813 }
814 
SetVPN(const basegfx::B3DVector & rNewVPN)815 void B3dViewport::SetVPN(const basegfx::B3DVector& rNewVPN)
816 {
817     aVPN = rNewVPN;
818     CalcOrientation();
819 }
820 
SetVUV(const basegfx::B3DVector & rNewVUV)821 void B3dViewport::SetVUV(const basegfx::B3DVector& rNewVUV)
822 {
823     aVUV = rNewVUV;
824     CalcOrientation();
825 }
826 
SetViewportValues(const basegfx::B3DPoint & rNewVRP,const basegfx::B3DVector & rNewVPN,const basegfx::B3DVector & rNewVUV)827 void B3dViewport::SetViewportValues(
828     const basegfx::B3DPoint& rNewVRP,
829     const basegfx::B3DVector& rNewVPN,
830     const basegfx::B3DVector& rNewVUV)
831 {
832     aVRP = rNewVRP;
833     aVPN = rNewVPN;
834     aVUV = rNewVUV;
835     CalcOrientation();
836 }
837 
CalcOrientation()838 void B3dViewport::CalcOrientation()
839 {
840     SetOrientation(aVRP, aVPN, aVUV);
841 }
842 
843 /*************************************************************************
844 |*
845 |* Konstruktor B3dViewport
846 |*
847 \************************************************************************/
848 
B3dCamera(const basegfx::B3DPoint & rPos,const basegfx::B3DVector & rLkAt,double fFocLen,double fBnkAng,sal_Bool bUseFocLen)849 B3dCamera::B3dCamera(
850     const basegfx::B3DPoint& rPos, const basegfx::B3DVector& rLkAt,
851     double fFocLen, double fBnkAng, sal_Bool bUseFocLen)
852 :   B3dViewport(),
853     aPosition(rPos),
854     aCorrectedPosition(rPos),
855     aLookAt(rLkAt),
856     fFocalLength(fFocLen),
857     fBankAngle(fBnkAng),
858     bUseFocalLength(bUseFocLen)
859 {
860     CalcNewViewportValues();
861 }
862 
~B3dCamera()863 B3dCamera::~B3dCamera()
864 {
865 }
866 
SetPosition(const basegfx::B3DPoint & rNewPos)867 void B3dCamera::SetPosition(const basegfx::B3DPoint& rNewPos)
868 {
869     if(rNewPos != aPosition)
870     {
871         // Zuweisen
872         aCorrectedPosition = aPosition = rNewPos;
873 
874         // Neuberechnung
875         CalcNewViewportValues();
876     }
877 }
878 
SetLookAt(const basegfx::B3DVector & rNewLookAt)879 void B3dCamera::SetLookAt(const basegfx::B3DVector& rNewLookAt)
880 {
881     if(rNewLookAt != aLookAt)
882     {
883         // Zuweisen
884         aLookAt = rNewLookAt;
885 
886         // Neuberechnung
887         CalcNewViewportValues();
888     }
889 }
890 
SetPositionAndLookAt(const basegfx::B3DPoint & rNewPos,const basegfx::B3DVector & rNewLookAt)891 void B3dCamera::SetPositionAndLookAt(const basegfx::B3DPoint& rNewPos, const basegfx::B3DVector& rNewLookAt)
892 {
893     if(rNewPos != aPosition || rNewLookAt != aLookAt)
894     {
895         // Zuweisen
896         aPosition = rNewPos;
897         aLookAt = rNewLookAt;
898 
899         // Neuberechnung
900         CalcNewViewportValues();
901     }
902 }
903 
SetFocalLength(double fLen)904 void B3dCamera::SetFocalLength(double fLen)
905 {
906     if(fLen != fFocalLength)
907     {
908         // Zuweisen
909         if(fLen < 5.0)
910             fLen = 5.0;
911         fFocalLength = fLen;
912 
913         // Neuberechnung
914         CalcNewViewportValues();
915     }
916 }
917 
SetBankAngle(double fAngle)918 void B3dCamera::SetBankAngle(double fAngle)
919 {
920     if(fAngle != fBankAngle)
921     {
922         // Zuweisen
923         fBankAngle = fAngle;
924 
925         // Neuberechnung
926         CalcNewViewportValues();
927     }
928 }
929 
SetUseFocalLength(sal_Bool bNew)930 void B3dCamera::SetUseFocalLength(sal_Bool bNew)
931 {
932     if(bNew != (sal_Bool)bUseFocalLength)
933     {
934         // Zuweisen
935         bUseFocalLength = bNew;
936 
937         // Neuberechnung
938         CalcNewViewportValues();
939     }
940 }
941 
DeviceRectangleChange()942 void B3dCamera::DeviceRectangleChange()
943 {
944     // call parent
945     B3dViewport::DeviceRectangleChange();
946 
947     // Auf Aenderung reagieren
948     CalcNewViewportValues();
949 }
950 
CalcNewViewportValues()951 void B3dCamera::CalcNewViewportValues()
952 {
953     basegfx::B3DVector aViewVector(aPosition - aLookAt);
954     basegfx::B3DVector aNewVPN(aViewVector);
955 
956     basegfx::B3DVector aNewVUV(0.0, 1.0, 0.0);
957     if(aNewVPN.getLength() < aNewVPN.getY())
958         aNewVUV.setX(0.5);
959 
960     aNewVUV.normalize();
961     aNewVPN.normalize();
962 
963     basegfx::B3DVector aNewToTheRight = aNewVPN;
964     aNewToTheRight = aNewToTheRight.getPerpendicular(aNewVUV);
965     aNewToTheRight.normalize();
966     aNewVUV = aNewToTheRight.getPerpendicular(aNewVPN);
967     aNewVUV.normalize();
968 
969     SetViewportValues(aPosition, aNewVPN, aNewVUV);
970     if(CalcFocalLength())
971         SetViewportValues(aCorrectedPosition, aNewVPN, aNewVUV);
972 
973     if(fBankAngle != 0.0)
974     {
975         basegfx::B3DHomMatrix aRotMat;
976         aRotMat.rotate(0.0, 0.0, fBankAngle);
977         basegfx::B3DVector aUp(0.0, 1.0, 0.0);
978         aUp *= aRotMat;
979         aUp = EyeToWorldCoor(aUp);
980         aUp.normalize();
981         SetVUV(aUp);
982     }
983 }
984 
CalcFocalLength()985 sal_Bool B3dCamera::CalcFocalLength()
986 {
987     double fWidth = GetDeviceRectangleWidth();
988     sal_Bool bRetval = sal_False;
989 
990     if(bUseFocalLength)
991     {
992         // Position aufgrund der FocalLength korrigieren
993         aCorrectedPosition = basegfx::B3DPoint(0.0, 0.0, fFocalLength * fWidth / 35.0);
994         aCorrectedPosition = EyeToWorldCoor(aCorrectedPosition);
995         bRetval = sal_True;
996     }
997     else
998     {
999         // FocalLength anhand der Position anpassen
1000         basegfx::B3DPoint aOldPosition;
1001         aOldPosition = WorldToEyeCoor(aOldPosition);
1002         if(fWidth != 0.0)
1003             fFocalLength = aOldPosition.getZ() / fWidth * 35.0;
1004         if(fFocalLength < 5.0)
1005             fFocalLength = 5.0;
1006     }
1007     return bRetval;
1008 }
1009 
1010 // eof
1011