nss: upgrade to release 3.73
[LibreOffice.git] / drawinglayer / source / geometry / viewinformation3d.cxx
blobb3e75bffa6dde2c74b0038e381e2ed82a1cb5c88
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <drawinglayer/geometry/viewinformation3d.hxx>
21 #include <basegfx/matrix/b3dhommatrix.hxx>
22 #include <com/sun/star/beans/PropertyValue.hpp>
23 #include <com/sun/star/geometry/AffineMatrix3D.hpp>
24 #include <basegfx/utils/canvastools.hxx>
25 #include <rtl/instance.hxx>
26 #include <com/sun/star/uno/Sequence.hxx>
29 using namespace com::sun::star;
32 namespace drawinglayer::geometry
34 /** Implementation class for ViewInformation3D
36 class ImpViewInformation3D
38 private:
39 // ViewInformation3D implementation can change refcount, so we have only
40 // two memory regions for pairs of ViewInformation3D/ImpViewInformation3D
41 friend class ::drawinglayer::geometry::ViewInformation3D;
43 // the 3D transformations
44 // Object to World. This may change and being adapted when entering 3D transformation
45 // groups
46 basegfx::B3DHomMatrix maObjectTransformation;
48 // World to Camera. This includes VRP, VPN and VUV camera coordinate system
49 basegfx::B3DHomMatrix maOrientation;
51 // Camera to Device with X,Y and Z [-1.0 .. 1.0]. This is the
52 // 3D to 2D projection which may be parallel or perspective. When it is perspective,
53 // the last line of the homogen matrix will NOT be unused
54 basegfx::B3DHomMatrix maProjection;
56 // Device to View with X,Y and Z [0.0 .. 1.0]. This converts from -1 to 1 coordinates
57 // in camera coordinate system to 0 to 1 in unit 2D coordinates. This way it stays
58 // view-independent. To get discrete coordinates, the 2D transformation of a scene
59 // as 2D object needs to be involved
60 basegfx::B3DHomMatrix maDeviceToView;
62 // Object to View is the linear combination of all four transformations. It's
63 // buffered to avoid too much matrix multiplying and created on demand
64 basegfx::B3DHomMatrix maObjectToView;
66 // the point in time
67 double mfViewTime;
69 // the complete PropertyValue representation (if already created)
70 uno::Sequence< beans::PropertyValue > mxViewInformation;
72 // the extra PropertyValues; does not contain the transformations
73 uno::Sequence< beans::PropertyValue > mxExtendedInformation;
75 // the local UNO API strings
76 static OUString getNamePropertyObjectTransformation()
78 return "ObjectTransformation";
81 static OUString getNamePropertyOrientation()
83 return "Orientation";
86 static OUString getNamePropertyProjection()
88 return "Projection";
91 static OUString getNamePropertyProjection_30()
93 return "Projection30";
96 static OUString getNamePropertyProjection_31()
98 return "Projection31";
101 static OUString getNamePropertyProjection_32()
103 return "Projection32";
106 static OUString getNamePropertyProjection_33()
108 return "Projection33";
111 static OUString getNamePropertyDeviceToView()
113 return "DeviceToView";
116 static OUString getNamePropertyTime()
118 return "Time";
121 // a central PropertyValue parsing method to allow transportation of
122 // all ViewParameters using UNO API
123 void impInterpretPropertyValues(const uno::Sequence< beans::PropertyValue >& rViewParameters)
125 if(!rViewParameters.hasElements())
126 return;
128 const sal_Int32 nCount(rViewParameters.getLength());
129 sal_Int32 nExtendedInsert(0);
131 // prepare extended information for filtering. Maximum size is nCount
132 mxExtendedInformation.realloc(nCount);
134 for(sal_Int32 a(0); a < nCount; a++)
136 const beans::PropertyValue& rProp = rViewParameters[a];
138 if(rProp.Name == getNamePropertyObjectTransformation())
140 css::geometry::AffineMatrix3D aAffineMatrix3D;
141 rProp.Value >>= aAffineMatrix3D;
142 maObjectTransformation = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
144 else if(rProp.Name == getNamePropertyOrientation())
146 css::geometry::AffineMatrix3D aAffineMatrix3D;
147 rProp.Value >>= aAffineMatrix3D;
148 maOrientation = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
150 else if(rProp.Name == getNamePropertyProjection())
152 // projection may be defined using a frustum in which case the last line of
153 // the 4x4 matrix is not (0,0,0,1). Since AffineMatrix3D does not support that,
154 // these four values need to be treated extra
155 const double f_30(maProjection.get(3, 0));
156 const double f_31(maProjection.get(3, 1));
157 const double f_32(maProjection.get(3, 2));
158 const double f_33(maProjection.get(3, 3));
160 css::geometry::AffineMatrix3D aAffineMatrix3D;
161 rProp.Value >>= aAffineMatrix3D;
162 maProjection = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
164 maProjection.set(3, 0, f_30);
165 maProjection.set(3, 1, f_31);
166 maProjection.set(3, 2, f_32);
167 maProjection.set(3, 3, f_33);
169 else if(rProp.Name == getNamePropertyProjection_30())
171 double f_30(0.0);
172 rProp.Value >>= f_30;
173 maProjection.set(3, 0, f_30);
175 else if(rProp.Name == getNamePropertyProjection_31())
177 double f_31(0.0);
178 rProp.Value >>= f_31;
179 maProjection.set(3, 1, f_31);
181 else if(rProp.Name == getNamePropertyProjection_32())
183 double f_32(0.0);
184 rProp.Value >>= f_32;
185 maProjection.set(3, 2, f_32);
187 else if(rProp.Name == getNamePropertyProjection_33())
189 double f_33(1.0);
190 rProp.Value >>= f_33;
191 maProjection.set(3, 3, f_33);
193 else if(rProp.Name == getNamePropertyDeviceToView())
195 css::geometry::AffineMatrix3D aAffineMatrix3D;
196 rProp.Value >>= aAffineMatrix3D;
197 maDeviceToView = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
199 else if(rProp.Name == getNamePropertyTime())
201 rProp.Value >>= mfViewTime;
203 else
205 // extra information; add to filtered information
206 mxExtendedInformation[nExtendedInsert++] = rProp;
210 // extra information size is now known; realloc to final size
211 mxExtendedInformation.realloc(nExtendedInsert);
214 // central method to create a Sequence of PropertyValues containing he complete
215 // data set
216 void impFillViewInformationFromContent()
218 const bool bObjectTransformationUsed(!maObjectTransformation.isIdentity());
219 const bool bOrientationUsed(!maOrientation.isIdentity());
220 const bool bProjectionUsed(!maProjection.isIdentity());
221 const bool bDeviceToViewUsed(!maDeviceToView.isIdentity());
222 const bool bTimeUsed(0.0 < mfViewTime);
223 const bool bExtraInformation(mxExtendedInformation.hasElements());
225 // projection may be defined using a frustum in which case the last line of
226 // the 4x4 matrix is not (0,0,0,1). Since AffineMatrix3D does not support that,
227 // these four values need to be treated extra
228 const bool bProjectionUsed_30(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 0)));
229 const bool bProjectionUsed_31(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 1)));
230 const bool bProjectionUsed_32(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 2)));
231 const bool bProjectionUsed_33(bProjectionUsed && !basegfx::fTools::equal(maProjection.get(3, 3), 1.0));
233 sal_uInt32 nIndex(0);
234 const sal_uInt32 nCount(
235 (bObjectTransformationUsed ? 1 : 0) +
236 (bOrientationUsed ? 1 : 0) +
237 (bProjectionUsed ? 1 : 0) +
238 (bProjectionUsed_30 ? 1 : 0) +
239 (bProjectionUsed_31 ? 1 : 0) +
240 (bProjectionUsed_32 ? 1 : 0) +
241 (bProjectionUsed_33 ? 1 : 0) +
242 (bDeviceToViewUsed ? 1 : 0) +
243 (bTimeUsed ? 1 : 0) +
244 (bExtraInformation ? mxExtendedInformation.getLength() : 0));
246 mxViewInformation.realloc(nCount);
248 if(bObjectTransformationUsed)
250 css::geometry::AffineMatrix3D aAffineMatrix3D;
251 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maObjectTransformation);
252 mxViewInformation[nIndex].Name = getNamePropertyObjectTransformation();
253 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
254 nIndex++;
257 if(bOrientationUsed)
259 css::geometry::AffineMatrix3D aAffineMatrix3D;
260 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maOrientation);
261 mxViewInformation[nIndex].Name = getNamePropertyOrientation();
262 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
263 nIndex++;
266 if(bProjectionUsed)
268 css::geometry::AffineMatrix3D aAffineMatrix3D;
269 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maProjection);
270 mxViewInformation[nIndex].Name = getNamePropertyProjection();
271 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
272 nIndex++;
275 if(bProjectionUsed_30)
277 mxViewInformation[nIndex].Name = getNamePropertyProjection_30();
278 mxViewInformation[nIndex].Value <<= maProjection.get(3, 0);
279 nIndex++;
282 if(bProjectionUsed_31)
284 mxViewInformation[nIndex].Name = getNamePropertyProjection_31();
285 mxViewInformation[nIndex].Value <<= maProjection.get(3, 1);
286 nIndex++;
289 if(bProjectionUsed_32)
291 mxViewInformation[nIndex].Name = getNamePropertyProjection_32();
292 mxViewInformation[nIndex].Value <<= maProjection.get(3, 2);
293 nIndex++;
296 if(bProjectionUsed_33)
298 mxViewInformation[nIndex].Name = getNamePropertyProjection_33();
299 mxViewInformation[nIndex].Value <<= maProjection.get(3, 3);
300 nIndex++;
303 if(bDeviceToViewUsed)
305 css::geometry::AffineMatrix3D aAffineMatrix3D;
306 basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maDeviceToView);
307 mxViewInformation[nIndex].Name = getNamePropertyDeviceToView();
308 mxViewInformation[nIndex].Value <<= aAffineMatrix3D;
309 nIndex++;
312 if(bTimeUsed)
314 mxViewInformation[nIndex].Name = getNamePropertyTime();
315 mxViewInformation[nIndex].Value <<= mfViewTime;
316 nIndex++;
319 if(bExtraInformation)
321 const sal_Int32 nExtra(mxExtendedInformation.getLength());
323 for(sal_Int32 a(0); a < nExtra; a++)
325 mxViewInformation[nIndex++] = mxExtendedInformation[a];
330 public:
331 ImpViewInformation3D(
332 const basegfx::B3DHomMatrix& rObjectTransformation,
333 const basegfx::B3DHomMatrix& rOrientation,
334 const basegfx::B3DHomMatrix& rProjection,
335 const basegfx::B3DHomMatrix& rDeviceToView,
336 double fViewTime,
337 const uno::Sequence< beans::PropertyValue >& rExtendedParameters)
338 : maObjectTransformation(rObjectTransformation),
339 maOrientation(rOrientation),
340 maProjection(rProjection),
341 maDeviceToView(rDeviceToView),
342 mfViewTime(fViewTime),
343 mxViewInformation(),
344 mxExtendedInformation()
346 impInterpretPropertyValues(rExtendedParameters);
349 explicit ImpViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters)
350 : maObjectTransformation(),
351 maOrientation(),
352 maProjection(),
353 maDeviceToView(),
354 mfViewTime(),
355 mxViewInformation(rViewParameters),
356 mxExtendedInformation()
358 impInterpretPropertyValues(rViewParameters);
361 ImpViewInformation3D()
362 : maObjectTransformation(),
363 maOrientation(),
364 maProjection(),
365 maDeviceToView(),
366 mfViewTime(),
367 mxViewInformation(),
368 mxExtendedInformation()
372 const basegfx::B3DHomMatrix& getObjectTransformation() const { return maObjectTransformation; }
373 const basegfx::B3DHomMatrix& getOrientation() const { return maOrientation; }
374 const basegfx::B3DHomMatrix& getProjection() const { return maProjection; }
375 const basegfx::B3DHomMatrix& getDeviceToView() const { return maDeviceToView; }
376 double getViewTime() const { return mfViewTime; }
378 const basegfx::B3DHomMatrix& getObjectToView() const
380 // on demand WorldToView creation
382 if(maObjectToView.isIdentity())
384 const_cast< ImpViewInformation3D* >(this)->maObjectToView = maDeviceToView * maProjection * maOrientation * maObjectTransformation;
387 return maObjectToView;
390 const uno::Sequence< beans::PropertyValue >& getViewInformationSequence() const
392 if(!mxViewInformation.hasElements())
394 const_cast< ImpViewInformation3D* >(this)->impFillViewInformationFromContent();
397 return mxViewInformation;
400 const uno::Sequence< beans::PropertyValue >& getExtendedInformationSequence() const
402 return mxExtendedInformation;
405 bool operator==(const ImpViewInformation3D& rCandidate) const
407 return (maObjectTransformation == rCandidate.maObjectTransformation
408 && maOrientation == rCandidate.maOrientation
409 && maProjection == rCandidate.maProjection
410 && maDeviceToView == rCandidate.maDeviceToView
411 && mfViewTime == rCandidate.mfViewTime
412 && mxExtendedInformation == rCandidate.mxExtendedInformation);
415 } // end of namespace drawinglayer::geometry
418 namespace drawinglayer::geometry
420 namespace
422 struct theGlobalDefault :
423 public rtl::Static< ViewInformation3D::ImplType, theGlobalDefault > {};
426 ViewInformation3D::ViewInformation3D(
427 const basegfx::B3DHomMatrix& rObjectObjectTransformation,
428 const basegfx::B3DHomMatrix& rOrientation,
429 const basegfx::B3DHomMatrix& rProjection,
430 const basegfx::B3DHomMatrix& rDeviceToView,
431 double fViewTime,
432 const uno::Sequence< beans::PropertyValue >& rExtendedParameters)
433 : mpViewInformation3D(ImpViewInformation3D(
434 rObjectObjectTransformation, rOrientation, rProjection,
435 rDeviceToView, fViewTime, rExtendedParameters))
439 ViewInformation3D::ViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters)
440 : mpViewInformation3D(ImpViewInformation3D(rViewParameters))
444 ViewInformation3D::ViewInformation3D()
445 : mpViewInformation3D(theGlobalDefault::get())
449 ViewInformation3D::ViewInformation3D(const ViewInformation3D&) = default;
451 ViewInformation3D::ViewInformation3D(ViewInformation3D&&) = default;
453 ViewInformation3D::~ViewInformation3D() = default;
455 bool ViewInformation3D::isDefault() const
457 return mpViewInformation3D.same_object(theGlobalDefault::get());
460 ViewInformation3D& ViewInformation3D::operator=(const ViewInformation3D&) = default;
462 ViewInformation3D& ViewInformation3D::operator=(ViewInformation3D&&) = default;
464 bool ViewInformation3D::operator==(const ViewInformation3D& rCandidate) const
466 return rCandidate.mpViewInformation3D == mpViewInformation3D;
469 const basegfx::B3DHomMatrix& ViewInformation3D::getObjectTransformation() const
471 return mpViewInformation3D->getObjectTransformation();
474 const basegfx::B3DHomMatrix& ViewInformation3D::getOrientation() const
476 return mpViewInformation3D->getOrientation();
479 const basegfx::B3DHomMatrix& ViewInformation3D::getProjection() const
481 return mpViewInformation3D->getProjection();
484 const basegfx::B3DHomMatrix& ViewInformation3D::getDeviceToView() const
486 return mpViewInformation3D->getDeviceToView();
489 const basegfx::B3DHomMatrix& ViewInformation3D::getObjectToView() const
491 return mpViewInformation3D->getObjectToView();
494 double ViewInformation3D::getViewTime() const
496 return mpViewInformation3D->getViewTime();
499 const uno::Sequence< beans::PropertyValue >& ViewInformation3D::getViewInformationSequence() const
501 return mpViewInformation3D->getViewInformationSequence();
504 const uno::Sequence< beans::PropertyValue >& ViewInformation3D::getExtendedInformationSequence() const
506 return mpViewInformation3D->getExtendedInformationSequence();
509 } // end of namespace
511 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */