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