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