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/sdrcubeprimitive3d.hxx> 32 #include <basegfx/polygon/b3dpolypolygontools.hxx> 33 #include <basegfx/polygon/b3dpolygon.hxx> 34 #include <basegfx/matrix/b2dhommatrix.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 SdrCubePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const 53 { 54 const basegfx::B3DRange aUnitRange(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); 55 Primitive3DSequence aRetval; 56 basegfx::B3DPolyPolygon aFill(basegfx::tools::createCubeFillPolyPolygonFromB3DRange(aUnitRange)); 57 58 // normal creation 59 if(!getSdrLFSAttribute().getFill().isDefault()) 60 { 61 if(::com::sun::star::drawing::NormalsKind_SPECIFIC == getSdr3DObjectAttribute().getNormalsKind() 62 || ::com::sun::star::drawing::NormalsKind_SPHERE == getSdr3DObjectAttribute().getNormalsKind()) 63 { 64 // create sphere normals 65 const basegfx::B3DPoint aCenter(basegfx::tools::getRange(aFill).getCenter()); 66 aFill = basegfx::tools::applyDefaultNormalsSphere(aFill, aCenter); 67 } 68 69 if(getSdr3DObjectAttribute().getNormalsInvert()) 70 { 71 // invert normals 72 aFill = basegfx::tools::invertNormals(aFill); 73 } 74 } 75 76 // texture coordinates 77 if(!getSdrLFSAttribute().getFill().isDefault()) 78 { 79 // handle texture coordinates X 80 const bool bParallelX(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == getSdr3DObjectAttribute().getTextureProjectionX()); 81 const bool bObjectSpecificX(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionX()); 82 const bool bSphereX(!bParallelX && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == getSdr3DObjectAttribute().getTextureProjectionX())); 83 84 // handle texture coordinates Y 85 const bool bParallelY(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == getSdr3DObjectAttribute().getTextureProjectionY()); 86 const bool bObjectSpecificY(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionY()); 87 const bool bSphereY(!bParallelY && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == getSdr3DObjectAttribute().getTextureProjectionY())); 88 89 if(bParallelX || bParallelY) 90 { 91 // apply parallel texture coordinates in X and/or Y 92 const basegfx::B3DRange aRange(basegfx::tools::getRange(aFill)); 93 aFill = basegfx::tools::applyDefaultTextureCoordinatesParallel(aFill, aRange, bParallelX, bParallelY); 94 } 95 96 if(bSphereX || bSphereY) 97 { 98 // apply spherical texture coordinates in X and/or Y 99 const basegfx::B3DRange aRange(basegfx::tools::getRange(aFill)); 100 const basegfx::B3DPoint aCenter(aRange.getCenter()); 101 aFill = basegfx::tools::applyDefaultTextureCoordinatesSphere(aFill, aCenter, bSphereX, bSphereY); 102 } 103 104 if(bObjectSpecificX || bObjectSpecificY) 105 { 106 // object-specific 107 for(sal_uInt32 a(0L); a < aFill.count(); a++) 108 { 109 basegfx::B3DPolygon aTmpPoly(aFill.getB3DPolygon(a)); 110 111 if(aTmpPoly.count() >= 4L) 112 { 113 for(sal_uInt32 b(0L); b < 4L; b++) 114 { 115 basegfx::B2DPoint aPoint(aTmpPoly.getTextureCoordinate(b)); 116 117 if(bObjectSpecificX) 118 { 119 aPoint.setX((1L == b || 2L == b) ? 1.0 : 0.0); 120 } 121 122 if(bObjectSpecificY) 123 { 124 aPoint.setY((2L == b || 3L == b) ? 1.0 : 0.0); 125 } 126 127 aTmpPoly.setTextureCoordinate(b, aPoint); 128 } 129 130 aFill.setB3DPolygon(a, aTmpPoly); 131 } 132 } 133 } 134 135 // transform texture coordinates to texture size 136 basegfx::B2DHomMatrix aTexMatrix; 137 aTexMatrix.scale(getTextureSize().getX(), getTextureSize().getY()); 138 aFill.transformTextureCoordiantes(aTexMatrix); 139 } 140 141 // build vector of PolyPolygons 142 ::std::vector< basegfx::B3DPolyPolygon > a3DPolyPolygonVector; 143 144 for(sal_uInt32 a(0L); a < aFill.count(); a++) 145 { 146 a3DPolyPolygonVector.push_back(basegfx::B3DPolyPolygon(aFill.getB3DPolygon(a))); 147 } 148 149 if(!getSdrLFSAttribute().getFill().isDefault()) 150 { 151 // add fill 152 aRetval = create3DPolyPolygonFillPrimitives( 153 a3DPolyPolygonVector, 154 getTransform(), 155 getTextureSize(), 156 getSdr3DObjectAttribute(), 157 getSdrLFSAttribute().getFill(), 158 getSdrLFSAttribute().getFillFloatTransGradient()); 159 } 160 else 161 { 162 // create simplified 3d hit test geometry 163 aRetval = createHiddenGeometryPrimitives3D( 164 a3DPolyPolygonVector, 165 getTransform(), 166 getTextureSize(), 167 getSdr3DObjectAttribute()); 168 } 169 170 // add line 171 if(!getSdrLFSAttribute().getLine().isDefault()) 172 { 173 basegfx::B3DPolyPolygon aLine(basegfx::tools::createCubePolyPolygonFromB3DRange(aUnitRange)); 174 const Primitive3DSequence aLines(create3DPolyPolygonLinePrimitives( 175 aLine, getTransform(), getSdrLFSAttribute().getLine())); 176 appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aLines); 177 } 178 179 // add shadow 180 if(!getSdrLFSAttribute().getShadow().isDefault() && aRetval.hasElements()) 181 { 182 const Primitive3DSequence aShadow(createShadowPrimitive3D( 183 aRetval, getSdrLFSAttribute().getShadow(), getSdr3DObjectAttribute().getShadow3D())); 184 appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aShadow); 185 } 186 187 return aRetval; 188 } 189 190 SdrCubePrimitive3D::SdrCubePrimitive3D( 191 const basegfx::B3DHomMatrix& rTransform, 192 const basegfx::B2DVector& rTextureSize, 193 const attribute::SdrLineFillShadowAttribute3D& rSdrLFSAttribute, 194 const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute) 195 : SdrPrimitive3D(rTransform, rTextureSize, rSdrLFSAttribute, rSdr3DObjectAttribute) 196 { 197 } 198 199 bool SdrCubePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const 200 { 201 return SdrPrimitive3D::operator==(rPrimitive); 202 } 203 204 basegfx::B3DRange SdrCubePrimitive3D::getB3DRange(const geometry::ViewInformation3D& /*rViewInformation*/) const 205 { 206 // use defaut from sdrPrimitive3D which uses transformation expanded by line width/2. 207 // The parent implementation which uses the ranges of the decomposition would be more 208 // corrcet, but for historical reasons it is necessary to do the old method: To get 209 // the range of the non-transformed geometry and transform it then. This leads to different 210 // ranges where the new method is more correct, but the need to keep the old behaviour 211 // has priority here. 212 return getStandard3DRange(); 213 } 214 215 // provide unique ID 216 ImplPrimitrive3DIDBlock(SdrCubePrimitive3D, PRIMITIVE3D_ID_SDRCUBEPRIMITIVE3D) 217 218 } // end of namespace primitive3d 219 } // end of namespace drawinglayer 220 221 ////////////////////////////////////////////////////////////////////////////// 222 // eof 223