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