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