1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: sdrsphereprimitive3d.cxx,v $
9 * last change: $Author: aw $ $Date: 2008-06-10 09:29:33 $
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/primitive3d/sdrsphereprimitive3d.hxx>
40 #include <basegfx/polygon/b3dpolypolygontools.hxx>
41 #include <basegfx/matrix/b2dhommatrix.hxx>
42 #include <basegfx/polygon/b3dpolygon.hxx>
43 #include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx>
44 #include <basegfx/tools/canvastools.hxx>
45 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
46 #include <drawinglayer/primitive3d/hittestprimitive3d.hxx>
47 #include <drawinglayer/attribute/sdrattribute.hxx>
49 //////////////////////////////////////////////////////////////////////////////
51 using namespace com::sun::star
;
53 //////////////////////////////////////////////////////////////////////////////
55 namespace drawinglayer
59 Primitive3DSequence
SdrSpherePrimitive3D::createLocalDecomposition(const geometry::ViewInformation3D
& /*rViewInformation*/) const
61 Primitive3DSequence aRetval
;
62 const basegfx::B3DRange
aUnitRange(0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
63 const bool bCreateNormals(::com::sun::star::drawing::NormalsKind_SPECIFIC
== getSdr3DObjectAttribute().getNormalsKind()
64 || ::com::sun::star::drawing::NormalsKind_SPHERE
== getSdr3DObjectAttribute().getNormalsKind());
66 // create unit geometry
67 basegfx::B3DPolyPolygon
aFill(basegfx::tools::createSphereFillPolyPolygonFromB3DRange(aUnitRange
,
68 getHorizontalSegments(), getVerticalSegments(), bCreateNormals
));
71 if(getSdrLFSAttribute().getFill()
73 && getSdr3DObjectAttribute().getNormalsInvert()
74 && aFill
.areNormalsUsed())
77 aFill
= basegfx::tools::invertNormals(aFill
);
80 // texture coordinates
81 if(getSdrLFSAttribute().getFill())
83 // handle texture coordinates X
84 const bool bParallelX(::com::sun::star::drawing::TextureProjectionMode_PARALLEL
== getSdr3DObjectAttribute().getTextureProjectionX());
85 const bool bObjectSpecificX(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC
== getSdr3DObjectAttribute().getTextureProjectionX());
86 const bool bSphereX(::com::sun::star::drawing::TextureProjectionMode_SPHERE
== getSdr3DObjectAttribute().getTextureProjectionX());
88 // handle texture coordinates Y
89 const bool bParallelY(::com::sun::star::drawing::TextureProjectionMode_PARALLEL
== getSdr3DObjectAttribute().getTextureProjectionY());
90 const bool bObjectSpecificY(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC
== getSdr3DObjectAttribute().getTextureProjectionY());
91 const bool bSphereY(::com::sun::star::drawing::TextureProjectionMode_SPHERE
== getSdr3DObjectAttribute().getTextureProjectionY());
93 if(bParallelX
|| bParallelY
)
95 // apply parallel texture coordinates in X and/or Y
96 const basegfx::B3DRange
aRange(basegfx::tools::getRange(aFill
));
97 aFill
= basegfx::tools::applyDefaultTextureCoordinatesParallel(aFill
, aRange
, bParallelX
, bParallelY
);
100 if(bSphereX
|| bObjectSpecificX
|| bSphereY
|| bObjectSpecificY
)
102 double fRelativeAngle(0.0);
106 // Since the texture coordinates are (for historical reasons)
107 // different from forced to sphere texture coordinates,
108 // create a old version from it by rotating to old state before applying
109 // the texture coordinates to emulate old behaviour
110 fRelativeAngle
= F_2PI
* ((double)((getHorizontalSegments() >> 1L) - 1L) / (double)getHorizontalSegments());
111 basegfx::B3DHomMatrix aRot
;
112 aRot
.rotate(0.0, fRelativeAngle
, 0.0);
113 aFill
.transform(aRot
);
116 // apply spherical texture coordinates in X and/or Y
117 const basegfx::B3DRange
aRange(basegfx::tools::getRange(aFill
));
118 const basegfx::B3DPoint
aCenter(aRange
.getCenter());
119 aFill
= basegfx::tools::applyDefaultTextureCoordinatesSphere(aFill
, aCenter
,
120 bSphereX
|| bObjectSpecificX
, bSphereY
|| bObjectSpecificY
);
125 basegfx::B3DHomMatrix aRot
;
126 aRot
.rotate(0.0, -fRelativeAngle
, 0.0);
127 aFill
.transform(aRot
);
131 // transform texture coordinates to texture size
132 basegfx::B2DHomMatrix aTexMatrix
;
133 aTexMatrix
.scale(getTextureSize().getX(), getTextureSize().getY());
134 aFill
.transformTextureCoordiantes(aTexMatrix
);
137 // build vector of PolyPolygons
138 ::std::vector
< basegfx::B3DPolyPolygon
> a3DPolyPolygonVector
;
140 for(sal_uInt32
a(0L); a
< aFill
.count(); a
++)
142 a3DPolyPolygonVector
.push_back(basegfx::B3DPolyPolygon(aFill
.getB3DPolygon(a
)));
145 if(getSdrLFSAttribute().getFill())
148 aRetval
= create3DPolyPolygonFillPrimitives(
149 a3DPolyPolygonVector
,
152 getSdr3DObjectAttribute(),
153 *getSdrLFSAttribute().getFill(),
154 getSdrLFSAttribute().getFillFloatTransGradient());
158 // create simplified 3d hit test geometry
159 const attribute::SdrFillAttribute
aSimplifiedFillAttribute(0.0, basegfx::BColor(), 0, 0, 0);
161 aRetval
= create3DPolyPolygonFillPrimitives(
162 a3DPolyPolygonVector
,
165 getSdr3DObjectAttribute(),
166 aSimplifiedFillAttribute
,
169 // encapsulate in HitTestPrimitive3D and add
170 const Primitive3DReference
xRef(new HitTestPrimitive3D(aRetval
));
171 aRetval
= Primitive3DSequence(&xRef
, 1L);
175 if(getSdrLFSAttribute().getLine())
177 basegfx::B3DPolyPolygon
aSphere(basegfx::tools::createSpherePolyPolygonFromB3DRange(aUnitRange
, getHorizontalSegments(), getVerticalSegments()));
178 const Primitive3DSequence
aLines(create3DPolyPolygonLinePrimitives(aSphere
, getTransform(), *getSdrLFSAttribute().getLine()));
179 appendPrimitive3DSequenceToPrimitive3DSequence(aRetval
, aLines
);
183 if(getSdrLFSAttribute().getShadow() && aRetval
.hasElements())
185 const Primitive3DSequence
aShadow(createShadowPrimitive3D(aRetval
, *getSdrLFSAttribute().getShadow(), getSdr3DObjectAttribute().getShadow3D()));
186 appendPrimitive3DSequenceToPrimitive3DSequence(aRetval
, aShadow
);
192 SdrSpherePrimitive3D::SdrSpherePrimitive3D(
193 const basegfx::B3DHomMatrix
& rTransform
,
194 const basegfx::B2DVector
& rTextureSize
,
195 const attribute::SdrLineFillShadowAttribute
& rSdrLFSAttribute
,
196 const attribute::Sdr3DObjectAttribute
& rSdr3DObjectAttribute
,
197 sal_uInt32 nHorizontalSegments
,
198 sal_uInt32 nVerticalSegments
)
199 : SdrPrimitive3D(rTransform
, rTextureSize
, rSdrLFSAttribute
, rSdr3DObjectAttribute
),
200 mnHorizontalSegments(nHorizontalSegments
),
201 mnVerticalSegments(nVerticalSegments
)
205 bool SdrSpherePrimitive3D::operator==(const BasePrimitive3D
& rPrimitive
) const
207 if(SdrPrimitive3D::operator==(rPrimitive
))
209 const SdrSpherePrimitive3D
& rCompare
= static_cast< const SdrSpherePrimitive3D
& >(rPrimitive
);
211 return (getHorizontalSegments() == rCompare
.getHorizontalSegments()
212 && getVerticalSegments() == rCompare
.getVerticalSegments());
218 basegfx::B3DRange
SdrSpherePrimitive3D::getB3DRange(const geometry::ViewInformation3D
& /*rViewInformation*/) const
220 // use defaut from sdrPrimitive3D which uses transformation expanded by line width/2
221 // The parent implementation which uses the ranges of the decomposition would be more
222 // corrcet, but for historical reasons it is necessary to do the old method: To get
223 // the range of the non-transformed geometry and transform it then. This leads to different
224 // ranges where the new method is more correct, but the need to keep the old behaviour
225 // has priority here.
226 return getStandard3DRange();
230 ImplPrimitrive3DIDBlock(SdrSpherePrimitive3D
, PRIMITIVE3D_ID_SDRSPHEREPRIMITIVE3D
)
232 } // end of namespace primitive3d
233 } // end of namespace drawinglayer
235 //////////////////////////////////////////////////////////////////////////////