1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: viewinformation3d.cxx,v $
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,
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
56 /** Implementation class for ViewInformation3D
58 class ImpViewInformation3D
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
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
;
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())
205 rProp
.Value
>>= f_30
;
206 maProjection
.set(3, 0, f_30
);
208 else if(rProp
.Name
== getNamePropertyProjection_31())
211 rProp
.Value
>>= f_31
;
212 maProjection
.set(3, 1, f_31
);
214 else if(rProp
.Name
== getNamePropertyProjection_32())
217 rProp
.Value
>>= f_32
;
218 maProjection
.set(3, 2, f_32
);
220 else if(rProp
.Name
== getNamePropertyProjection_33())
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
;
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
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
;
294 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D
;
295 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D
, maOrientation
);
296 mxViewInformation
[nIndex
].Name
= getNamePropertyOrientation();
297 mxViewInformation
[nIndex
].Value
<<= aAffineMatrix3D
;
303 com::sun::star::geometry::AffineMatrix3D aAffineMatrix3D
;
304 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D
, maProjection
);
305 mxViewInformation
[nIndex
].Name
= getNamePropertyProjection();
306 mxViewInformation
[nIndex
].Value
<<= aAffineMatrix3D
;
310 if(bProjectionUsed_30
)
312 mxViewInformation
[nIndex
].Name
= getNamePropertyProjection_30();
313 mxViewInformation
[nIndex
].Value
<<= maProjection
.get(3, 0);
317 if(bProjectionUsed_31
)
319 mxViewInformation
[nIndex
].Name
= getNamePropertyProjection_31();
320 mxViewInformation
[nIndex
].Value
<<= maProjection
.get(3, 1);
324 if(bProjectionUsed_32
)
326 mxViewInformation
[nIndex
].Name
= getNamePropertyProjection_32();
327 mxViewInformation
[nIndex
].Value
<<= maProjection
.get(3, 2);
331 if(bProjectionUsed_33
)
333 mxViewInformation
[nIndex
].Name
= getNamePropertyProjection_33();
334 mxViewInformation
[nIndex
].Value
<<= maProjection
.get(3, 3);
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
;
349 mxViewInformation
[nIndex
].Name
= getNamePropertyTime();
350 mxViewInformation
[nIndex
].Value
<<= mfViewTime
;
354 if(bExtraInformation
)
356 const sal_Int32
nExtra(mxExtendedInformation
.getLength());
358 for(sal_Int32
a(0); a
< nExtra
; a
++)
360 mxViewInformation
[nIndex
++] = mxExtendedInformation
[a
];
366 ImpViewInformation3D(
367 const basegfx::B3DHomMatrix
& rObjectTransformation
,
368 const basegfx::B3DHomMatrix
& rOrientation
,
369 const basegfx::B3DHomMatrix
& rProjection
,
370 const basegfx::B3DHomMatrix
& rDeviceToView
,
372 const uno::Sequence
< beans::PropertyValue
>& rExtendedParameters
)
374 maObjectTransformation(rObjectTransformation
),
375 maOrientation(rOrientation
),
376 maProjection(rProjection
),
377 maDeviceToView(rDeviceToView
),
378 mfViewTime(fViewTime
),
380 mxExtendedInformation()
382 impInterpretPropertyValues(rExtendedParameters
);
385 ImpViewInformation3D(const uno::Sequence
< beans::PropertyValue
>& rViewParameters
)
387 maObjectTransformation(),
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
453 ViewInformation3D::ViewInformation3D(
454 const basegfx::B3DHomMatrix
& rObjectObjectTransformation
,
455 const basegfx::B3DHomMatrix
& rOrientation
,
456 const basegfx::B3DHomMatrix
& rProjection
,
457 const basegfx::B3DHomMatrix
& rDeviceToView
,
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
--;
486 delete mpViewInformation3D
;
490 ViewInformation3D
& ViewInformation3D::operator=(const ViewInformation3D
& rCandidate
)
492 ::osl::Mutex m_mutex
;
494 if(mpViewInformation3D
->mnRefCount
)
496 mpViewInformation3D
->mnRefCount
--;
500 delete mpViewInformation3D
;
503 mpViewInformation3D
= rCandidate
.mpViewInformation3D
;
504 mpViewInformation3D
->mnRefCount
++;
509 bool ViewInformation3D::operator==(const ViewInformation3D
& rCandidate
) const
511 if(rCandidate
.mpViewInformation3D
== mpViewInformation3D
)
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 //////////////////////////////////////////////////////////////////////////////