merge the formfield patch from ooo-build
[ooovba.git] / drawinglayer / source / geometry / viewinformation3d.cxx
blob8925fb3bb66a8036e85dbed68df0898aa8978058
1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: viewinformation3d.cxx,v $
7 * $Revision: 1.2 $
9 * last change: $Author: aw $ $Date: 2008-06-24 15:31:07 $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2005 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * MA 02111-1307 USA
34 ************************************************************************/
36 // MARKER(update_precomp.py): autogen include statement, do not remove
37 #include "precompiled_drawinglayer.hxx"
39 #include <drawinglayer/geometry/viewinformation3d.hxx>
40 #include <basegfx/range/b3drange.hxx>
41 #include <basegfx/matrix/b3dhommatrix.hxx>
42 #include <com/sun/star/geometry/AffineMatrix3D.hpp>
43 #include <com/sun/star/geometry/RealRectangle3D.hpp>
44 #include <basegfx/tools/canvastools.hxx>
46 //////////////////////////////////////////////////////////////////////////////
48 using namespace com::sun::star;
50 //////////////////////////////////////////////////////////////////////////////
52 namespace drawinglayer
54 namespace geometry
56 /** Implementation class for ViewInformation3D
58 class ImpViewInformation3D
60 private:
61 // ViewInformation3D implementation can change refcount, so we have only
62 // two memory regions for pairs of ViewInformation3D/ImpViewInformation3D
63 friend class ::drawinglayer::geometry::ViewInformation3D;
65 // the refcounter. 0 means exclusively used
66 sal_uInt32 mnRefCount;
68 // the 3D transformations
69 // Object to World. This may change and being adapted when entering 3D transformation
70 // groups
71 basegfx::B3DHomMatrix maObjectTransformation;
73 // World to Camera. This includes VRP, VPN and VUV camera coordinate system
74 basegfx::B3DHomMatrix maOrientation;
76 // Camera to Device with X,Y and Z [-1.0 .. 1.0]. This is the
77 // 3D to 2D projection which may be parallell or perspective. When it is perspective,
78 // the last line of the homogen matrix will NOT be unused
79 basegfx::B3DHomMatrix maProjection;
81 // Device to View with X,Y and Z [0.0 .. 1.0]. This converts from -1 to 1 coordinates
82 // in camera coordinate system to 0 to 1 in unit 2D coordinates. This way it stays
83 // view-independent. To get discrete coordinates, the 2D transformation of a scene
84 // as 2D object needs to be involved
85 basegfx::B3DHomMatrix maDeviceToView;
87 // Object to View is the linear combination of all four transformations. It's
88 // buffered to avoid too much matrix multiplying and created on demand
89 basegfx::B3DHomMatrix maObjectToView;
91 // the point in time
92 double mfViewTime;
94 // the complete PropertyValue representation (if already created)
95 uno::Sequence< beans::PropertyValue > mxViewInformation;
97 // the extra PropertyValues; does not contain the transformations
98 uno::Sequence< beans::PropertyValue > mxExtendedInformation;
100 // the local UNO API strings
101 const ::rtl::OUString& getNamePropertyObjectTransformation()
103 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("ObjectTransformation"));
104 return s_sNameProperty;
107 const ::rtl::OUString& getNamePropertyOrientation()
109 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Orientation"));
110 return s_sNameProperty;
113 const ::rtl::OUString& getNamePropertyProjection()
115 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection"));
116 return s_sNameProperty;
119 const ::rtl::OUString& getNamePropertyProjection_30()
121 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection30"));
122 return s_sNameProperty;
125 const ::rtl::OUString& getNamePropertyProjection_31()
127 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection31"));
128 return s_sNameProperty;
131 const ::rtl::OUString& getNamePropertyProjection_32()
133 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection32"));
134 return s_sNameProperty;
137 const ::rtl::OUString& getNamePropertyProjection_33()
139 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Projection33"));
140 return s_sNameProperty;
143 const ::rtl::OUString& getNamePropertyDeviceToView()
145 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("DeviceToView"));
146 return s_sNameProperty;
149 const ::rtl::OUString& getNamePropertyTime()
151 static ::rtl::OUString s_sNamePropertyTime(RTL_CONSTASCII_USTRINGPARAM("Time"));
152 return s_sNamePropertyTime;
155 // a central PropertyValue parsing method to allow transportatin of
156 // all ViewParameters using UNO API
157 void impInterpretPropertyValues(const uno::Sequence< beans::PropertyValue >& rViewParameters)
159 if(rViewParameters.hasElements())
161 const sal_Int32 nCount(rViewParameters.getLength());
162 sal_Int32 nExtendedInsert(0);
164 // prepare extended information for filtering. Maximum size is nCount
165 mxExtendedInformation.realloc(nCount);
167 for(sal_Int32 a(0); a < nCount; a++)
169 const beans::PropertyValue& rProp = rViewParameters[a];
171 if(rProp.Name == getNamePropertyObjectTransformation())
173 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
174 rProp.Value >>= aAffineMatrix3D;
175 maObjectTransformation = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
177 else if(rProp.Name == getNamePropertyOrientation())
179 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
180 rProp.Value >>= aAffineMatrix3D;
181 maOrientation = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
183 else if(rProp.Name == getNamePropertyProjection())
185 // projection may be defined using a frustum in which case the last line of
186 // the 4x4 matrix is not (0,0,0,1). Since AffineMatrix3D does not support that,
187 // these four values need to be treated extra
188 const double f_30(maProjection.get(3, 0));
189 const double f_31(maProjection.get(3, 1));
190 const double f_32(maProjection.get(3, 2));
191 const double f_33(maProjection.get(3, 3));
193 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
194 rProp.Value >>= aAffineMatrix3D;
195 maProjection = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
197 maProjection.set(3, 0, f_30);
198 maProjection.set(3, 1, f_31);
199 maProjection.set(3, 2, f_32);
200 maProjection.set(3, 3, f_33);
202 else if(rProp.Name == getNamePropertyProjection_30())
204 double f_30(0.0);
205 rProp.Value >>= f_30;
206 maProjection.set(3, 0, f_30);
208 else if(rProp.Name == getNamePropertyProjection_31())
210 double f_31(0.0);
211 rProp.Value >>= f_31;
212 maProjection.set(3, 1, f_31);
214 else if(rProp.Name == getNamePropertyProjection_32())
216 double f_32(0.0);
217 rProp.Value >>= f_32;
218 maProjection.set(3, 2, f_32);
220 else if(rProp.Name == getNamePropertyProjection_33())
222 double f_33(1.0);
223 rProp.Value >>= f_33;
224 maProjection.set(3, 3, f_33);
226 else if(rProp.Name == getNamePropertyDeviceToView())
228 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
229 rProp.Value >>= aAffineMatrix3D;
230 maDeviceToView = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
232 else if(rProp.Name == getNamePropertyTime())
234 rProp.Value >>= mfViewTime;
236 else
238 // extra information; add to filtered information
239 mxExtendedInformation[nExtendedInsert++] = rProp;
243 // extra information size is now known; realloc to final size
244 mxExtendedInformation.realloc(nExtendedInsert);
248 // central method to create a Sequence of PropertyValues containing he complete
249 // data set
250 void impFillViewInformationFromContent()
252 uno::Sequence< beans::PropertyValue > xRetval;
253 const bool bObjectTransformationUsed(!maObjectTransformation.isIdentity());
254 const bool bOrientationUsed(!maOrientation.isIdentity());
255 const bool bProjectionUsed(!maProjection.isIdentity());
256 const bool bDeviceToViewUsed(!maDeviceToView.isIdentity());
257 const bool bTimeUsed(0.0 < mfViewTime);
258 const bool bExtraInformation(mxExtendedInformation.hasElements());
260 // projection may be defined using a frustum in which case the last line of
261 // the 4x4 matrix is not (0,0,0,1). Since AffineMatrix3D does not support that,
262 // these four values need to be treated extra
263 const bool bProjectionUsed_30(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 0)));
264 const bool bProjectionUsed_31(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 1)));
265 const bool bProjectionUsed_32(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 2)));
266 const bool bProjectionUsed_33(bProjectionUsed && !basegfx::fTools::equal(maProjection.get(3, 3), 1.0));
268 sal_uInt32 nIndex(0);
269 const sal_uInt32 nCount(
270 (bObjectTransformationUsed ? 1 : 0) +
271 (bOrientationUsed ? 1 : 0) +
272 (bProjectionUsed ? 1 : 0) +
273 (bProjectionUsed_30 ? 1 : 0) +
274 (bProjectionUsed_31 ? 1 : 0) +
275 (bProjectionUsed_32 ? 1 : 0) +
276 (bProjectionUsed_33 ? 1 : 0) +
277 (bDeviceToViewUsed ? 1 : 0) +
278 (bTimeUsed ? 1 : 0) +
279 (bExtraInformation ? mxExtendedInformation.getLength() : 0));
281 mxViewInformation.realloc(nCount);
283 if(bObjectTransformationUsed)
285 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
286 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maObjectTransformation);
287 mxViewInformation[nIndex].Name = getNamePropertyObjectTransformation();
288 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
289 nIndex++;
292 if(bOrientationUsed)
294 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
295 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maOrientation);
296 mxViewInformation[nIndex].Name = getNamePropertyOrientation();
297 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
298 nIndex++;
301 if(bProjectionUsed)
303 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
304 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maProjection);
305 mxViewInformation[nIndex].Name = getNamePropertyProjection();
306 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
307 nIndex++;
310 if(bProjectionUsed_30)
312 mxViewInformation[nIndex].Name = getNamePropertyProjection_30();
313 mxViewInformation[nIndex].Value <<= maProjection.get(3, 0);
314 nIndex++;
317 if(bProjectionUsed_31)
319 mxViewInformation[nIndex].Name = getNamePropertyProjection_31();
320 mxViewInformation[nIndex].Value <<= maProjection.get(3, 1);
321 nIndex++;
324 if(bProjectionUsed_32)
326 mxViewInformation[nIndex].Name = getNamePropertyProjection_32();
327 mxViewInformation[nIndex].Value <<= maProjection.get(3, 2);
328 nIndex++;
331 if(bProjectionUsed_33)
333 mxViewInformation[nIndex].Name = getNamePropertyProjection_33();
334 mxViewInformation[nIndex].Value <<= maProjection.get(3, 3);
335 nIndex++;
338 if(bDeviceToViewUsed)
340 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D;
341 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maDeviceToView);
342 mxViewInformation[nIndex].Name = getNamePropertyDeviceToView();
343 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
344 nIndex++;
347 if(bTimeUsed)
349 mxViewInformation[nIndex].Name = getNamePropertyTime();
350 mxViewInformation[nIndex].Value <<= mfViewTime;
351 nIndex++;
354 if(bExtraInformation)
356 const sal_Int32 nExtra(mxExtendedInformation.getLength());
358 for(sal_Int32 a(0); a < nExtra; a++)
360 mxViewInformation[nIndex++] = mxExtendedInformation[a];
365 public:
366 ImpViewInformation3D(
367 const basegfx::B3DHomMatrix& rObjectTransformation,
368 const basegfx::B3DHomMatrix& rOrientation,
369 const basegfx::B3DHomMatrix& rProjection,
370 const basegfx::B3DHomMatrix& rDeviceToView,
371 double fViewTime,
372 const uno::Sequence< beans::PropertyValue >& rExtendedParameters)
373 : mnRefCount(0),
374 maObjectTransformation(rObjectTransformation),
375 maOrientation(rOrientation),
376 maProjection(rProjection),
377 maDeviceToView(rDeviceToView),
378 mfViewTime(fViewTime),
379 mxViewInformation(),
380 mxExtendedInformation()
382 impInterpretPropertyValues(rExtendedParameters);
385 ImpViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters)
386 : mnRefCount(0),
387 maObjectTransformation(),
388 maOrientation(),
389 maProjection(),
390 maDeviceToView(),
391 mfViewTime(),
392 mxViewInformation(rViewParameters),
393 mxExtendedInformation()
395 impInterpretPropertyValues(rViewParameters);
398 const basegfx::B3DHomMatrix& getObjectTransformation() const { return maObjectTransformation; }
399 const basegfx::B3DHomMatrix& getOrientation() const { return maOrientation; }
400 const basegfx::B3DHomMatrix& getProjection() const { return maProjection; }
401 const basegfx::B3DHomMatrix& getDeviceToView() const { return maDeviceToView; }
402 double getViewTime() const { return mfViewTime; }
404 const basegfx::B3DHomMatrix& getObjectToView() const
406 // on demand WorldToView creation
407 ::osl::Mutex m_mutex;
409 if(maObjectToView.isIdentity())
411 const_cast< ImpViewInformation3D* >(this)->maObjectToView = maDeviceToView * maProjection * maOrientation * maObjectTransformation;
414 return maObjectToView;
417 const uno::Sequence< beans::PropertyValue >& getViewInformationSequence() const
419 ::osl::Mutex m_mutex;
421 if(!mxViewInformation.hasElements())
423 const_cast< ImpViewInformation3D* >(this)->impFillViewInformationFromContent();
426 return mxViewInformation;
429 const uno::Sequence< beans::PropertyValue >& getExtendedInformationSequence() const
431 return mxExtendedInformation;
434 bool operator==(const ImpViewInformation3D& rCandidate) const
436 return (maObjectTransformation == rCandidate.maObjectTransformation
437 && maOrientation == rCandidate.maOrientation
438 && maProjection == rCandidate.maProjection
439 && maDeviceToView == rCandidate.maDeviceToView
440 && mfViewTime == rCandidate.mfViewTime
441 && mxExtendedInformation == rCandidate.mxExtendedInformation);
444 } // end of anonymous namespace
445 } // end of namespace drawinglayer
447 //////////////////////////////////////////////////////////////////////////////
449 namespace drawinglayer
451 namespace geometry
453 ViewInformation3D::ViewInformation3D(
454 const basegfx::B3DHomMatrix& rObjectObjectTransformation,
455 const basegfx::B3DHomMatrix& rOrientation,
456 const basegfx::B3DHomMatrix& rProjection,
457 const basegfx::B3DHomMatrix& rDeviceToView,
458 double fViewTime,
459 const uno::Sequence< beans::PropertyValue >& rExtendedParameters)
460 : mpViewInformation3D(new ImpViewInformation3D(rObjectObjectTransformation, rOrientation, rProjection, rDeviceToView, fViewTime, rExtendedParameters))
464 ViewInformation3D::ViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters)
465 : mpViewInformation3D(new ImpViewInformation3D(rViewParameters))
469 ViewInformation3D::ViewInformation3D(const ViewInformation3D& rCandidate)
470 : mpViewInformation3D(rCandidate.mpViewInformation3D)
472 ::osl::Mutex m_mutex;
473 mpViewInformation3D->mnRefCount++;
476 ViewInformation3D::~ViewInformation3D()
478 ::osl::Mutex m_mutex;
480 if(mpViewInformation3D->mnRefCount)
482 mpViewInformation3D->mnRefCount--;
484 else
486 delete mpViewInformation3D;
490 ViewInformation3D& ViewInformation3D::operator=(const ViewInformation3D& rCandidate)
492 ::osl::Mutex m_mutex;
494 if(mpViewInformation3D->mnRefCount)
496 mpViewInformation3D->mnRefCount--;
498 else
500 delete mpViewInformation3D;
503 mpViewInformation3D = rCandidate.mpViewInformation3D;
504 mpViewInformation3D->mnRefCount++;
506 return *this;
509 bool ViewInformation3D::operator==(const ViewInformation3D& rCandidate) const
511 if(rCandidate.mpViewInformation3D == mpViewInformation3D)
513 return true;
516 return (*rCandidate.mpViewInformation3D == *mpViewInformation3D);
519 const basegfx::B3DHomMatrix& ViewInformation3D::getObjectTransformation() const
521 return mpViewInformation3D->getObjectTransformation();
524 const basegfx::B3DHomMatrix& ViewInformation3D::getOrientation() const
526 return mpViewInformation3D->getOrientation();
529 const basegfx::B3DHomMatrix& ViewInformation3D::getProjection() const
531 return mpViewInformation3D->getProjection();
534 const basegfx::B3DHomMatrix& ViewInformation3D::getDeviceToView() const
536 return mpViewInformation3D->getDeviceToView();
539 const basegfx::B3DHomMatrix& ViewInformation3D::getObjectToView() const
541 return mpViewInformation3D->getObjectToView();
544 double ViewInformation3D::getViewTime() const
546 return mpViewInformation3D->getViewTime();
549 const uno::Sequence< beans::PropertyValue >& ViewInformation3D::getViewInformationSequence() const
551 return mpViewInformation3D->getViewInformationSequence();
554 const uno::Sequence< beans::PropertyValue >& ViewInformation3D::getExtendedInformationSequence() const
556 return mpViewInformation3D->getExtendedInformationSequence();
558 } // end of namespace geometry
559 } // end of namespace drawinglayer
561 //////////////////////////////////////////////////////////////////////////////
562 // eof