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