xref: /aoo41x/main/svx/source/engine3d/viewpt3d2.cxx (revision f6e50924)
1*f6e50924SAndrew Rist /**************************************************************
2*f6e50924SAndrew Rist  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include <svx/viewpt3d.hxx>
27cdf0e10cSrcweir #include <svx/volume3d.hxx>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir /*************************************************************************
30cdf0e10cSrcweir |*
31cdf0e10cSrcweir |* Konstruktor
32cdf0e10cSrcweir |*
33cdf0e10cSrcweir \************************************************************************/
34cdf0e10cSrcweir 
Viewport3D()35cdf0e10cSrcweir Viewport3D::Viewport3D() :
36cdf0e10cSrcweir 	aVRP(0, 0, 5),
37cdf0e10cSrcweir 	aVPN(0, 0, 1),
38cdf0e10cSrcweir 	aVUV(0, 1, 1),
39cdf0e10cSrcweir 	aPRP(0, 0, 2),
40cdf0e10cSrcweir 	fVPD(-3),
41cdf0e10cSrcweir 	fNearClipDist (0.0),
42cdf0e10cSrcweir 	fFarClipDist (0.0),
43cdf0e10cSrcweir 	eProjection(PR_PERSPECTIVE),
44cdf0e10cSrcweir 	eAspectMapping(AS_NO_MAPPING),
45cdf0e10cSrcweir 	aDeviceRect(Point(0,0), Size(-1,-1)),
46cdf0e10cSrcweir 	aViewPoint (0, 0, 5000),
47cdf0e10cSrcweir 	bTfValid(0),
48cdf0e10cSrcweir 	fWRatio (1.0),
49cdf0e10cSrcweir 	fHRatio (1.0)
50cdf0e10cSrcweir {
51cdf0e10cSrcweir 	aViewWin.X = -1; aViewWin.Y = -1;
52cdf0e10cSrcweir 	aViewWin.W =  2; aViewWin.H = 2;
53cdf0e10cSrcweir }
54cdf0e10cSrcweir 
55cdf0e10cSrcweir /*************************************************************************
56cdf0e10cSrcweir |*
57cdf0e10cSrcweir |* ViewWindow (in View-Koordinaten) setzen
58cdf0e10cSrcweir |*
59cdf0e10cSrcweir \************************************************************************/
60cdf0e10cSrcweir 
SetViewWindow(double fX,double fY,double fW,double fH)61cdf0e10cSrcweir void Viewport3D::SetViewWindow(double fX, double fY, double fW, double fH)
62cdf0e10cSrcweir {
63cdf0e10cSrcweir 	aViewWin.X = fX;
64cdf0e10cSrcweir 	aViewWin.Y = fY;
65cdf0e10cSrcweir 	if ( fW > 0 )	aViewWin.W = fW;
66cdf0e10cSrcweir 	else			aViewWin.W = 1.0;
67cdf0e10cSrcweir 	if ( fH > 0 )	aViewWin.H = fH;
68cdf0e10cSrcweir 	else			aViewWin.H = 1.0;
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 	fWRatio = aDeviceRect.GetWidth() / aViewWin.W;
71cdf0e10cSrcweir 	fHRatio = aDeviceRect.GetHeight() / aViewWin.H;
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
74cdf0e10cSrcweir /*************************************************************************
75cdf0e10cSrcweir |*
76cdf0e10cSrcweir |* ViewWindow zurueckgeben
77cdf0e10cSrcweir |*
78cdf0e10cSrcweir \************************************************************************/
79cdf0e10cSrcweir 
GetViewWindow(double & rX,double & rY,double & rW,double & rH) const80cdf0e10cSrcweir void Viewport3D::GetViewWindow(double& rX, double& rY,
81cdf0e10cSrcweir 							   double& rW, double& rH) const
82cdf0e10cSrcweir {
83cdf0e10cSrcweir 	rX = aViewWin.X;
84cdf0e10cSrcweir 	rY = aViewWin.Y;
85cdf0e10cSrcweir 	rW = aViewWin.W;
86cdf0e10cSrcweir 	rH = aViewWin.H;
87cdf0e10cSrcweir }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir /*************************************************************************
90cdf0e10cSrcweir |*
91cdf0e10cSrcweir |* Beobachterposition (PRP) in Weltkoordinaten zurueckgeben
92cdf0e10cSrcweir |*
93cdf0e10cSrcweir \************************************************************************/
94cdf0e10cSrcweir 
GetViewPoint()95cdf0e10cSrcweir const basegfx::B3DPoint& Viewport3D::GetViewPoint()
96cdf0e10cSrcweir {
97cdf0e10cSrcweir 	MakeTransform();
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 	return aViewPoint;
100cdf0e10cSrcweir }
101cdf0e10cSrcweir 
102cdf0e10cSrcweir /*************************************************************************
103cdf0e10cSrcweir |*
104cdf0e10cSrcweir |* Transformationsmatrix zurueckgeben
105cdf0e10cSrcweir |*
106cdf0e10cSrcweir \************************************************************************/
107cdf0e10cSrcweir 
GetViewTransform()108cdf0e10cSrcweir const basegfx::B3DHomMatrix& Viewport3D::GetViewTransform()
109cdf0e10cSrcweir {
110cdf0e10cSrcweir 	MakeTransform();
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 	return aViewTf;
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 
121cdf0e10cSrcweir /*************************************************************************
122cdf0e10cSrcweir |*
123cdf0e10cSrcweir |* View-Transformationsmatrix berechnen
124cdf0e10cSrcweir |*
125cdf0e10cSrcweir \************************************************************************/
126cdf0e10cSrcweir 
MakeTransform(void)127cdf0e10cSrcweir void Viewport3D::MakeTransform(void)
128cdf0e10cSrcweir {
129cdf0e10cSrcweir 	if ( !bTfValid )
130cdf0e10cSrcweir 	{
131cdf0e10cSrcweir 		double fV, fXupVp, fYupVp;
132cdf0e10cSrcweir 		aViewPoint = aVRP + aVPN * aPRP.getZ();
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 		// auf Einheitsmatrix zuruecksetzen
135cdf0e10cSrcweir 		aViewTf.identity();
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 		// in den Ursprung verschieben
138cdf0e10cSrcweir 		aViewTf.translate(-aVRP.getX(), -aVRP.getY(), -aVRP.getZ());
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 		// fV = Laenge der Projektion von aVPN auf die yz-Ebene:
141cdf0e10cSrcweir 		fV = aVPN.getYZLength();
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 		if ( fV != 0 )
144cdf0e10cSrcweir 		{
145cdf0e10cSrcweir 			basegfx::B3DHomMatrix aTemp;
146cdf0e10cSrcweir 			const double fSin(aVPN.getY() / fV);
147cdf0e10cSrcweir 			const double fCos(aVPN.getZ() / fV);
148cdf0e10cSrcweir 			aTemp.set(2, 2, fCos);
149cdf0e10cSrcweir 			aTemp.set(1, 1, fCos);
150cdf0e10cSrcweir 			aTemp.set(2, 1, fSin);
151cdf0e10cSrcweir 			aTemp.set(1, 2, -fSin);
152cdf0e10cSrcweir 			aViewTf *= aTemp;
153cdf0e10cSrcweir 		}
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 		{
156cdf0e10cSrcweir 			basegfx::B3DHomMatrix aTemp;
157cdf0e10cSrcweir 			const double fSin(-aVPN.getX());
158cdf0e10cSrcweir 			const double fCos(fV);
159cdf0e10cSrcweir 			aTemp.set(2, 2, fCos);
160cdf0e10cSrcweir 			aTemp.set(0, 0, fCos);
161cdf0e10cSrcweir 			aTemp.set(0, 2, fSin);
162cdf0e10cSrcweir 			aTemp.set(2, 0, -fSin);
163cdf0e10cSrcweir 			aViewTf *= aTemp;
164cdf0e10cSrcweir 		}
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 		// X- und Y-Koordinaten des View Up Vektors in das (vorlaeufige)
167cdf0e10cSrcweir 		// View-Koordinatensytem umrechnen
168cdf0e10cSrcweir 		fXupVp = aViewTf.get(0, 0) * aVUV.getX() + aViewTf.get(0, 1) * aVUV.getY() + aViewTf.get(0, 2) * aVUV.getZ();
169cdf0e10cSrcweir 		fYupVp = aViewTf.get(1, 0) * aVUV.getX() + aViewTf.get(1, 1) * aVUV.getY() + aViewTf.get(1, 2) * aVUV.getZ();
170cdf0e10cSrcweir 		fV = sqrt(fXupVp * fXupVp + fYupVp * fYupVp);
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 		if ( fV != 0 )
173cdf0e10cSrcweir 		{
174cdf0e10cSrcweir 			basegfx::B3DHomMatrix aTemp;
175cdf0e10cSrcweir 			const double fSin(fXupVp / fV);
176cdf0e10cSrcweir 			const double fCos(fYupVp / fV);
177cdf0e10cSrcweir 			aTemp.set(1, 1, fCos);
178cdf0e10cSrcweir 			aTemp.set(0, 0, fCos);
179cdf0e10cSrcweir 			aTemp.set(1, 0, fSin);
180cdf0e10cSrcweir 			aTemp.set(0, 1, -fSin);
181cdf0e10cSrcweir 			aViewTf *= aTemp;
182cdf0e10cSrcweir 		}
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 		bTfValid = sal_True;
185cdf0e10cSrcweir 	}
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
188cdf0e10cSrcweir /*************************************************************************
189cdf0e10cSrcweir |*
190cdf0e10cSrcweir |* DeviceWindow des Ausgabegeraetes setzen
191cdf0e10cSrcweir |*
192cdf0e10cSrcweir \************************************************************************/
193cdf0e10cSrcweir 
SetDeviceWindow(const Rectangle & rRect)194cdf0e10cSrcweir void Viewport3D::SetDeviceWindow(const Rectangle& rRect)
195cdf0e10cSrcweir {
196cdf0e10cSrcweir 	long nNewW = rRect.GetWidth();
197cdf0e10cSrcweir 	long nNewH = rRect.GetHeight();
198cdf0e10cSrcweir 	long nOldW = aDeviceRect.GetWidth();
199cdf0e10cSrcweir 	long nOldH = aDeviceRect.GetHeight();
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 	switch ( eAspectMapping )
202cdf0e10cSrcweir 	{
203cdf0e10cSrcweir 		double	fRatio, fTmp;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 		// Mapping, ohne die reale Groesse der Objekte im Device-Window
206cdf0e10cSrcweir 		// zu aendern
207cdf0e10cSrcweir 		case AS_HOLD_SIZE:
208cdf0e10cSrcweir 			// Wenn Device ungueltig (w, h = -1), zunaechst
209cdf0e10cSrcweir 			// View mit AsHoldX anpassen
210cdf0e10cSrcweir 			if ( nOldW > 0 && nOldH > 0 )
211cdf0e10cSrcweir 			{
212cdf0e10cSrcweir 				fRatio = (double) nNewW / nOldW;
213cdf0e10cSrcweir 				aViewWin.X *= fRatio;
214cdf0e10cSrcweir 				aViewWin.W *= fRatio;
215cdf0e10cSrcweir 				fRatio = (double) nNewH / nOldH;
216cdf0e10cSrcweir 				aViewWin.Y *= fRatio;
217cdf0e10cSrcweir 				aViewWin.H *= fRatio;
218cdf0e10cSrcweir 				break;
219cdf0e10cSrcweir 			}
220cdf0e10cSrcweir 		case AS_HOLD_X:
221cdf0e10cSrcweir 			// View-Hoehe an -Breite anpassen
222cdf0e10cSrcweir 			fRatio = (double) nNewH / nNewW;
223cdf0e10cSrcweir 			fTmp = aViewWin.H;
224cdf0e10cSrcweir 			aViewWin.H = aViewWin.W * fRatio;
225cdf0e10cSrcweir 			aViewWin.Y = aViewWin.Y * aViewWin.H / fTmp;
226cdf0e10cSrcweir 			break;
227cdf0e10cSrcweir 
228cdf0e10cSrcweir 		case AS_HOLD_Y:
229cdf0e10cSrcweir 			// View-Breite an -Hoehe anpassen
230cdf0e10cSrcweir 			fRatio = (double) nNewW / nNewH;
231cdf0e10cSrcweir 			fTmp = aViewWin.W;
232cdf0e10cSrcweir 			aViewWin.W = aViewWin.H * fRatio;
233cdf0e10cSrcweir 			aViewWin.X = aViewWin.X * aViewWin.W / fTmp;
234cdf0e10cSrcweir 			break;
235cdf0e10cSrcweir 		default: break;
236cdf0e10cSrcweir 	}
237cdf0e10cSrcweir 	fWRatio = nNewW / aViewWin.W;
238cdf0e10cSrcweir 	fHRatio = nNewH / aViewWin.H;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 	aDeviceRect = rRect;
241cdf0e10cSrcweir }
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 
252cdf0e10cSrcweir /*************************************************************************
253cdf0e10cSrcweir |*
254cdf0e10cSrcweir |* 3D-Punkt auf Viewplane projizieren
255cdf0e10cSrcweir |*
256cdf0e10cSrcweir \************************************************************************/
257cdf0e10cSrcweir 
DoProjection(const basegfx::B3DPoint & rVec) const258cdf0e10cSrcweir basegfx::B3DPoint Viewport3D::DoProjection(const basegfx::B3DPoint& rVec) const
259cdf0e10cSrcweir {
260cdf0e10cSrcweir 	basegfx::B3DPoint aVec(rVec);
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 	if ( eProjection == PR_PERSPECTIVE )
263cdf0e10cSrcweir 	{
264cdf0e10cSrcweir 		double fPrDist = fVPD - aPRP.getZ();
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 		if ( aPRP.getZ() == rVec.getZ() )
267cdf0e10cSrcweir 		{
268cdf0e10cSrcweir 			aVec.setX(0.0);
269cdf0e10cSrcweir 			aVec.setY(0.0);
270cdf0e10cSrcweir 		}
271cdf0e10cSrcweir 		else
272cdf0e10cSrcweir 		{
273cdf0e10cSrcweir 			// Das ist die Version fuer beliebigen PRP, wird aber
274cdf0e10cSrcweir 			// aus Performancegruenden nicht verwendet
275cdf0e10cSrcweir 			fPrDist /= aVec.getZ() - aPRP.getZ();
276cdf0e10cSrcweir 			aVec.setX(aVec.getX() * fPrDist);
277cdf0e10cSrcweir 			aVec.setY(aVec.getY() * fPrDist);
278cdf0e10cSrcweir 		}
279cdf0e10cSrcweir 	}
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 	return aVec;
282cdf0e10cSrcweir }
283cdf0e10cSrcweir 
284cdf0e10cSrcweir /*************************************************************************
285cdf0e10cSrcweir |*
286cdf0e10cSrcweir |* 3D-Punkt auf Geraetekoordinaten mappen
287cdf0e10cSrcweir |*
288cdf0e10cSrcweir \************************************************************************/
289cdf0e10cSrcweir 
MapToDevice(const basegfx::B3DPoint & rVec) const290cdf0e10cSrcweir basegfx::B3DPoint Viewport3D::MapToDevice(const basegfx::B3DPoint& rVec) const
291cdf0e10cSrcweir {
292cdf0e10cSrcweir 	basegfx::B3DPoint aRetval;
293cdf0e10cSrcweir 
294cdf0e10cSrcweir 	// Y-Koordinate subtrahieren, da die Device-Y-Achse von oben
295cdf0e10cSrcweir 	// nach unten verlaeuft
296cdf0e10cSrcweir 	aRetval.setX((double)aDeviceRect.Left() + ((rVec.getX() - aViewWin.X) * fWRatio));
297cdf0e10cSrcweir 	aRetval.setY((double)aDeviceRect.Bottom() - ((rVec.getY() - aViewWin.Y) * fHRatio));
298cdf0e10cSrcweir 	aRetval.setZ(rVec.getZ());
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 	return aRetval;
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir /*************************************************************************
304cdf0e10cSrcweir |*
305cdf0e10cSrcweir |* View Reference Point setzen
306cdf0e10cSrcweir |*
307cdf0e10cSrcweir \************************************************************************/
308cdf0e10cSrcweir 
SetVRP(const basegfx::B3DPoint & rNewVRP)309cdf0e10cSrcweir void Viewport3D::SetVRP(const basegfx::B3DPoint& rNewVRP)
310cdf0e10cSrcweir {
311cdf0e10cSrcweir 	aVRP = rNewVRP;
312cdf0e10cSrcweir 	bTfValid = sal_False;
313cdf0e10cSrcweir }
314cdf0e10cSrcweir 
315cdf0e10cSrcweir /*************************************************************************
316cdf0e10cSrcweir |*
317cdf0e10cSrcweir |* View Plane Normal setzen
318cdf0e10cSrcweir |*
319cdf0e10cSrcweir \************************************************************************/
320cdf0e10cSrcweir 
SetVPN(const basegfx::B3DVector & rNewVPN)321cdf0e10cSrcweir void Viewport3D::SetVPN(const basegfx::B3DVector& rNewVPN)
322cdf0e10cSrcweir {
323cdf0e10cSrcweir 	aVPN = rNewVPN;
324cdf0e10cSrcweir 	aVPN.normalize();
325cdf0e10cSrcweir 	bTfValid = sal_False;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir /*************************************************************************
329cdf0e10cSrcweir |*
330cdf0e10cSrcweir |* View Up Vector setzen
331cdf0e10cSrcweir |*
332cdf0e10cSrcweir \************************************************************************/
333cdf0e10cSrcweir 
SetVUV(const basegfx::B3DVector & rNewVUV)334cdf0e10cSrcweir void Viewport3D::SetVUV(const basegfx::B3DVector& rNewVUV)
335cdf0e10cSrcweir {
336cdf0e10cSrcweir 	aVUV = rNewVUV;
337cdf0e10cSrcweir 	bTfValid = sal_False;
338cdf0e10cSrcweir }
339cdf0e10cSrcweir 
340cdf0e10cSrcweir /*************************************************************************
341cdf0e10cSrcweir |*
342cdf0e10cSrcweir |* Center Of Projection setzen
343cdf0e10cSrcweir |*
344cdf0e10cSrcweir \************************************************************************/
345cdf0e10cSrcweir 
SetPRP(const basegfx::B3DPoint & rNewPRP)346cdf0e10cSrcweir void Viewport3D::SetPRP(const basegfx::B3DPoint& rNewPRP)
347cdf0e10cSrcweir {
348cdf0e10cSrcweir 	aPRP = rNewPRP;
349cdf0e10cSrcweir 	aPRP.setX(0.0);
350cdf0e10cSrcweir 	aPRP.setY(0.0);
351cdf0e10cSrcweir 	bTfValid = sal_False;
352cdf0e10cSrcweir }
353cdf0e10cSrcweir 
354cdf0e10cSrcweir /*************************************************************************
355cdf0e10cSrcweir |*
356cdf0e10cSrcweir |* View Plane Distance setzen
357cdf0e10cSrcweir |*
358cdf0e10cSrcweir \************************************************************************/
359cdf0e10cSrcweir 
SetVPD(double fNewVPD)360cdf0e10cSrcweir void Viewport3D::SetVPD(double fNewVPD)
361cdf0e10cSrcweir {
362cdf0e10cSrcweir 	fVPD = fNewVPD;
363cdf0e10cSrcweir 	bTfValid = sal_False;
364cdf0e10cSrcweir }
365cdf0e10cSrcweir 
366cdf0e10cSrcweir /*************************************************************************
367cdf0e10cSrcweir |*
368cdf0e10cSrcweir |* Abstand der vorderen Clippingebene setzen
369cdf0e10cSrcweir |*
370cdf0e10cSrcweir \************************************************************************/
371cdf0e10cSrcweir 
SetNearClipDist(double fNewNCD)372cdf0e10cSrcweir void Viewport3D::SetNearClipDist(double fNewNCD)
373cdf0e10cSrcweir {
374cdf0e10cSrcweir 	fNearClipDist = fNewNCD;
375cdf0e10cSrcweir 	bTfValid = sal_False;
376cdf0e10cSrcweir }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir /*************************************************************************
379cdf0e10cSrcweir |*
380cdf0e10cSrcweir |* Abstand der hinteren Clippingebene setzen
381cdf0e10cSrcweir |*
382cdf0e10cSrcweir \************************************************************************/
383cdf0e10cSrcweir 
SetFarClipDist(double fNewFCD)384cdf0e10cSrcweir void Viewport3D::SetFarClipDist(double fNewFCD)
385cdf0e10cSrcweir {
386cdf0e10cSrcweir 	fFarClipDist = fNewFCD;
387cdf0e10cSrcweir 	bTfValid = sal_False;
388cdf0e10cSrcweir }
389cdf0e10cSrcweir 
390cdf0e10cSrcweir // eof
391