1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewpt3d2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <svx/viewpt3d.hxx>
34 #include <svx/volume3d.hxx>
36 /*************************************************************************
40 \************************************************************************/
42 Viewport3D::Viewport3D() :
50 eProjection(PR_PERSPECTIVE
),
51 eAspectMapping(AS_NO_MAPPING
),
52 aDeviceRect(Point(0,0), Size(-1,-1)),
53 aViewPoint (0, 0, 5000),
58 aViewWin
.X
= -1; aViewWin
.Y
= -1;
59 aViewWin
.W
= 2; aViewWin
.H
= 2;
62 /*************************************************************************
64 |* ViewWindow (in View-Koordinaten) setzen
66 \************************************************************************/
68 void Viewport3D::SetViewWindow(double fX
, double fY
, double fW
, double fH
)
72 if ( fW
> 0 ) aViewWin
.W
= fW
;
73 else aViewWin
.W
= 1.0;
74 if ( fH
> 0 ) aViewWin
.H
= fH
;
75 else aViewWin
.H
= 1.0;
77 fWRatio
= aDeviceRect
.GetWidth() / aViewWin
.W
;
78 fHRatio
= aDeviceRect
.GetHeight() / aViewWin
.H
;
81 /*************************************************************************
83 |* ViewWindow zurueckgeben
85 \************************************************************************/
87 void Viewport3D::GetViewWindow(double& rX
, double& rY
,
88 double& rW
, double& rH
) const
96 /*************************************************************************
98 |* Beobachterposition (PRP) in Weltkoordinaten zurueckgeben
100 \************************************************************************/
102 const basegfx::B3DPoint
& Viewport3D::GetViewPoint()
109 /*************************************************************************
111 |* Transformationsmatrix zurueckgeben
113 \************************************************************************/
115 const basegfx::B3DHomMatrix
& Viewport3D::GetViewTransform()
128 /*************************************************************************
130 |* View-Transformationsmatrix berechnen
132 \************************************************************************/
134 void Viewport3D::MakeTransform(void)
138 double fV
, fXupVp
, fYupVp
;
139 aViewPoint
= aVRP
+ aVPN
* aPRP
.getZ();
141 // auf Einheitsmatrix zuruecksetzen
144 // in den Ursprung verschieben
145 aViewTf
.translate(-aVRP
.getX(), -aVRP
.getY(), -aVRP
.getZ());
147 // fV = Laenge der Projektion von aVPN auf die yz-Ebene:
148 fV
= aVPN
.getYZLength();
152 basegfx::B3DHomMatrix aTemp
;
153 const double fSin(aVPN
.getY() / fV
);
154 const double fCos(aVPN
.getZ() / fV
);
155 aTemp
.set(2, 2, fCos
);
156 aTemp
.set(1, 1, fCos
);
157 aTemp
.set(2, 1, fSin
);
158 aTemp
.set(1, 2, -fSin
);
163 basegfx::B3DHomMatrix aTemp
;
164 const double fSin(-aVPN
.getX());
165 const double fCos(fV
);
166 aTemp
.set(2, 2, fCos
);
167 aTemp
.set(0, 0, fCos
);
168 aTemp
.set(0, 2, fSin
);
169 aTemp
.set(2, 0, -fSin
);
173 // X- und Y-Koordinaten des View Up Vektors in das (vorlaeufige)
174 // View-Koordinatensytem umrechnen
175 fXupVp
= aViewTf
.get(0, 0) * aVUV
.getX() + aViewTf
.get(0, 1) * aVUV
.getY() + aViewTf
.get(0, 2) * aVUV
.getZ();
176 fYupVp
= aViewTf
.get(1, 0) * aVUV
.getX() + aViewTf
.get(1, 1) * aVUV
.getY() + aViewTf
.get(1, 2) * aVUV
.getZ();
177 fV
= sqrt(fXupVp
* fXupVp
+ fYupVp
* fYupVp
);
181 basegfx::B3DHomMatrix aTemp
;
182 const double fSin(fXupVp
/ fV
);
183 const double fCos(fYupVp
/ fV
);
184 aTemp
.set(1, 1, fCos
);
185 aTemp
.set(0, 0, fCos
);
186 aTemp
.set(1, 0, fSin
);
187 aTemp
.set(0, 1, -fSin
);
195 /*************************************************************************
197 |* DeviceWindow des Ausgabegeraetes setzen
199 \************************************************************************/
201 void Viewport3D::SetDeviceWindow(const Rectangle
& rRect
)
203 long nNewW
= rRect
.GetWidth();
204 long nNewH
= rRect
.GetHeight();
205 long nOldW
= aDeviceRect
.GetWidth();
206 long nOldH
= aDeviceRect
.GetHeight();
208 switch ( eAspectMapping
)
212 // Mapping, ohne die reale Groesse der Objekte im Device-Window
215 // Wenn Device ungueltig (w, h = -1), zunaechst
216 // View mit AsHoldX anpassen
217 if ( nOldW
> 0 && nOldH
> 0 )
219 fRatio
= (double) nNewW
/ nOldW
;
220 aViewWin
.X
*= fRatio
;
221 aViewWin
.W
*= fRatio
;
222 fRatio
= (double) nNewH
/ nOldH
;
223 aViewWin
.Y
*= fRatio
;
224 aViewWin
.H
*= fRatio
;
228 // View-Hoehe an -Breite anpassen
229 fRatio
= (double) nNewH
/ nNewW
;
231 aViewWin
.H
= aViewWin
.W
* fRatio
;
232 aViewWin
.Y
= aViewWin
.Y
* aViewWin
.H
/ fTmp
;
236 // View-Breite an -Hoehe anpassen
237 fRatio
= (double) nNewW
/ nNewH
;
239 aViewWin
.W
= aViewWin
.H
* fRatio
;
240 aViewWin
.X
= aViewWin
.X
* aViewWin
.W
/ fTmp
;
244 fWRatio
= nNewW
/ aViewWin
.W
;
245 fHRatio
= nNewH
/ aViewWin
.H
;
259 /*************************************************************************
261 |* 3D-Punkt auf Viewplane projizieren
263 \************************************************************************/
265 basegfx::B3DPoint
Viewport3D::DoProjection(const basegfx::B3DPoint
& rVec
) const
267 basegfx::B3DPoint
aVec(rVec
);
269 if ( eProjection
== PR_PERSPECTIVE
)
271 double fPrDist
= fVPD
- aPRP
.getZ();
273 if ( aPRP
.getZ() == rVec
.getZ() )
280 // Das ist die Version fuer beliebigen PRP, wird aber
281 // aus Performancegruenden nicht verwendet
282 fPrDist
/= aVec
.getZ() - aPRP
.getZ();
283 aVec
.setX(aVec
.getX() * fPrDist
);
284 aVec
.setY(aVec
.getY() * fPrDist
);
291 /*************************************************************************
293 |* 3D-Punkt auf Geraetekoordinaten mappen
295 \************************************************************************/
297 basegfx::B3DPoint
Viewport3D::MapToDevice(const basegfx::B3DPoint
& rVec
) const
299 basegfx::B3DPoint aRetval
;
301 // Y-Koordinate subtrahieren, da die Device-Y-Achse von oben
302 // nach unten verlaeuft
303 aRetval
.setX((double)aDeviceRect
.Left() + ((rVec
.getX() - aViewWin
.X
) * fWRatio
));
304 aRetval
.setY((double)aDeviceRect
.Bottom() - ((rVec
.getY() - aViewWin
.Y
) * fHRatio
));
305 aRetval
.setZ(rVec
.getZ());
310 /*************************************************************************
312 |* View Reference Point setzen
314 \************************************************************************/
316 void Viewport3D::SetVRP(const basegfx::B3DPoint
& rNewVRP
)
322 /*************************************************************************
324 |* View Plane Normal setzen
326 \************************************************************************/
328 void Viewport3D::SetVPN(const basegfx::B3DVector
& rNewVPN
)
335 /*************************************************************************
337 |* View Up Vector setzen
339 \************************************************************************/
341 void Viewport3D::SetVUV(const basegfx::B3DVector
& rNewVUV
)
347 /*************************************************************************
349 |* Center Of Projection setzen
351 \************************************************************************/
353 void Viewport3D::SetPRP(const basegfx::B3DPoint
& rNewPRP
)
361 /*************************************************************************
363 |* View Plane Distance setzen
365 \************************************************************************/
367 void Viewport3D::SetVPD(double fNewVPD
)
373 /*************************************************************************
375 |* Abstand der vorderen Clippingebene setzen
377 \************************************************************************/
379 void Viewport3D::SetNearClipDist(double fNewNCD
)
381 fNearClipDist
= fNewNCD
;
385 /*************************************************************************
387 |* Abstand der hinteren Clippingebene setzen
389 \************************************************************************/
391 void Viewport3D::SetFarClipDist(double fNewFCD
)
393 fFarClipDist
= fNewFCD
;