xref: /AOO41X/main/svx/source/engine3d/camera3d.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
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/camera3d.hxx>
27 #include <tools/stream.hxx>
28 
29 /*************************************************************************
30 |*
31 |* Konstruktor
32 |*
33 \************************************************************************/
34 
Camera3D(const basegfx::B3DPoint & rPos,const basegfx::B3DPoint & rLookAt,double fFocalLen,double fBankAng)35 Camera3D::Camera3D(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt,
36                    double fFocalLen, double fBankAng) :
37     aResetPos(rPos),
38     aResetLookAt(rLookAt),
39     fResetFocalLength(fFocalLen),
40     fResetBankAngle(fBankAng),
41     fBankAngle(fBankAng),
42     bAutoAdjustProjection(sal_True)
43 {
44     SetVPD(0);
45     SetPosition(rPos);
46     SetLookAt(rLookAt);
47     SetFocalLength(fFocalLen);
48 }
49 
50 /*************************************************************************
51 |*
52 |* Default-Konstruktor
53 |*
54 \************************************************************************/
55 
Camera3D()56 Camera3D::Camera3D()
57 {
58     basegfx::B3DPoint aVector3D(0.0 ,0.0 ,1.0);
59     Camera3D(aVector3D, basegfx::B3DPoint());
60 }
61 
62 /*************************************************************************
63 |*
64 |* Konstruktor
65 |*
66 \************************************************************************/
67 
Reset()68 void Camera3D::Reset()
69 {
70     SetVPD(0);
71     fBankAngle = fResetBankAngle;
72     SetPosition(aResetPos);
73     SetLookAt(aResetLookAt);
74     SetFocalLength(fResetFocalLength);
75 }
76 
77 /*************************************************************************
78 |*
79 |* Defaultwerte fuer Reset setzen
80 |*
81 \************************************************************************/
82 
SetDefaults(const basegfx::B3DPoint & rPos,const basegfx::B3DPoint & rLookAt,double fFocalLen,double fBankAng)83 void Camera3D::SetDefaults(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt,
84                             double fFocalLen, double fBankAng)
85 {
86     aResetPos           = rPos;
87     aResetLookAt        = rLookAt;
88     fResetFocalLength   = fFocalLen;
89     fResetBankAngle     = fBankAng;
90 }
91 
92 /*************************************************************************
93 |*
94 |* ViewWindow setzen und PRP anpassen
95 |*
96 \************************************************************************/
97 
SetViewWindow(double fX,double fY,double fW,double fH)98 void Camera3D::SetViewWindow(double fX, double fY, double fW, double fH)
99 {
100     Viewport3D::SetViewWindow(fX, fY, fW, fH);
101     if ( bAutoAdjustProjection )
102         SetFocalLength(fFocalLength);
103 }
104 
105 /*************************************************************************
106 |*
107 |* Kameraposition setzen
108 |*
109 \************************************************************************/
110 
SetPosition(const basegfx::B3DPoint & rNewPos)111 void Camera3D::SetPosition(const basegfx::B3DPoint& rNewPos)
112 {
113     if ( rNewPos != aPosition )
114     {
115         aPosition = rNewPos;
116         SetVRP(aPosition);
117         SetVPN(aPosition - aLookAt);
118         SetBankAngle(fBankAngle);
119     }
120 }
121 
122 /*************************************************************************
123 |*
124 |* Blickpunkt setzen
125 |*
126 \************************************************************************/
127 
SetLookAt(const basegfx::B3DPoint & rNewLookAt)128 void Camera3D::SetLookAt(const basegfx::B3DPoint& rNewLookAt)
129 {
130     if ( rNewLookAt != aLookAt )
131     {
132         aLookAt = rNewLookAt;
133         SetVPN(aPosition - aLookAt);
134         SetBankAngle(fBankAngle);
135     }
136 }
137 
138 /*************************************************************************
139 |*
140 |* Position und Blickpunkt setzen
141 |*
142 \************************************************************************/
143 
SetPosAndLookAt(const basegfx::B3DPoint & rNewPos,const basegfx::B3DPoint & rNewLookAt)144 void Camera3D::SetPosAndLookAt(const basegfx::B3DPoint& rNewPos,
145                                const basegfx::B3DPoint& rNewLookAt)
146 {
147     if ( rNewPos != aPosition || rNewLookAt != aLookAt )
148     {
149         aPosition = rNewPos;
150         aLookAt = rNewLookAt;
151 
152         SetVRP(aPosition);
153         SetVPN(aPosition - aLookAt);
154         SetBankAngle(fBankAngle);
155     }
156 }
157 
158 /*************************************************************************
159 |*
160 |* seitlichen Neigungswinkel setzen
161 |*
162 \************************************************************************/
163 
SetBankAngle(double fAngle)164 void Camera3D::SetBankAngle(double fAngle)
165 {
166     basegfx::B3DVector aDiff(aPosition - aLookAt);
167     basegfx::B3DVector aPrj(aDiff);
168     fBankAngle = fAngle;
169 
170     if ( aDiff.getY() == 0 )
171     {
172         aPrj.setY(-1.0);
173     }
174     else
175     {   // aPrj = Projektion von aDiff auf die XZ-Ebene
176         aPrj.setY(0.0);
177 
178         if ( aDiff.getY() < 0.0 )
179         {
180             aPrj = -aPrj;
181         }
182     }
183 
184     // von aDiff nach oben zeigenden View-Up-Vektor berechnen
185     aPrj = aPrj.getPerpendicular(aDiff);
186     aPrj = aPrj.getPerpendicular(aDiff);
187     aDiff.normalize();
188 
189     // auf Z-Achse rotieren, dort um BankAngle drehen und zurueck
190     basegfx::B3DHomMatrix aTf;
191     const double fV(sqrt(aDiff.getY() * aDiff.getY() + aDiff.getZ() * aDiff.getZ()));
192 
193     if ( fV != 0.0 )
194     {
195         basegfx::B3DHomMatrix aTemp;
196         const double fSin(aDiff.getY() / fV);
197         const double fCos(aDiff.getZ() / fV);
198 
199         aTemp.set(1, 1, fCos);
200         aTemp.set(2, 2, fCos);
201         aTemp.set(2, 1, fSin);
202         aTemp.set(1, 2, -fSin);
203 
204         aTf *= aTemp;
205     }
206 
207     {
208         basegfx::B3DHomMatrix aTemp;
209         const double fSin(-aDiff.getX());
210         const double fCos(fV);
211 
212         aTemp.set(0, 0, fCos);
213         aTemp.set(2, 2, fCos);
214         aTemp.set(0, 2, fSin);
215         aTemp.set(2, 0, -fSin);
216 
217         aTf *= aTemp;
218     }
219 
220     aTf.rotate(0.0, 0.0, fBankAngle);
221 
222     {
223         basegfx::B3DHomMatrix aTemp;
224         const double fSin(aDiff.getX());
225         const double fCos(fV);
226 
227         aTemp.set(0, 0, fCos);
228         aTemp.set(2, 2, fCos);
229         aTemp.set(0, 2, fSin);
230         aTemp.set(2, 0, -fSin);
231 
232         aTf *= aTemp;
233     }
234 
235     if ( fV != 0.0 )
236     {
237         basegfx::B3DHomMatrix aTemp;
238         const double fSin(-aDiff.getY() / fV);
239         const double fCos(aDiff.getZ() / fV);
240 
241         aTemp.set(1, 1, fCos);
242         aTemp.set(2, 2, fCos);
243         aTemp.set(2, 1, fSin);
244         aTemp.set(1, 2, -fSin);
245 
246         aTf *= aTemp;
247     }
248 
249     SetVUV(aTf * aPrj);
250 }
251 
252 /*************************************************************************
253 |*
254 |* Brennweite setzen
255 |*
256 \************************************************************************/
257 
SetFocalLength(double fLen)258 void Camera3D::SetFocalLength(double fLen)
259 {
260     if ( fLen < 5 )
261         fLen = 5;
262     SetPRP(basegfx::B3DPoint(0.0, 0.0, fLen / 35.0 * aViewWin.W));
263     fFocalLength = fLen;
264 }
265 
266 /*************************************************************************
267 |*
268 |* Um die Kameraposition drehen, LookAt wird dabei veraendert
269 |*
270 \************************************************************************/
271 
Rotate(double fHAngle,double fVAngle)272 void Camera3D::Rotate(double fHAngle, double fVAngle)
273 {
274     basegfx::B3DHomMatrix aTf;
275     basegfx::B3DVector aDiff(aLookAt - aPosition);
276     const double fV(sqrt(aDiff.getX() * aDiff.getX() + aDiff.getZ() * aDiff.getZ()));
277 
278     if ( fV != 0.0 )
279     {
280         basegfx::B3DHomMatrix aTemp;
281         const double fSin(aDiff.getZ() / fV);
282         const double fCos(aDiff.getX() / fV);
283 
284         aTemp.set(0, 0, fCos);
285         aTemp.set(2, 2, fCos);
286         aTemp.set(0, 2, fSin);
287         aTemp.set(2, 0, -fSin);
288 
289         aTf *= aTemp;
290     }
291 
292     {
293         aTf.rotate(0.0, 0.0, fVAngle);
294     }
295 
296     if ( fV != 0.0 )
297     {
298         basegfx::B3DHomMatrix aTemp;
299         const double fSin(-aDiff.getZ() / fV);
300         const double fCos(aDiff.getX() / fV);
301 
302         aTemp.set(0, 0, fCos);
303         aTemp.set(2, 2, fCos);
304         aTemp.set(0, 2, fSin);
305         aTemp.set(2, 0, -fSin);
306 
307         aTf *= aTemp;
308     }
309 
310     {
311         aTf.rotate(0.0, fHAngle, 0.0);
312     }
313 
314     aDiff *= aTf;
315     SetLookAt(aPosition + aDiff);
316 }
317 
318 
319 /*************************************************************************
320 |*
321 |* Um den Blickpunkt drehen, Position wird dabei veraendert
322 |*
323 \************************************************************************/
324 
RotateAroundLookAt(double fHAngle,double fVAngle)325 void Camera3D::RotateAroundLookAt(double fHAngle, double fVAngle)
326 {
327     basegfx::B3DHomMatrix aTf;
328     basegfx::B3DVector aDiff(aPosition - aLookAt);
329     const double fV(sqrt(aDiff.getX() * aDiff.getX() + aDiff.getZ() * aDiff.getZ()));
330 
331     if ( fV != 0.0 )
332     {
333         basegfx::B3DHomMatrix aTemp;
334         const double fSin(aDiff.getZ() / fV);
335         const double fCos(aDiff.getX() / fV);
336 
337         aTemp.set(0, 0, fCos);
338         aTemp.set(2, 2, fCos);
339         aTemp.set(0, 2, fSin);
340         aTemp.set(2, 0, -fSin);
341 
342         aTf *= aTemp;
343     }
344 
345     {
346         aTf.rotate(0.0, 0.0, fVAngle);
347     }
348 
349     if ( fV != 0.0 )
350     {
351         basegfx::B3DHomMatrix aTemp;
352         const double fSin(-aDiff.getZ() / fV);
353         const double fCos(aDiff.getX() / fV);
354 
355         aTemp.set(0, 0, fCos);
356         aTemp.set(2, 2, fCos);
357         aTemp.set(0, 2, fSin);
358         aTemp.set(2, 0, -fSin);
359 
360         aTf *= aTemp;
361     }
362 
363     {
364         aTf.rotate(0.0, fHAngle, 0.0);
365     }
366 
367     aDiff *= aTf;
368     SetPosition(aLookAt + aDiff);
369 }
370 
371 /*************************************************************************
372 |*
373 |* FG: ??? Setzt wohl die Projektionsebene in eine bestimmte Tiefe
374 |*
375 \************************************************************************/
376 
SetFocalLengthWithCorrect(double fLen)377 void Camera3D::SetFocalLengthWithCorrect(double fLen)
378 {
379     if ( fLen < 5.0 )
380     {
381         fLen = 5.0;
382     }
383 
384     SetPRP(basegfx::B3DPoint(0.0, 0.0, aPRP.getZ() * fLen / fFocalLength));
385     fFocalLength = fLen;
386 }
387 
388 // eof
389