xref: /trunk/main/tools/source/generic/b3dtrans.cxx (revision 89b56da7)
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