merge the formfield patch from ooo-build
[ooovba.git] / svx / source / engine3d / camera3d.cxx
bloba2243e68676a684158d78c823884d1772aadac77
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: camera3d.cxx,v $
10 * $Revision: 1.9 $
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/camera3d.hxx>
34 #include <tools/stream.hxx>
36 /*************************************************************************
38 |* Konstruktor
40 \************************************************************************/
42 Camera3D::Camera3D(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt,
43 double fFocalLen, double fBankAng) :
44 aResetPos(rPos),
45 aResetLookAt(rLookAt),
46 fResetFocalLength(fFocalLen),
47 fResetBankAngle(fBankAng),
48 fBankAngle(fBankAng),
49 bAutoAdjustProjection(TRUE)
51 SetVPD(0);
52 SetPosition(rPos);
53 SetLookAt(rLookAt);
54 SetFocalLength(fFocalLen);
57 /*************************************************************************
59 |* Default-Konstruktor
61 \************************************************************************/
63 Camera3D::Camera3D()
65 basegfx::B3DPoint aVector3D(0.0 ,0.0 ,1.0);
66 Camera3D(aVector3D, basegfx::B3DPoint());
69 /*************************************************************************
71 |* Konstruktor
73 \************************************************************************/
75 void Camera3D::Reset()
77 SetVPD(0);
78 fBankAngle = fResetBankAngle;
79 SetPosition(aResetPos);
80 SetLookAt(aResetLookAt);
81 SetFocalLength(fResetFocalLength);
84 /*************************************************************************
86 |* Defaultwerte fuer Reset setzen
88 \************************************************************************/
90 void Camera3D::SetDefaults(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt,
91 double fFocalLen, double fBankAng)
93 aResetPos = rPos;
94 aResetLookAt = rLookAt;
95 fResetFocalLength = fFocalLen;
96 fResetBankAngle = fBankAng;
99 /*************************************************************************
101 |* ViewWindow setzen und PRP anpassen
103 \************************************************************************/
105 void Camera3D::SetViewWindow(double fX, double fY, double fW, double fH)
107 Viewport3D::SetViewWindow(fX, fY, fW, fH);
108 if ( bAutoAdjustProjection )
109 SetFocalLength(fFocalLength);
112 /*************************************************************************
114 |* Kameraposition setzen
116 \************************************************************************/
118 void Camera3D::SetPosition(const basegfx::B3DPoint& rNewPos)
120 if ( rNewPos != aPosition )
122 aPosition = rNewPos;
123 SetVRP(aPosition);
124 SetVPN(aPosition - aLookAt);
125 SetBankAngle(fBankAngle);
129 /*************************************************************************
131 |* Blickpunkt setzen
133 \************************************************************************/
135 void Camera3D::SetLookAt(const basegfx::B3DPoint& rNewLookAt)
137 if ( rNewLookAt != aLookAt )
139 aLookAt = rNewLookAt;
140 SetVPN(aPosition - aLookAt);
141 SetBankAngle(fBankAngle);
145 /*************************************************************************
147 |* Position und Blickpunkt setzen
149 \************************************************************************/
151 void Camera3D::SetPosAndLookAt(const basegfx::B3DPoint& rNewPos,
152 const basegfx::B3DPoint& rNewLookAt)
154 if ( rNewPos != aPosition || rNewLookAt != aLookAt )
156 aPosition = rNewPos;
157 aLookAt = rNewLookAt;
159 SetVRP(aPosition);
160 SetVPN(aPosition - aLookAt);
161 SetBankAngle(fBankAngle);
165 /*************************************************************************
167 |* seitlichen Neigungswinkel setzen
169 \************************************************************************/
171 void Camera3D::SetBankAngle(double fAngle)
173 basegfx::B3DVector aDiff(aPosition - aLookAt);
174 basegfx::B3DVector aPrj(aDiff);
175 fBankAngle = fAngle;
177 if ( aDiff.getY() == 0 )
179 aPrj.setY(-1.0);
181 else
182 { // aPrj = Projektion von aDiff auf die XZ-Ebene
183 aPrj.setY(0.0);
185 if ( aDiff.getY() < 0.0 )
187 aPrj = -aPrj;
191 // von aDiff nach oben zeigenden View-Up-Vektor berechnen
192 aPrj = aPrj.getPerpendicular(aDiff);
193 aPrj = aPrj.getPerpendicular(aDiff);
194 aDiff.normalize();
196 // auf Z-Achse rotieren, dort um BankAngle drehen und zurueck
197 basegfx::B3DHomMatrix aTf;
198 const double fV(sqrt(aDiff.getY() * aDiff.getY() + aDiff.getZ() * aDiff.getZ()));
200 if ( fV != 0.0 )
202 basegfx::B3DHomMatrix aTemp;
203 const double fSin(aDiff.getY() / fV);
204 const double fCos(aDiff.getZ() / fV);
206 aTemp.set(1, 1, fCos);
207 aTemp.set(2, 2, fCos);
208 aTemp.set(2, 1, fSin);
209 aTemp.set(1, 2, -fSin);
211 aTf *= aTemp;
215 basegfx::B3DHomMatrix aTemp;
216 const double fSin(-aDiff.getX());
217 const double fCos(fV);
219 aTemp.set(0, 0, fCos);
220 aTemp.set(2, 2, fCos);
221 aTemp.set(0, 2, fSin);
222 aTemp.set(2, 0, -fSin);
224 aTf *= aTemp;
227 aTf.rotate(0.0, 0.0, fBankAngle);
230 basegfx::B3DHomMatrix aTemp;
231 const double fSin(aDiff.getX());
232 const double fCos(fV);
234 aTemp.set(0, 0, fCos);
235 aTemp.set(2, 2, fCos);
236 aTemp.set(0, 2, fSin);
237 aTemp.set(2, 0, -fSin);
239 aTf *= aTemp;
242 if ( fV != 0.0 )
244 basegfx::B3DHomMatrix aTemp;
245 const double fSin(-aDiff.getY() / fV);
246 const double fCos(aDiff.getZ() / fV);
248 aTemp.set(1, 1, fCos);
249 aTemp.set(2, 2, fCos);
250 aTemp.set(2, 1, fSin);
251 aTemp.set(1, 2, -fSin);
253 aTf *= aTemp;
256 SetVUV(aTf * aPrj);
259 /*************************************************************************
261 |* Brennweite setzen
263 \************************************************************************/
265 void Camera3D::SetFocalLength(double fLen)
267 if ( fLen < 5 )
268 fLen = 5;
269 SetPRP(basegfx::B3DPoint(0.0, 0.0, fLen / 35.0 * aViewWin.W));
270 fFocalLength = fLen;
273 /*************************************************************************
275 |* Um die Kameraposition drehen, LookAt wird dabei veraendert
277 \************************************************************************/
279 void Camera3D::Rotate(double fHAngle, double fVAngle)
281 basegfx::B3DHomMatrix aTf;
282 basegfx::B3DVector aDiff(aLookAt - aPosition);
283 const double fV(sqrt(aDiff.getX() * aDiff.getX() + aDiff.getZ() * aDiff.getZ()));
285 if ( fV != 0.0 )
287 basegfx::B3DHomMatrix aTemp;
288 const double fSin(aDiff.getZ() / fV);
289 const double fCos(aDiff.getX() / fV);
291 aTemp.set(0, 0, fCos);
292 aTemp.set(2, 2, fCos);
293 aTemp.set(0, 2, fSin);
294 aTemp.set(2, 0, -fSin);
296 aTf *= aTemp;
300 aTf.rotate(0.0, 0.0, fVAngle);
303 if ( fV != 0.0 )
305 basegfx::B3DHomMatrix aTemp;
306 const double fSin(-aDiff.getZ() / fV);
307 const double fCos(aDiff.getX() / fV);
309 aTemp.set(0, 0, fCos);
310 aTemp.set(2, 2, fCos);
311 aTemp.set(0, 2, fSin);
312 aTemp.set(2, 0, -fSin);
314 aTf *= aTemp;
318 aTf.rotate(0.0, fHAngle, 0.0);
321 aDiff *= aTf;
322 SetLookAt(aPosition + aDiff);
326 /*************************************************************************
328 |* Um den Blickpunkt drehen, Position wird dabei veraendert
330 \************************************************************************/
332 void Camera3D::RotateAroundLookAt(double fHAngle, double fVAngle)
334 basegfx::B3DHomMatrix aTf;
335 basegfx::B3DVector aDiff(aPosition - aLookAt);
336 const double fV(sqrt(aDiff.getX() * aDiff.getX() + aDiff.getZ() * aDiff.getZ()));
338 if ( fV != 0.0 )
340 basegfx::B3DHomMatrix aTemp;
341 const double fSin(aDiff.getZ() / fV);
342 const double fCos(aDiff.getX() / fV);
344 aTemp.set(0, 0, fCos);
345 aTemp.set(2, 2, fCos);
346 aTemp.set(0, 2, fSin);
347 aTemp.set(2, 0, -fSin);
349 aTf *= aTemp;
353 aTf.rotate(0.0, 0.0, fVAngle);
356 if ( fV != 0.0 )
358 basegfx::B3DHomMatrix aTemp;
359 const double fSin(-aDiff.getZ() / fV);
360 const double fCos(aDiff.getX() / fV);
362 aTemp.set(0, 0, fCos);
363 aTemp.set(2, 2, fCos);
364 aTemp.set(0, 2, fSin);
365 aTemp.set(2, 0, -fSin);
367 aTf *= aTemp;
371 aTf.rotate(0.0, fHAngle, 0.0);
374 aDiff *= aTf;
375 SetPosition(aLookAt + aDiff);
378 /*************************************************************************
380 |* FG: ??? Setzt wohl die Projektionsebene in eine bestimmte Tiefe
382 \************************************************************************/
384 void Camera3D::SetFocalLengthWithCorrect(double fLen)
386 if ( fLen < 5.0 )
388 fLen = 5.0;
391 SetPRP(basegfx::B3DPoint(0.0, 0.0, aPRP.getZ() * fLen / fFocalLength));
392 fFocalLength = fLen;
395 // eof