xref: /trunk/main/svx/source/engine3d/viewpt3d2.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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