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