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