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