xref: /trunk/main/drawinglayer/source/primitive3d/sdrcubeprimitive3d.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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