1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
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
10cdf0e10cSrcweir *
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.
19cdf0e10cSrcweir *
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