1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_drawinglayer.hxx" 30 31 #include <drawinglayer/primitive3d/sdrsphereprimitive3d.hxx> 32 #include <basegfx/polygon/b3dpolypolygontools.hxx> 33 #include <basegfx/matrix/b2dhommatrix.hxx> 34 #include <basegfx/polygon/b3dpolygon.hxx> 35 #include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx> 36 #include <basegfx/tools/canvastools.hxx> 37 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> 38 #include <drawinglayer/attribute/sdrfillattribute.hxx> 39 #include <drawinglayer/attribute/sdrlineattribute.hxx> 40 #include <drawinglayer/attribute/sdrshadowattribute.hxx> 41 42 ////////////////////////////////////////////////////////////////////////////// 43 44 using namespace com::sun::star; 45 46 ////////////////////////////////////////////////////////////////////////////// 47 48 namespace drawinglayer 49 { 50 namespace primitive3d 51 { 52 Primitive3DSequence SdrSpherePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const 53 { 54 Primitive3DSequence aRetval; 55 const basegfx::B3DRange aUnitRange(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); 56 const bool bCreateNormals(::com::sun::star::drawing::NormalsKind_SPECIFIC == getSdr3DObjectAttribute().getNormalsKind() 57 || ::com::sun::star::drawing::NormalsKind_SPHERE == getSdr3DObjectAttribute().getNormalsKind()); 58 59 // create unit geometry 60 basegfx::B3DPolyPolygon aFill(basegfx::tools::createSphereFillPolyPolygonFromB3DRange(aUnitRange, 61 getHorizontalSegments(), getVerticalSegments(), bCreateNormals)); 62 63 // normal inversion 64 if(!getSdrLFSAttribute().getFill().isDefault() 65 && bCreateNormals 66 && getSdr3DObjectAttribute().getNormalsInvert() 67 && aFill.areNormalsUsed()) 68 { 69 // invert normals 70 aFill = basegfx::tools::invertNormals(aFill); 71 } 72 73 // texture coordinates 74 if(!getSdrLFSAttribute().getFill().isDefault()) 75 { 76 // handle texture coordinates X 77 const bool bParallelX(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == getSdr3DObjectAttribute().getTextureProjectionX()); 78 const bool bObjectSpecificX(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionX()); 79 const bool bSphereX(::com::sun::star::drawing::TextureProjectionMode_SPHERE == getSdr3DObjectAttribute().getTextureProjectionX()); 80 81 // handle texture coordinates Y 82 const bool bParallelY(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == getSdr3DObjectAttribute().getTextureProjectionY()); 83 const bool bObjectSpecificY(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionY()); 84 const bool bSphereY(::com::sun::star::drawing::TextureProjectionMode_SPHERE == getSdr3DObjectAttribute().getTextureProjectionY()); 85 86 if(bParallelX || bParallelY) 87 { 88 // apply parallel texture coordinates in X and/or Y 89 const basegfx::B3DRange aRange(basegfx::tools::getRange(aFill)); 90 aFill = basegfx::tools::applyDefaultTextureCoordinatesParallel(aFill, aRange, bParallelX, bParallelY); 91 } 92 93 if(bSphereX || bObjectSpecificX || bSphereY || bObjectSpecificY) 94 { 95 double fRelativeAngle(0.0); 96 97 if(bObjectSpecificX) 98 { 99 // Since the texture coordinates are (for historical reasons) 100 // different from forced to sphere texture coordinates, 101 // create a old version from it by rotating to old state before applying 102 // the texture coordinates to emulate old behaviour 103 fRelativeAngle = F_2PI * ((double)((getHorizontalSegments() >> 1L) - 1L) / (double)getHorizontalSegments()); 104 basegfx::B3DHomMatrix aRot; 105 aRot.rotate(0.0, fRelativeAngle, 0.0); 106 aFill.transform(aRot); 107 } 108 109 // apply spherical texture coordinates in X and/or Y 110 const basegfx::B3DRange aRange(basegfx::tools::getRange(aFill)); 111 const basegfx::B3DPoint aCenter(aRange.getCenter()); 112 aFill = basegfx::tools::applyDefaultTextureCoordinatesSphere(aFill, aCenter, 113 bSphereX || bObjectSpecificX, bSphereY || bObjectSpecificY); 114 115 if(bObjectSpecificX) 116 { 117 // rotate back again 118 basegfx::B3DHomMatrix aRot; 119 aRot.rotate(0.0, -fRelativeAngle, 0.0); 120 aFill.transform(aRot); 121 } 122 } 123 124 // transform texture coordinates to texture size 125 basegfx::B2DHomMatrix aTexMatrix; 126 aTexMatrix.scale(getTextureSize().getX(), getTextureSize().getY()); 127 aFill.transformTextureCoordiantes(aTexMatrix); 128 } 129 130 // build vector of PolyPolygons 131 ::std::vector< basegfx::B3DPolyPolygon > a3DPolyPolygonVector; 132 133 for(sal_uInt32 a(0L); a < aFill.count(); a++) 134 { 135 a3DPolyPolygonVector.push_back(basegfx::B3DPolyPolygon(aFill.getB3DPolygon(a))); 136 } 137 138 if(!getSdrLFSAttribute().getFill().isDefault()) 139 { 140 // add fill 141 aRetval = create3DPolyPolygonFillPrimitives( 142 a3DPolyPolygonVector, 143 getTransform(), 144 getTextureSize(), 145 getSdr3DObjectAttribute(), 146 getSdrLFSAttribute().getFill(), 147 getSdrLFSAttribute().getFillFloatTransGradient()); 148 } 149 else 150 { 151 // create simplified 3d hit test geometry 152 aRetval = createHiddenGeometryPrimitives3D( 153 a3DPolyPolygonVector, 154 getTransform(), 155 getTextureSize(), 156 getSdr3DObjectAttribute()); 157 } 158 159 // add line 160 if(!getSdrLFSAttribute().getLine().isDefault()) 161 { 162 basegfx::B3DPolyPolygon aSphere(basegfx::tools::createSpherePolyPolygonFromB3DRange(aUnitRange, getHorizontalSegments(), getVerticalSegments())); 163 const Primitive3DSequence aLines(create3DPolyPolygonLinePrimitives( 164 aSphere, getTransform(), getSdrLFSAttribute().getLine())); 165 appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aLines); 166 } 167 168 // add shadow 169 if(!getSdrLFSAttribute().getShadow().isDefault() 170 && aRetval.hasElements()) 171 { 172 const Primitive3DSequence aShadow(createShadowPrimitive3D( 173 aRetval, getSdrLFSAttribute().getShadow(), getSdr3DObjectAttribute().getShadow3D())); 174 appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aShadow); 175 } 176 177 return aRetval; 178 } 179 180 SdrSpherePrimitive3D::SdrSpherePrimitive3D( 181 const basegfx::B3DHomMatrix& rTransform, 182 const basegfx::B2DVector& rTextureSize, 183 const attribute::SdrLineFillShadowAttribute3D& rSdrLFSAttribute, 184 const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute, 185 sal_uInt32 nHorizontalSegments, 186 sal_uInt32 nVerticalSegments) 187 : SdrPrimitive3D(rTransform, rTextureSize, rSdrLFSAttribute, rSdr3DObjectAttribute), 188 mnHorizontalSegments(nHorizontalSegments), 189 mnVerticalSegments(nVerticalSegments) 190 { 191 } 192 193 bool SdrSpherePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const 194 { 195 if(SdrPrimitive3D::operator==(rPrimitive)) 196 { 197 const SdrSpherePrimitive3D& rCompare = static_cast< const SdrSpherePrimitive3D& >(rPrimitive); 198 199 return (getHorizontalSegments() == rCompare.getHorizontalSegments() 200 && getVerticalSegments() == rCompare.getVerticalSegments()); 201 } 202 203 return false; 204 } 205 206 basegfx::B3DRange SdrSpherePrimitive3D::getB3DRange(const geometry::ViewInformation3D& /*rViewInformation*/) const 207 { 208 // use defaut from sdrPrimitive3D which uses transformation expanded by line width/2 209 // The parent implementation which uses the ranges of the decomposition would be more 210 // corrcet, but for historical reasons it is necessary to do the old method: To get 211 // the range of the non-transformed geometry and transform it then. This leads to different 212 // ranges where the new method is more correct, but the need to keep the old behaviour 213 // has priority here. 214 return getStandard3DRange(); 215 } 216 217 // provide unique ID 218 ImplPrimitrive3DIDBlock(SdrSpherePrimitive3D, PRIMITIVE3D_ID_SDRSPHEREPRIMITIVE3D) 219 220 } // end of namespace primitive3d 221 } // end of namespace drawinglayer 222 223 ////////////////////////////////////////////////////////////////////////////// 224 // eof 225