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