Bump for 3.6-28
[LibreOffice.git] / drawinglayer / source / geometry / viewinformation3d.cxx
blob9ba9379dca5ecaeb991cbb7e29e7775988d358e2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <drawinglayer/geometry/viewinformation3d.hxx>
30 #include <basegfx/range/b3drange.hxx>
31 #include <basegfx/matrix/b3dhommatrix.hxx>
32 #include <com/sun/star/geometry/AffineMatrix3D.hpp>
33 #include <com/sun/star/geometry/RealRectangle3D.hpp>
34 #include <basegfx/tools/canvastools.hxx>
36 //////////////////////////////////////////////////////////////////////////////
38 using namespace com::sun::star;
40 //////////////////////////////////////////////////////////////////////////////
42 namespace drawinglayer
44 namespace geometry
46 /** Implementation class for ViewInformation3D
48 class ImpViewInformation3D
50 private:
51 // ViewInformation3D implementation can change refcount, so we have only
52 // two memory regions for pairs of ViewInformation3D/ImpViewInformation3D
53 friend class ::drawinglayer::geometry::ViewInformation3D;
55 // the refcounter. 0 means exclusively used
56 sal_uInt32 mnRefCount;
58 // the 3D transformations
59 // Object to World. This may change and being adapted when entering 3D transformation
60 // groups
61 basegfx::B3DHomMatrix maObjectTransformation;
63 // World to Camera. This includes VRP, VPN and VUV camera coordinate system
64 basegfx::B3DHomMatrix maOrientation;
66 // Camera to Device with X,Y and Z [-1.0 .. 1.0]. This is the
67 // 3D to 2D projection which may be parallell or perspective. When it is perspective,
68 // the last line of the homogen matrix will NOT be unused
69 basegfx::B3DHomMatrix maProjection;
71 // Device to View with X,Y and Z [0.0 .. 1.0]. This converts from -1 to 1 coordinates
72 // in camera coordinate system to 0 to 1 in unit 2D coordinates. This way it stays
73 // view-independent. To get discrete coordinates, the 2D transformation of a scene
74 // as 2D object needs to be involved
75 basegfx::B3DHomMatrix maDeviceToView;
77 // Object to View is the linear combination of all four transformations. It's
78 // buffered to avoid too much matrix multiplying and created on demand
79 basegfx::B3DHomMatrix maObjectToView;
81 // the point in time
82 double mfViewTime;
84 // the complete PropertyValue representation (if already created)
85 uno::Sequence< beans::PropertyValue > mxViewInformation;
87 // the extra PropertyValues; does not contain the transformations
88 uno::Sequence< beans::PropertyValue > mxExtendedInformation;
90 // the local UNO API strings
91 const ::rtl::OUString& getNamePropertyObjectTransformation()
93 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("ObjectTransformation"));
94 return s_sNameProperty;
97 const ::rtl::OUString& getNamePropertyOrientation()
99 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Orientation"));
100 return s_sNameProperty;
103 const ::rtl::OUString& getNamePropertyProjection()
105 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection"));
106 return s_sNameProperty;
109 const ::rtl::OUString& getNamePropertyProjection_30()
111 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection30"));
112 return s_sNameProperty;
115 const ::rtl::OUString& getNamePropertyProjection_31()
117 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection31"));
118 return s_sNameProperty;
121 const ::rtl::OUString& getNamePropertyProjection_32()
123 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection32"));
124 return s_sNameProperty;
127 const ::rtl::OUString& getNamePropertyProjection_33()
129 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection33"));
130 return s_sNameProperty;
133 const ::rtl::OUString& getNamePropertyDeviceToView()
135 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("DeviceToView"));
136 return s_sNameProperty;
139 const ::rtl::OUString& getNamePropertyTime()
141 static ::rtl::OUString s_sNamePropertyTime(RTL_CONSTASCII_USTRINGPARAM("Time"));
142 return s_sNamePropertyTime;
145 // a central PropertyValue parsing method to allow transportatin of
146 // all ViewParameters using UNO API
147 void impInterpretPropertyValues(const uno::Sequence< beans::PropertyValue >& rViewParameters)
149 if(rViewParameters.hasElements())
151 const sal_Int32 nCount(rViewParameters.getLength());
152 sal_Int32 nExtendedInsert(0);
154 // prepare extended information for filtering. Maximum size is nCount
155 mxExtendedInformation.realloc(nCount);
157 for(sal_Int32 a(0); a < nCount; a++)
159 const beans::PropertyValue& rProp = rViewParameters[a];
161 if(rProp.Name == getNamePropertyObjectTransformation())
163 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
164 rProp.Value >>= aAffineMatrix3D;
165 maObjectTransformation = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
167 else if(rProp.Name == getNamePropertyOrientation())
169 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
170 rProp.Value >>= aAffineMatrix3D;
171 maOrientation = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
173 else if(rProp.Name == getNamePropertyProjection())
175 // projection may be defined using a frustum in which case the last line of
176 // the 4x4 matrix is not (0,0,0,1). Since AffineMatrix3D does not support that,
177 // these four values need to be treated extra
178 const double f_30(maProjection.get(3, 0));
179 const double f_31(maProjection.get(3, 1));
180 const double f_32(maProjection.get(3, 2));
181 const double f_33(maProjection.get(3, 3));
183 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
184 rProp.Value >>= aAffineMatrix3D;
185 maProjection = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
187 maProjection.set(3, 0, f_30);
188 maProjection.set(3, 1, f_31);
189 maProjection.set(3, 2, f_32);
190 maProjection.set(3, 3, f_33);
192 else if(rProp.Name == getNamePropertyProjection_30())
194 double f_30(0.0);
195 rProp.Value >>= f_30;
196 maProjection.set(3, 0, f_30);
198 else if(rProp.Name == getNamePropertyProjection_31())
200 double f_31(0.0);
201 rProp.Value >>= f_31;
202 maProjection.set(3, 1, f_31);
204 else if(rProp.Name == getNamePropertyProjection_32())
206 double f_32(0.0);
207 rProp.Value >>= f_32;
208 maProjection.set(3, 2, f_32);
210 else if(rProp.Name == getNamePropertyProjection_33())
212 double f_33(1.0);
213 rProp.Value >>= f_33;
214 maProjection.set(3, 3, f_33);
216 else if(rProp.Name == getNamePropertyDeviceToView())
218 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
219 rProp.Value >>= aAffineMatrix3D;
220 maDeviceToView = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
222 else if(rProp.Name == getNamePropertyTime())
224 rProp.Value >>= mfViewTime;
226 else
228 // extra information; add to filtered information
229 mxExtendedInformation[nExtendedInsert++] = rProp;
233 // extra information size is now known; realloc to final size
234 mxExtendedInformation.realloc(nExtendedInsert);
238 // central method to create a Sequence of PropertyValues containing he complete
239 // data set
240 void impFillViewInformationFromContent()
242 uno::Sequence< beans::PropertyValue > xRetval;
243 const bool bObjectTransformationUsed(!maObjectTransformation.isIdentity());
244 const bool bOrientationUsed(!maOrientation.isIdentity());
245 const bool bProjectionUsed(!maProjection.isIdentity());
246 const bool bDeviceToViewUsed(!maDeviceToView.isIdentity());
247 const bool bTimeUsed(0.0 < mfViewTime);
248 const bool bExtraInformation(mxExtendedInformation.hasElements());
250 // projection may be defined using a frustum in which case the last line of
251 // the 4x4 matrix is not (0,0,0,1). Since AffineMatrix3D does not support that,
252 // these four values need to be treated extra
253 const bool bProjectionUsed_30(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 0)));
254 const bool bProjectionUsed_31(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 1)));
255 const bool bProjectionUsed_32(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 2)));
256 const bool bProjectionUsed_33(bProjectionUsed && !basegfx::fTools::equal(maProjection.get(3, 3), 1.0));
258 sal_uInt32 nIndex(0);
259 const sal_uInt32 nCount(
260 (bObjectTransformationUsed ? 1 : 0) +
261 (bOrientationUsed ? 1 : 0) +
262 (bProjectionUsed ? 1 : 0) +
263 (bProjectionUsed_30 ? 1 : 0) +
264 (bProjectionUsed_31 ? 1 : 0) +
265 (bProjectionUsed_32 ? 1 : 0) +
266 (bProjectionUsed_33 ? 1 : 0) +
267 (bDeviceToViewUsed ? 1 : 0) +
268 (bTimeUsed ? 1 : 0) +
269 (bExtraInformation ? mxExtendedInformation.getLength() : 0));
271 mxViewInformation.realloc(nCount);
273 if(bObjectTransformationUsed)
275 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
276 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maObjectTransformation);
277 mxViewInformation[nIndex].Name = getNamePropertyObjectTransformation();
278 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
279 nIndex++;
282 if(bOrientationUsed)
284 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
285 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maOrientation);
286 mxViewInformation[nIndex].Name = getNamePropertyOrientation();
287 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
288 nIndex++;
291 if(bProjectionUsed)
293 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
294 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maProjection);
295 mxViewInformation[nIndex].Name = getNamePropertyProjection();
296 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
297 nIndex++;
300 if(bProjectionUsed_30)
302 mxViewInformation[nIndex].Name = getNamePropertyProjection_30();
303 mxViewInformation[nIndex].Value <<= maProjection.get(3, 0);
304 nIndex++;
307 if(bProjectionUsed_31)
309 mxViewInformation[nIndex].Name = getNamePropertyProjection_31();
310 mxViewInformation[nIndex].Value <<= maProjection.get(3, 1);
311 nIndex++;
314 if(bProjectionUsed_32)
316 mxViewInformation[nIndex].Name = getNamePropertyProjection_32();
317 mxViewInformation[nIndex].Value <<= maProjection.get(3, 2);
318 nIndex++;
321 if(bProjectionUsed_33)
323 mxViewInformation[nIndex].Name = getNamePropertyProjection_33();
324 mxViewInformation[nIndex].Value <<= maProjection.get(3, 3);
325 nIndex++;
328 if(bDeviceToViewUsed)
330 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
331 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maDeviceToView);
332 mxViewInformation[nIndex].Name = getNamePropertyDeviceToView();
333 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
334 nIndex++;
337 if(bTimeUsed)
339 mxViewInformation[nIndex].Name = getNamePropertyTime();
340 mxViewInformation[nIndex].Value <<= mfViewTime;
341 nIndex++;
344 if(bExtraInformation)
346 const sal_Int32 nExtra(mxExtendedInformation.getLength());
348 for(sal_Int32 a(0); a < nExtra; a++)
350 mxViewInformation[nIndex++] = mxExtendedInformation[a];
355 public:
356 ImpViewInformation3D(
357 const basegfx::B3DHomMatrix& rObjectTransformation,
358 const basegfx::B3DHomMatrix& rOrientation,
359 const basegfx::B3DHomMatrix& rProjection,
360 const basegfx::B3DHomMatrix& rDeviceToView,
361 double fViewTime,
362 const uno::Sequence< beans::PropertyValue >& rExtendedParameters)
363 : mnRefCount(0),
364 maObjectTransformation(rObjectTransformation),
365 maOrientation(rOrientation),
366 maProjection(rProjection),
367 maDeviceToView(rDeviceToView),
368 mfViewTime(fViewTime),
369 mxViewInformation(),
370 mxExtendedInformation()
372 impInterpretPropertyValues(rExtendedParameters);
375 ImpViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters)
376 : mnRefCount(0),
377 maObjectTransformation(),
378 maOrientation(),
379 maProjection(),
380 maDeviceToView(),
381 mfViewTime(),
382 mxViewInformation(rViewParameters),
383 mxExtendedInformation()
385 impInterpretPropertyValues(rViewParameters);
388 ImpViewInformation3D()
389 : mnRefCount(0),
390 maObjectTransformation(),
391 maOrientation(),
392 maProjection(),
393 maDeviceToView(),
394 mfViewTime(),
395 mxViewInformation(),
396 mxExtendedInformation()
400 const basegfx::B3DHomMatrix& getObjectTransformation() const { return maObjectTransformation; }
401 const basegfx::B3DHomMatrix& getOrientation() const { return maOrientation; }
402 const basegfx::B3DHomMatrix& getProjection() const { return maProjection; }
403 const basegfx::B3DHomMatrix& getDeviceToView() const { return maDeviceToView; }
404 double getViewTime() const { return mfViewTime; }
406 const basegfx::B3DHomMatrix& getObjectToView() const
408 // on demand WorldToView creation
409 ::osl::Mutex m_mutex;
411 if(maObjectToView.isIdentity())
413 const_cast< ImpViewInformation3D* >(this)->maObjectToView = maDeviceToView * maProjection * maOrientation * maObjectTransformation;
416 return maObjectToView;
419 const uno::Sequence< beans::PropertyValue >& getViewInformationSequence() const
421 ::osl::Mutex m_mutex;
423 if(!mxViewInformation.hasElements())
425 const_cast< ImpViewInformation3D* >(this)->impFillViewInformationFromContent();
428 return mxViewInformation;
431 const uno::Sequence< beans::PropertyValue >& getExtendedInformationSequence() const
433 return mxExtendedInformation;
436 bool operator==(const ImpViewInformation3D& rCandidate) const
438 return (maObjectTransformation == rCandidate.maObjectTransformation
439 && maOrientation == rCandidate.maOrientation
440 && maProjection == rCandidate.maProjection
441 && maDeviceToView == rCandidate.maDeviceToView
442 && mfViewTime == rCandidate.mfViewTime
443 && mxExtendedInformation == rCandidate.mxExtendedInformation);
446 static ImpViewInformation3D* get_global_default()
448 static ImpViewInformation3D* pDefault = 0;
450 if(!pDefault)
452 pDefault = new ImpViewInformation3D();
454 // never delete; start with RefCount 1, not 0
455 pDefault->mnRefCount++;
458 return pDefault;
461 } // end of anonymous namespace
462 } // end of namespace drawinglayer
464 //////////////////////////////////////////////////////////////////////////////
466 namespace drawinglayer
468 namespace geometry
470 ViewInformation3D::ViewInformation3D(
471 const basegfx::B3DHomMatrix& rObjectObjectTransformation,
472 const basegfx::B3DHomMatrix& rOrientation,
473 const basegfx::B3DHomMatrix& rProjection,
474 const basegfx::B3DHomMatrix& rDeviceToView,
475 double fViewTime,
476 const uno::Sequence< beans::PropertyValue >& rExtendedParameters)
477 : mpViewInformation3D(new ImpViewInformation3D(
478 rObjectObjectTransformation, rOrientation, rProjection,
479 rDeviceToView, fViewTime, rExtendedParameters))
483 ViewInformation3D::ViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters)
484 : mpViewInformation3D(new ImpViewInformation3D(rViewParameters))
488 ViewInformation3D::ViewInformation3D()
489 : mpViewInformation3D(ImpViewInformation3D::get_global_default())
491 mpViewInformation3D->mnRefCount++;
494 ViewInformation3D::ViewInformation3D(const ViewInformation3D& rCandidate)
495 : mpViewInformation3D(rCandidate.mpViewInformation3D)
497 ::osl::Mutex m_mutex;
498 mpViewInformation3D->mnRefCount++;
501 ViewInformation3D::~ViewInformation3D()
503 ::osl::Mutex m_mutex;
505 if(mpViewInformation3D->mnRefCount)
507 mpViewInformation3D->mnRefCount--;
509 else
511 delete mpViewInformation3D;
515 bool ViewInformation3D::isDefault() const
517 return mpViewInformation3D == ImpViewInformation3D::get_global_default();
520 ViewInformation3D& ViewInformation3D::operator=(const ViewInformation3D& rCandidate)
522 ::osl::Mutex m_mutex;
524 if(mpViewInformation3D->mnRefCount)
526 mpViewInformation3D->mnRefCount--;
528 else
530 delete mpViewInformation3D;
533 mpViewInformation3D = rCandidate.mpViewInformation3D;
534 mpViewInformation3D->mnRefCount++;
536 return *this;
539 bool ViewInformation3D::operator==(const ViewInformation3D& rCandidate) const
541 if(rCandidate.mpViewInformation3D == mpViewInformation3D)
543 return true;
546 if(rCandidate.isDefault() != isDefault())
548 return false;
551 return (*rCandidate.mpViewInformation3D == *mpViewInformation3D);
554 const basegfx::B3DHomMatrix& ViewInformation3D::getObjectTransformation() const
556 return mpViewInformation3D->getObjectTransformation();
559 const basegfx::B3DHomMatrix& ViewInformation3D::getOrientation() const
561 return mpViewInformation3D->getOrientation();
564 const basegfx::B3DHomMatrix& ViewInformation3D::getProjection() const
566 return mpViewInformation3D->getProjection();
569 const basegfx::B3DHomMatrix& ViewInformation3D::getDeviceToView() const
571 return mpViewInformation3D->getDeviceToView();
574 const basegfx::B3DHomMatrix& ViewInformation3D::getObjectToView() const
576 return mpViewInformation3D->getObjectToView();
579 double ViewInformation3D::getViewTime() const
581 return mpViewInformation3D->getViewTime();
584 const uno::Sequence< beans::PropertyValue >& ViewInformation3D::getViewInformationSequence() const
586 return mpViewInformation3D->getViewInformationSequence();
589 const uno::Sequence< beans::PropertyValue >& ViewInformation3D::getExtendedInformationSequence() const
591 return mpViewInformation3D->getExtendedInformationSequence();
593 } // end of namespace geometry
594 } // end of namespace drawinglayer
596 //////////////////////////////////////////////////////////////////////////////
597 // eof
599 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */