xref: /AOO41X/main/svx/source/engine3d/helperminimaldepth3d.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svx.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <helperminimaldepth3d.hxx>
32*cdf0e10cSrcweir #include <drawinglayer/processor3d/baseprocessor3d.hxx>
33*cdf0e10cSrcweir #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
34*cdf0e10cSrcweir #include <drawinglayer/primitive3d/transformprimitive3d.hxx>
35*cdf0e10cSrcweir #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
36*cdf0e10cSrcweir #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
37*cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofe3d.hxx>
38*cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
39*cdf0e10cSrcweir #include <svx/obj3d.hxx>
40*cdf0e10cSrcweir #include <svx/scene3d.hxx>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir namespace drawinglayer
45*cdf0e10cSrcweir {
46*cdf0e10cSrcweir 	namespace processor3d
47*cdf0e10cSrcweir 	{
48*cdf0e10cSrcweir 		class MinimalDephInViewExtractor : public BaseProcessor3D
49*cdf0e10cSrcweir 		{
50*cdf0e10cSrcweir 		private:
51*cdf0e10cSrcweir             // the value which will be fetched as result
52*cdf0e10cSrcweir             double                                  mfMinimalDepth;
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir 			// as tooling, the process() implementation takes over API handling and calls this
55*cdf0e10cSrcweir 			// virtual render method when the primitive implementation is BasePrimitive3D-based.
56*cdf0e10cSrcweir 			virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate);
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir 		public:
59*cdf0e10cSrcweir 			MinimalDephInViewExtractor(const geometry::ViewInformation3D& rViewInformation)
60*cdf0e10cSrcweir             :   BaseProcessor3D(rViewInformation),
61*cdf0e10cSrcweir                 mfMinimalDepth(DBL_MAX)
62*cdf0e10cSrcweir             {}
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir 			// data access
65*cdf0e10cSrcweir             double getMinimalDepth() const { return mfMinimalDepth; }
66*cdf0e10cSrcweir 		};
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir         void MinimalDephInViewExtractor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate)
69*cdf0e10cSrcweir         {
70*cdf0e10cSrcweir 			// it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
71*cdf0e10cSrcweir 			switch(rCandidate.getPrimitive3DID())
72*cdf0e10cSrcweir 			{
73*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
74*cdf0e10cSrcweir 				{
75*cdf0e10cSrcweir 					// transform group. Remember current transformations
76*cdf0e10cSrcweir 					const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate);
77*cdf0e10cSrcweir 					const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir 					// create new transformation; add new object transform from right side
80*cdf0e10cSrcweir 					const geometry::ViewInformation3D aNewViewInformation3D(
81*cdf0e10cSrcweir 						aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(),
82*cdf0e10cSrcweir 						aLastViewInformation3D.getOrientation(),
83*cdf0e10cSrcweir 						aLastViewInformation3D.getProjection(),
84*cdf0e10cSrcweir 						aLastViewInformation3D.getDeviceToView(),
85*cdf0e10cSrcweir 						aLastViewInformation3D.getViewTime(),
86*cdf0e10cSrcweir 						aLastViewInformation3D.getExtendedInformationSequence());
87*cdf0e10cSrcweir 					updateViewInformation(aNewViewInformation3D);
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 					// let break down
90*cdf0e10cSrcweir 					process(rPrimitive.getChildren());
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir 					// restore transformations
93*cdf0e10cSrcweir 					updateViewInformation(aLastViewInformation3D);
94*cdf0e10cSrcweir 					break;
95*cdf0e10cSrcweir 				}
96*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
97*cdf0e10cSrcweir 				{
98*cdf0e10cSrcweir 					// PolygonHairlinePrimitive3D
99*cdf0e10cSrcweir 					const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rCandidate);
100*cdf0e10cSrcweir            			const basegfx::B3DPolygon& rPolygon = rPrimitive.getB3DPolygon();
101*cdf0e10cSrcweir                     const sal_uInt32 nCount(rPolygon.count());
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir                     for(sal_uInt32 a(0); a < nCount; a++)
104*cdf0e10cSrcweir                     {
105*cdf0e10cSrcweir                         const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * rPolygon.getB3DPoint(a));
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir                         if(aPointInView.getZ() < mfMinimalDepth)
108*cdf0e10cSrcweir                         {
109*cdf0e10cSrcweir                             mfMinimalDepth = aPointInView.getZ();
110*cdf0e10cSrcweir                         }
111*cdf0e10cSrcweir                     }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir                     break;
114*cdf0e10cSrcweir 				}
115*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
116*cdf0e10cSrcweir 				{
117*cdf0e10cSrcweir 					// PolyPolygonMaterialPrimitive3D
118*cdf0e10cSrcweir 					const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate);
119*cdf0e10cSrcweir            			const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon();
120*cdf0e10cSrcweir                     const sal_uInt32 nPolyCount(rPolyPolygon.count());
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir                     for(sal_uInt32 a(0); a < nPolyCount; a++)
123*cdf0e10cSrcweir                     {
124*cdf0e10cSrcweir            			    const basegfx::B3DPolygon aPolygon(rPolyPolygon.getB3DPolygon(a));
125*cdf0e10cSrcweir                         const sal_uInt32 nCount(aPolygon.count());
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir                         for(sal_uInt32 b(0); b < nCount; b++)
128*cdf0e10cSrcweir                         {
129*cdf0e10cSrcweir                             const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * aPolygon.getB3DPoint(b));
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir                             if(aPointInView.getZ() < mfMinimalDepth)
132*cdf0e10cSrcweir                             {
133*cdf0e10cSrcweir                                 mfMinimalDepth = aPointInView.getZ();
134*cdf0e10cSrcweir                             }
135*cdf0e10cSrcweir                         }
136*cdf0e10cSrcweir                     }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir                     break;
139*cdf0e10cSrcweir 				}
140*cdf0e10cSrcweir 				default :
141*cdf0e10cSrcweir 				{
142*cdf0e10cSrcweir 					// process recursively
143*cdf0e10cSrcweir 					process(rCandidate.get3DDecomposition(getViewInformation3D()));
144*cdf0e10cSrcweir 					break;
145*cdf0e10cSrcweir 				}
146*cdf0e10cSrcweir             }
147*cdf0e10cSrcweir         }
148*cdf0e10cSrcweir 	} // end of namespace processor3d
149*cdf0e10cSrcweir } // end of namespace drawinglayer
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
152*cdf0e10cSrcweir // changed to create values using VCs, Primitive3DSequence and ViewInformation3D to allow
153*cdf0e10cSrcweir // removal of old 3D bucket geometry. There is one slight difference in the result, it's
154*cdf0e10cSrcweir // in [0.0 .. 1.0] for Z-Depth since the scaling of the scene as 2D object is no longer
155*cdf0e10cSrcweir // part of the 3D transformations. This could be added since the ViewContactOfE3dScene is
156*cdf0e10cSrcweir // given, but is not needed since the permutation of the depth values needs only be correct
157*cdf0e10cSrcweir // relative to each other
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir double getMinimalDepthInViewCoordinates(const E3dCompoundObject& rObject)
160*cdf0e10cSrcweir {
161*cdf0e10cSrcweir     // this is a E3dCompoundObject, so it cannot be a scene (which is a E3dObject).
162*cdf0e10cSrcweir     // Get primitive sequence using VC
163*cdf0e10cSrcweir     const sdr::contact::ViewContactOfE3d& rVCObject = static_cast< sdr::contact::ViewContactOfE3d& >(rObject.GetViewContact());
164*cdf0e10cSrcweir 	const drawinglayer::primitive3d::Primitive3DSequence aPrimitives = rVCObject.getViewIndependentPrimitive3DSequence();
165*cdf0e10cSrcweir     double fRetval(DBL_MAX);
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir     if(aPrimitives.hasElements())
168*cdf0e10cSrcweir     {
169*cdf0e10cSrcweir         const E3dScene* pScene = rObject.GetScene();
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir         if(pScene)
172*cdf0e10cSrcweir         {
173*cdf0e10cSrcweir             // get ViewInformation3D from scene using VC
174*cdf0e10cSrcweir             const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
175*cdf0e10cSrcweir 	        const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir             // the scene's object transformation is already part of aViewInfo3D.getObjectTransformation()
178*cdf0e10cSrcweir             // for historical reasons (see ViewContactOfE3dScene::createViewInformation3D for more info)
179*cdf0e10cSrcweir             // and the object's transform is part of aPrimitives (and taken into account when decomposing
180*cdf0e10cSrcweir             // to PolygonHairlinePrimitive3D and PolyPolygonMaterialPrimitive3D). The missing part may be
181*cdf0e10cSrcweir             // some Scene SdrObjects lying in-between which may need to be added. This is e.g. used in chart,
182*cdf0e10cSrcweir             // and generally allowed in 3d scenes an their 3d object hierarchy
183*cdf0e10cSrcweir             basegfx::B3DHomMatrix aInBetweenSceneMatrix;
184*cdf0e10cSrcweir             E3dScene* pParentScene = dynamic_cast< E3dScene* >(rObject.GetParentObj());
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir             while(pParentScene && pParentScene != pScene)
187*cdf0e10cSrcweir             {
188*cdf0e10cSrcweir                 aInBetweenSceneMatrix = pParentScene->GetTransform() * aInBetweenSceneMatrix;
189*cdf0e10cSrcweir                 pParentScene = dynamic_cast< E3dScene* >(pParentScene->GetParentObj());
190*cdf0e10cSrcweir             }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir             // build new ViewInformation containing all transforms
193*cdf0e10cSrcweir             const drawinglayer::geometry::ViewInformation3D aNewViewInformation3D(
194*cdf0e10cSrcweir                 aViewInfo3D.getObjectTransformation() * aInBetweenSceneMatrix,
195*cdf0e10cSrcweir                 aViewInfo3D.getOrientation(),
196*cdf0e10cSrcweir                 aViewInfo3D.getProjection(),
197*cdf0e10cSrcweir                 aViewInfo3D.getDeviceToView(),
198*cdf0e10cSrcweir                 aViewInfo3D.getViewTime(),
199*cdf0e10cSrcweir                 aViewInfo3D.getExtendedInformationSequence());
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir             // create extractor helper, proccess geometry and get return value
202*cdf0e10cSrcweir             drawinglayer::processor3d::MinimalDephInViewExtractor aExtractor(aNewViewInformation3D);
203*cdf0e10cSrcweir             aExtractor.process(aPrimitives);
204*cdf0e10cSrcweir             fRetval = aExtractor.getMinimalDepth();
205*cdf0e10cSrcweir         }
206*cdf0e10cSrcweir     }
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 	return fRetval;
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
212*cdf0e10cSrcweir // eof
213