xref: /AOO41X/main/drawinglayer/source/processor3d/defaultprocessor3d.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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/processor3d/defaultprocessor3d.hxx>
32*cdf0e10cSrcweir #include <drawinglayer/primitive3d/textureprimitive3d.hxx>
33*cdf0e10cSrcweir #include <drawinglayer/texture/texture.hxx>
34*cdf0e10cSrcweir #include <drawinglayer/texture/texture3d.hxx>
35*cdf0e10cSrcweir #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
36*cdf0e10cSrcweir #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx>
37*cdf0e10cSrcweir #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
38*cdf0e10cSrcweir #include <basegfx/polygon/b3dpolygontools.hxx>
39*cdf0e10cSrcweir #include <drawinglayer/attribute/materialattribute3d.hxx>
40*cdf0e10cSrcweir #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
41*cdf0e10cSrcweir #include <basegfx/polygon/b3dpolypolygontools.hxx>
42*cdf0e10cSrcweir #include <com/sun/star/drawing/ShadeMode.hpp>
43*cdf0e10cSrcweir #include <drawinglayer/primitive3d/transformprimitive3d.hxx>
44*cdf0e10cSrcweir #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
45*cdf0e10cSrcweir #include <vcl/bitmapex.hxx>
46*cdf0e10cSrcweir #include <drawinglayer/attribute/sdrsceneattribute3d.hxx>
47*cdf0e10cSrcweir #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir using namespace com::sun::star;
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir namespace drawinglayer
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir 	namespace processor3d
58*cdf0e10cSrcweir 	{
59*cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderGradientTexturePrimitive3D(const primitive3d::GradientTexturePrimitive3D& rPrimitive, bool bTransparence)
60*cdf0e10cSrcweir 		{
61*cdf0e10cSrcweir 			const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren();
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir 			if(rSubSequence.hasElements())
64*cdf0e10cSrcweir 			{
65*cdf0e10cSrcweir 				// rescue values
66*cdf0e10cSrcweir 				const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate();
67*cdf0e10cSrcweir 				const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter();
68*cdf0e10cSrcweir 				const bool bOldSimpleTextureActive(getSimpleTextureActive());
69*cdf0e10cSrcweir 				boost::shared_ptr< texture::GeoTexSvx > pOldTex = (bTransparence) ? mpTransparenceGeoTexSvx : mpGeoTexSvx;
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir 				// create texture
72*cdf0e10cSrcweir 				const attribute::FillGradientAttribute& rFillGradient = rPrimitive.getGradient();
73*cdf0e10cSrcweir 				const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY());
74*cdf0e10cSrcweir 				const attribute::GradientStyle aGradientStyle(rFillGradient.getStyle());
75*cdf0e10cSrcweir 				sal_uInt32 nSteps(rFillGradient.getSteps());
76*cdf0e10cSrcweir 				const basegfx::BColor aStart(rFillGradient.getStartColor());
77*cdf0e10cSrcweir 				const basegfx::BColor aEnd(rFillGradient.getEndColor());
78*cdf0e10cSrcweir 				const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5));
79*cdf0e10cSrcweir 				boost::shared_ptr< texture::GeoTexSvx > pNewTex;
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 				if(nMaxSteps)
82*cdf0e10cSrcweir 				{
83*cdf0e10cSrcweir 					// there IS a color distance
84*cdf0e10cSrcweir 					if(nSteps == 0L)
85*cdf0e10cSrcweir 					{
86*cdf0e10cSrcweir 						nSteps = nMaxSteps;
87*cdf0e10cSrcweir 					}
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 					if(nSteps < 2L)
90*cdf0e10cSrcweir 					{
91*cdf0e10cSrcweir 						nSteps = 2L;
92*cdf0e10cSrcweir 					}
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 					if(nSteps > nMaxSteps)
95*cdf0e10cSrcweir 					{
96*cdf0e10cSrcweir 						nSteps = nMaxSteps;
97*cdf0e10cSrcweir 					}
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir 					switch(aGradientStyle)
100*cdf0e10cSrcweir 					{
101*cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_LINEAR:
102*cdf0e10cSrcweir 						{
103*cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientLinear(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getAngle()));
104*cdf0e10cSrcweir 							break;
105*cdf0e10cSrcweir 						}
106*cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_AXIAL:
107*cdf0e10cSrcweir 						{
108*cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientAxial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getAngle()));
109*cdf0e10cSrcweir 							break;
110*cdf0e10cSrcweir 						}
111*cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_RADIAL:
112*cdf0e10cSrcweir 						{
113*cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientRadial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY()));
114*cdf0e10cSrcweir 							break;
115*cdf0e10cSrcweir 						}
116*cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_ELLIPTICAL:
117*cdf0e10cSrcweir 						{
118*cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientElliptical(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle()));
119*cdf0e10cSrcweir 							break;
120*cdf0e10cSrcweir 						}
121*cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_SQUARE:
122*cdf0e10cSrcweir 						{
123*cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientSquare(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle()));
124*cdf0e10cSrcweir 							break;
125*cdf0e10cSrcweir 						}
126*cdf0e10cSrcweir 						case attribute::GRADIENTSTYLE_RECT:
127*cdf0e10cSrcweir 						{
128*cdf0e10cSrcweir 							pNewTex.reset(new texture::GeoTexSvxGradientRect(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle()));
129*cdf0e10cSrcweir 							break;
130*cdf0e10cSrcweir 						}
131*cdf0e10cSrcweir 					}
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir 					mbSimpleTextureActive = false;
134*cdf0e10cSrcweir 				}
135*cdf0e10cSrcweir 				else
136*cdf0e10cSrcweir 				{
137*cdf0e10cSrcweir 					// no color distance -> same color, use simple texture
138*cdf0e10cSrcweir 					pNewTex.reset(new texture::GeoTexSvxMono(aStart, 1.0 - aStart.luminance()));
139*cdf0e10cSrcweir 					mbSimpleTextureActive = true;
140*cdf0e10cSrcweir 				}
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 				// set created texture
143*cdf0e10cSrcweir 				if(bTransparence)
144*cdf0e10cSrcweir 				{
145*cdf0e10cSrcweir 					mpTransparenceGeoTexSvx = pNewTex;
146*cdf0e10cSrcweir 				}
147*cdf0e10cSrcweir 				else
148*cdf0e10cSrcweir 				{
149*cdf0e10cSrcweir 					mpGeoTexSvx = pNewTex;
150*cdf0e10cSrcweir 				}
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir 				// process sub-list
153*cdf0e10cSrcweir 				process(rSubSequence);
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 				// restore values
156*cdf0e10cSrcweir 				mbModulate = bOldModulate;
157*cdf0e10cSrcweir 				mbFilter = bOldFilter;
158*cdf0e10cSrcweir 				mbSimpleTextureActive = bOldSimpleTextureActive;
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir 				if(bTransparence)
161*cdf0e10cSrcweir 				{
162*cdf0e10cSrcweir 					mpTransparenceGeoTexSvx = pOldTex;
163*cdf0e10cSrcweir 				}
164*cdf0e10cSrcweir 				else
165*cdf0e10cSrcweir 				{
166*cdf0e10cSrcweir 					mpGeoTexSvx = pOldTex;
167*cdf0e10cSrcweir 				}
168*cdf0e10cSrcweir 			}
169*cdf0e10cSrcweir 		}
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D& rPrimitive)
172*cdf0e10cSrcweir 		{
173*cdf0e10cSrcweir 			const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren();
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir 			if(rSubSequence.hasElements())
176*cdf0e10cSrcweir 			{
177*cdf0e10cSrcweir 				// rescue values
178*cdf0e10cSrcweir 				const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate();
179*cdf0e10cSrcweir 				const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter();
180*cdf0e10cSrcweir 				boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx;
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir 				// calculate logic pixel size in object coordinates. Create transformation view
183*cdf0e10cSrcweir 				// to object by inverting ObjectToView
184*cdf0e10cSrcweir 				basegfx::B3DHomMatrix aInvObjectToView(getViewInformation3D().getObjectToView());
185*cdf0e10cSrcweir 				aInvObjectToView.invert();
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir 				// back-project discrete coordinates to object coordinates and extract
188*cdf0e10cSrcweir 				// maximum distance
189*cdf0e10cSrcweir 				const basegfx::B3DPoint aZero(aInvObjectToView * basegfx::B3DPoint(0.0, 0.0, 0.0));
190*cdf0e10cSrcweir 				const basegfx::B3DPoint aOne(aInvObjectToView * basegfx::B3DPoint(1.0, 1.0, 1.0));
191*cdf0e10cSrcweir 				const basegfx::B3DVector aLogicPixel(aOne - aZero);
192*cdf0e10cSrcweir 				double fLogicPixelSizeWorld(::std::max(::std::max(fabs(aLogicPixel.getX()), fabs(aLogicPixel.getY())), fabs(aLogicPixel.getZ())));
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 				// calculate logic pixel size in texture coordinates
195*cdf0e10cSrcweir 				const double fLogicTexSizeX(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getX());
196*cdf0e10cSrcweir 				const double fLogicTexSizeY(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getY());
197*cdf0e10cSrcweir 				const double fLogicTexSize(fLogicTexSizeX > fLogicTexSizeY ? fLogicTexSizeX : fLogicTexSizeY);
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 				// create texture and set
200*cdf0e10cSrcweir 				mpGeoTexSvx.reset(new texture::GeoTexSvxMultiHatch(rPrimitive, fLogicTexSize));
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir 				// process sub-list
203*cdf0e10cSrcweir 				process(rSubSequence);
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 				// restore values
206*cdf0e10cSrcweir 				mbModulate = bOldModulate;
207*cdf0e10cSrcweir 				mbFilter = bOldFilter;
208*cdf0e10cSrcweir 				mpGeoTexSvx = pOldTex;
209*cdf0e10cSrcweir 			}
210*cdf0e10cSrcweir 		}
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D& rPrimitive)
213*cdf0e10cSrcweir 		{
214*cdf0e10cSrcweir 			const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren();
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir 			if(rSubSequence.hasElements())
217*cdf0e10cSrcweir 			{
218*cdf0e10cSrcweir 				// rescue values
219*cdf0e10cSrcweir 				const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate();
220*cdf0e10cSrcweir 				const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter();
221*cdf0e10cSrcweir 				boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx;
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir 				// create texture
224*cdf0e10cSrcweir 				const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPrimitive.getFillBitmapAttribute();
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir 				if(rFillBitmapAttribute.getTiling())
227*cdf0e10cSrcweir 				{
228*cdf0e10cSrcweir 					mpGeoTexSvx.reset(new texture::GeoTexSvxBitmapTiled(
229*cdf0e10cSrcweir 						rFillBitmapAttribute.getBitmapEx().GetBitmap(),
230*cdf0e10cSrcweir 						rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(),
231*cdf0e10cSrcweir 						rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize()));
232*cdf0e10cSrcweir 				}
233*cdf0e10cSrcweir 				else
234*cdf0e10cSrcweir 				{
235*cdf0e10cSrcweir 					mpGeoTexSvx.reset(new texture::GeoTexSvxBitmap(
236*cdf0e10cSrcweir 						rFillBitmapAttribute.getBitmapEx().GetBitmap(),
237*cdf0e10cSrcweir 						rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(),
238*cdf0e10cSrcweir 						rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize()));
239*cdf0e10cSrcweir 				}
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir 				// process sub-list
242*cdf0e10cSrcweir 				process(rSubSequence);
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 				// restore values
245*cdf0e10cSrcweir 				mbModulate = bOldModulate;
246*cdf0e10cSrcweir 				mbFilter = bOldFilter;
247*cdf0e10cSrcweir 				mpGeoTexSvx = pOldTex;
248*cdf0e10cSrcweir 			}
249*cdf0e10cSrcweir 		}
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate)
252*cdf0e10cSrcweir 		{
253*cdf0e10cSrcweir 			const primitive3d::Primitive3DSequence& rSubSequence = rModifiedCandidate.getChildren();
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 			if(rSubSequence.hasElements())
256*cdf0e10cSrcweir 			{
257*cdf0e10cSrcweir 				// put modifier on stack
258*cdf0e10cSrcweir 				maBColorModifierStack.push(rModifiedCandidate.getColorModifier());
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 				// process sub-list
261*cdf0e10cSrcweir 				process(rModifiedCandidate.getChildren());
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 				// remove modifier from stack
264*cdf0e10cSrcweir 				maBColorModifierStack.pop();
265*cdf0e10cSrcweir 			}
266*cdf0e10cSrcweir 		}
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive)
269*cdf0e10cSrcweir 		{
270*cdf0e10cSrcweir 			basegfx::B3DPolygon aHairline(rPrimitive.getB3DPolygon());
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir 			if(aHairline.count())
273*cdf0e10cSrcweir 			{
274*cdf0e10cSrcweir 				// hairlines need no extra data, clear it
275*cdf0e10cSrcweir 				aHairline.clearTextureCoordinates();
276*cdf0e10cSrcweir 				aHairline.clearNormals();
277*cdf0e10cSrcweir 				aHairline.clearBColors();
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir 				// transform to device coordinates (-1.0 .. 1.0) and check for visibility
280*cdf0e10cSrcweir 				aHairline.transform(getViewInformation3D().getObjectToView());
281*cdf0e10cSrcweir 				const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aHairline));
282*cdf0e10cSrcweir 				const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY());
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir 				if(a2DRange.overlaps(maRasterRange))
285*cdf0e10cSrcweir 				{
286*cdf0e10cSrcweir 					const attribute::MaterialAttribute3D aMaterial(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor()));
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir 					rasterconvertB3DPolygon(aMaterial, aHairline);
289*cdf0e10cSrcweir 				}
290*cdf0e10cSrcweir 			}
291*cdf0e10cSrcweir 		}
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive)
294*cdf0e10cSrcweir 		{
295*cdf0e10cSrcweir 			basegfx::B3DPolyPolygon aFill(rPrimitive.getB3DPolyPolygon());
296*cdf0e10cSrcweir 			basegfx::BColor aObjectColor(rPrimitive.getMaterial().getColor());
297*cdf0e10cSrcweir 			bool bPaintIt(aFill.count());
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 			// #i98295# get ShadeMode. Correct early when only flat is possible due to missing normals
300*cdf0e10cSrcweir 			const ::com::sun::star::drawing::ShadeMode aShadeMode(
301*cdf0e10cSrcweir 				aFill.areNormalsUsed() ?
302*cdf0e10cSrcweir 					getSdrSceneAttribute().getShadeMode() : ::com::sun::star::drawing::ShadeMode_FLAT);
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir 			if(bPaintIt)
305*cdf0e10cSrcweir 			{
306*cdf0e10cSrcweir 				// get rid of texture coordinates if there is no texture
307*cdf0e10cSrcweir 				if(aFill.areTextureCoordinatesUsed() && !getGeoTexSvx().get() && !getTransparenceGeoTexSvx().get())
308*cdf0e10cSrcweir 				{
309*cdf0e10cSrcweir 					aFill.clearTextureCoordinates();
310*cdf0e10cSrcweir 				}
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir 				// #i98295# get rid of normals and color early when not needed
313*cdf0e10cSrcweir 				if(::com::sun::star::drawing::ShadeMode_FLAT == aShadeMode)
314*cdf0e10cSrcweir 				{
315*cdf0e10cSrcweir 					aFill.clearNormals();
316*cdf0e10cSrcweir 					aFill.clearBColors();
317*cdf0e10cSrcweir 				}
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir 				// transform to device coordinates (-1.0 .. 1.0) and check for visibility
320*cdf0e10cSrcweir 				aFill.transform(getViewInformation3D().getObjectToView());
321*cdf0e10cSrcweir 				const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aFill));
322*cdf0e10cSrcweir 				const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY());
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir 				bPaintIt = a2DRange.overlaps(maRasterRange);
325*cdf0e10cSrcweir 			}
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir 			// check if it shall be painted regarding hiding of normals (backface culling)
328*cdf0e10cSrcweir 			if(bPaintIt && !rPrimitive.getDoubleSided())
329*cdf0e10cSrcweir 			{
330*cdf0e10cSrcweir 				// get plane normal of polygon in view coordinates (with ZBuffer values),
331*cdf0e10cSrcweir 				// left-handed coordinate system
332*cdf0e10cSrcweir 				const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal());
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir 				if(aPlaneNormal.getZ() > 0.0)
335*cdf0e10cSrcweir 				{
336*cdf0e10cSrcweir 					bPaintIt = false;
337*cdf0e10cSrcweir 				}
338*cdf0e10cSrcweir 			}
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir 			if(bPaintIt)
341*cdf0e10cSrcweir 			{
342*cdf0e10cSrcweir 				// prepare ObjectToEye in NormalTransform
343*cdf0e10cSrcweir 				basegfx::B3DHomMatrix aNormalTransform(getViewInformation3D().getOrientation() * getViewInformation3D().getObjectTransformation());
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir 				if(getSdrSceneAttribute().getTwoSidedLighting())
346*cdf0e10cSrcweir 				{
347*cdf0e10cSrcweir 					// get plane normal of polygon in view coordinates (with ZBuffer values),
348*cdf0e10cSrcweir 					// left-handed coordinate system
349*cdf0e10cSrcweir 					const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal());
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir 					if(aPlaneNormal.getZ() > 0.0)
352*cdf0e10cSrcweir 					{
353*cdf0e10cSrcweir 						// mirror normals
354*cdf0e10cSrcweir 						aNormalTransform.scale(-1.0, -1.0, -1.0);
355*cdf0e10cSrcweir 					}
356*cdf0e10cSrcweir 				}
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir 				switch(aShadeMode)
359*cdf0e10cSrcweir 				{
360*cdf0e10cSrcweir 					case ::com::sun::star::drawing::ShadeMode_PHONG:
361*cdf0e10cSrcweir 					{
362*cdf0e10cSrcweir 						// phong shading. Transform normals to eye coor
363*cdf0e10cSrcweir 						aFill.transformNormals(aNormalTransform);
364*cdf0e10cSrcweir 						break;
365*cdf0e10cSrcweir 					}
366*cdf0e10cSrcweir 					case ::com::sun::star::drawing::ShadeMode_SMOOTH:
367*cdf0e10cSrcweir 					{
368*cdf0e10cSrcweir 						// gouraud shading. Transform normals to eye coor
369*cdf0e10cSrcweir 						aFill.transformNormals(aNormalTransform);
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir 						// prepare color model parameters, evtl. use blend color
372*cdf0e10cSrcweir 						const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor());
373*cdf0e10cSrcweir 						const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular());
374*cdf0e10cSrcweir 						const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission());
375*cdf0e10cSrcweir 						const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity());
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir 						// solve color model for each normal vector, set colors at points. Clear normals.
378*cdf0e10cSrcweir 						for(sal_uInt32 a(0L); a < aFill.count(); a++)
379*cdf0e10cSrcweir 						{
380*cdf0e10cSrcweir 							basegfx::B3DPolygon aPartFill(aFill.getB3DPolygon(a));
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir 							for(sal_uInt32 b(0L); b < aPartFill.count(); b++)
383*cdf0e10cSrcweir 							{
384*cdf0e10cSrcweir 								// solve color model. Transform normal to eye coor
385*cdf0e10cSrcweir 								const basegfx::B3DVector aNormal(aPartFill.getNormal(b));
386*cdf0e10cSrcweir 								const basegfx::BColor aSolvedColor(getSdrLightingAttribute().solveColorModel(aNormal, aColor, rSpecular, rEmission, nSpecularIntensity));
387*cdf0e10cSrcweir 								aPartFill.setBColor(b, aSolvedColor);
388*cdf0e10cSrcweir 							}
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir 							// clear normals on this part polygon and write it back
391*cdf0e10cSrcweir 							aPartFill.clearNormals();
392*cdf0e10cSrcweir 							aFill.setB3DPolygon(a, aPartFill);
393*cdf0e10cSrcweir 						}
394*cdf0e10cSrcweir 						break;
395*cdf0e10cSrcweir 					}
396*cdf0e10cSrcweir 					case ::com::sun::star::drawing::ShadeMode_FLAT:
397*cdf0e10cSrcweir 					{
398*cdf0e10cSrcweir 						// flat shading. Get plane vector in eye coordinates
399*cdf0e10cSrcweir 						const basegfx::B3DVector aPlaneEyeNormal(aNormalTransform * rPrimitive.getB3DPolyPolygon().getB3DPolygon(0L).getNormal());
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir 						// prepare color model parameters, evtl. use blend color
402*cdf0e10cSrcweir 						const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor());
403*cdf0e10cSrcweir 						const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular());
404*cdf0e10cSrcweir 						const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission());
405*cdf0e10cSrcweir 						const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity());
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir 						// solve color model for plane vector and use that color for whole plane
408*cdf0e10cSrcweir 						aObjectColor = getSdrLightingAttribute().solveColorModel(aPlaneEyeNormal, aColor, rSpecular, rEmission, nSpecularIntensity);
409*cdf0e10cSrcweir 						break;
410*cdf0e10cSrcweir 					}
411*cdf0e10cSrcweir 					default: // case ::com::sun::star::drawing::ShadeMode_DRAFT:
412*cdf0e10cSrcweir 					{
413*cdf0e10cSrcweir 						// draft, just use object color which is already set. Delete all other infos
414*cdf0e10cSrcweir 						aFill.clearNormals();
415*cdf0e10cSrcweir 						aFill.clearBColors();
416*cdf0e10cSrcweir 						break;
417*cdf0e10cSrcweir 					}
418*cdf0e10cSrcweir 				}
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir 				// draw it to ZBuffer
421*cdf0e10cSrcweir 				const attribute::MaterialAttribute3D aMaterial(
422*cdf0e10cSrcweir 					maBColorModifierStack.getModifiedColor(aObjectColor),
423*cdf0e10cSrcweir 					rPrimitive.getMaterial().getSpecular(),
424*cdf0e10cSrcweir 					rPrimitive.getMaterial().getEmission(),
425*cdf0e10cSrcweir 					rPrimitive.getMaterial().getSpecularIntensity());
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir 				rasterconvertB3DPolyPolygon(aMaterial, aFill);
428*cdf0e10cSrcweir 			}
429*cdf0e10cSrcweir 		}
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir 		void DefaultProcessor3D::impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D& rTransformCandidate)
432*cdf0e10cSrcweir 		{
433*cdf0e10cSrcweir 			// transform group. Remember current transformations
434*cdf0e10cSrcweir 			const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir 			// create new transformation; add new object transform from right side
437*cdf0e10cSrcweir 			const geometry::ViewInformation3D aNewViewInformation3D(
438*cdf0e10cSrcweir 				aLastViewInformation3D.getObjectTransformation() * rTransformCandidate.getTransformation(),
439*cdf0e10cSrcweir 				aLastViewInformation3D.getOrientation(),
440*cdf0e10cSrcweir 				aLastViewInformation3D.getProjection(),
441*cdf0e10cSrcweir 				aLastViewInformation3D.getDeviceToView(),
442*cdf0e10cSrcweir 				aLastViewInformation3D.getViewTime(),
443*cdf0e10cSrcweir 				aLastViewInformation3D.getExtendedInformationSequence());
444*cdf0e10cSrcweir 			updateViewInformation(aNewViewInformation3D);
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir 			// let break down recursively
447*cdf0e10cSrcweir 			process(rTransformCandidate.getChildren());
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir 			// restore transformations
450*cdf0e10cSrcweir 			updateViewInformation(aLastViewInformation3D);
451*cdf0e10cSrcweir 		}
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir 		void DefaultProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive)
454*cdf0e10cSrcweir 		{
455*cdf0e10cSrcweir 			// it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
456*cdf0e10cSrcweir 			switch(rBasePrimitive.getPrimitive3DID())
457*cdf0e10cSrcweir 			{
458*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_GRADIENTTEXTUREPRIMITIVE3D :
459*cdf0e10cSrcweir 				{
460*cdf0e10cSrcweir 					// GradientTexturePrimitive3D
461*cdf0e10cSrcweir 					const primitive3d::GradientTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::GradientTexturePrimitive3D& >(rBasePrimitive);
462*cdf0e10cSrcweir 					impRenderGradientTexturePrimitive3D(rPrimitive, false);
463*cdf0e10cSrcweir 					break;
464*cdf0e10cSrcweir 				}
465*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D :
466*cdf0e10cSrcweir 				{
467*cdf0e10cSrcweir 					// HatchTexturePrimitive3D
468*cdf0e10cSrcweir 					static bool bDoHatchDecomposition(false);
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir 					if(bDoHatchDecomposition)
471*cdf0e10cSrcweir 					{
472*cdf0e10cSrcweir 						// let break down
473*cdf0e10cSrcweir 						process(rBasePrimitive.get3DDecomposition(getViewInformation3D()));
474*cdf0e10cSrcweir 					}
475*cdf0e10cSrcweir 					else
476*cdf0e10cSrcweir 					{
477*cdf0e10cSrcweir 						// hatchTexturePrimitive3D
478*cdf0e10cSrcweir 						const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rBasePrimitive);
479*cdf0e10cSrcweir 						impRenderHatchTexturePrimitive3D(rPrimitive);
480*cdf0e10cSrcweir 					}
481*cdf0e10cSrcweir 					break;
482*cdf0e10cSrcweir 				}
483*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_BITMAPTEXTUREPRIMITIVE3D :
484*cdf0e10cSrcweir 				{
485*cdf0e10cSrcweir 					// BitmapTexturePrimitive3D
486*cdf0e10cSrcweir 					const primitive3d::BitmapTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::BitmapTexturePrimitive3D& >(rBasePrimitive);
487*cdf0e10cSrcweir 					impRenderBitmapTexturePrimitive3D(rPrimitive);
488*cdf0e10cSrcweir 					break;
489*cdf0e10cSrcweir 				}
490*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_TRANSPARENCETEXTUREPRIMITIVE3D :
491*cdf0e10cSrcweir 				{
492*cdf0e10cSrcweir 					// TransparenceTexturePrimitive3D
493*cdf0e10cSrcweir 					const primitive3d::TransparenceTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::TransparenceTexturePrimitive3D& >(rBasePrimitive);
494*cdf0e10cSrcweir                     mnTransparenceCounter++;
495*cdf0e10cSrcweir 					impRenderGradientTexturePrimitive3D(rPrimitive, true);
496*cdf0e10cSrcweir                     mnTransparenceCounter--;
497*cdf0e10cSrcweir 					break;
498*cdf0e10cSrcweir 				}
499*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_MODIFIEDCOLORPRIMITIVE3D :
500*cdf0e10cSrcweir 				{
501*cdf0e10cSrcweir 					// ModifiedColorPrimitive3D
502*cdf0e10cSrcweir 					// Force output to unified color.
503*cdf0e10cSrcweir 					const primitive3d::ModifiedColorPrimitive3D& rPrimitive = static_cast< const primitive3d::ModifiedColorPrimitive3D& >(rBasePrimitive);
504*cdf0e10cSrcweir 					impRenderModifiedColorPrimitive3D(rPrimitive);
505*cdf0e10cSrcweir 					break;
506*cdf0e10cSrcweir 				}
507*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
508*cdf0e10cSrcweir 				{
509*cdf0e10cSrcweir 					// directdraw of PolygonHairlinePrimitive3D
510*cdf0e10cSrcweir 					const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rBasePrimitive);
511*cdf0e10cSrcweir 					impRenderPolygonHairlinePrimitive3D(rPrimitive);
512*cdf0e10cSrcweir 					break;
513*cdf0e10cSrcweir 				}
514*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
515*cdf0e10cSrcweir 				{
516*cdf0e10cSrcweir 					// directdraw of PolyPolygonMaterialPrimitive3D
517*cdf0e10cSrcweir 					const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rBasePrimitive);
518*cdf0e10cSrcweir 					impRenderPolyPolygonMaterialPrimitive3D(rPrimitive);
519*cdf0e10cSrcweir 					break;
520*cdf0e10cSrcweir 				}
521*cdf0e10cSrcweir 				case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
522*cdf0e10cSrcweir 				{
523*cdf0e10cSrcweir 					// transform group (TransformPrimitive3D)
524*cdf0e10cSrcweir 					impRenderTransformPrimitive3D(static_cast< const primitive3d::TransformPrimitive3D& >(rBasePrimitive));
525*cdf0e10cSrcweir 					break;
526*cdf0e10cSrcweir 				}
527*cdf0e10cSrcweir 				default:
528*cdf0e10cSrcweir 				{
529*cdf0e10cSrcweir 					// process recursively
530*cdf0e10cSrcweir 					process(rBasePrimitive.get3DDecomposition(getViewInformation3D()));
531*cdf0e10cSrcweir 					break;
532*cdf0e10cSrcweir 				}
533*cdf0e10cSrcweir 			}
534*cdf0e10cSrcweir 		}
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir 		DefaultProcessor3D::DefaultProcessor3D(
537*cdf0e10cSrcweir 			const geometry::ViewInformation3D& rViewInformation,
538*cdf0e10cSrcweir 			const attribute::SdrSceneAttribute& rSdrSceneAttribute,
539*cdf0e10cSrcweir 			const attribute::SdrLightingAttribute& rSdrLightingAttribute)
540*cdf0e10cSrcweir 		:	BaseProcessor3D(rViewInformation),
541*cdf0e10cSrcweir 			mrSdrSceneAttribute(rSdrSceneAttribute),
542*cdf0e10cSrcweir 			mrSdrLightingAttribute(rSdrLightingAttribute),
543*cdf0e10cSrcweir 			maRasterRange(),
544*cdf0e10cSrcweir 			maBColorModifierStack(),
545*cdf0e10cSrcweir 			mpGeoTexSvx(),
546*cdf0e10cSrcweir 			mpTransparenceGeoTexSvx(),
547*cdf0e10cSrcweir             maDrawinglayerOpt(),
548*cdf0e10cSrcweir             mnTransparenceCounter(0),
549*cdf0e10cSrcweir 			mbModulate(false),
550*cdf0e10cSrcweir 			mbFilter(false),
551*cdf0e10cSrcweir 			mbSimpleTextureActive(false)
552*cdf0e10cSrcweir 		{
553*cdf0e10cSrcweir 			// a derivation has to set maRasterRange which is used in the basic render methods.
554*cdf0e10cSrcweir 			// Setting to default here ([0.0 .. 1.0] in X,Y) to avoid problems
555*cdf0e10cSrcweir 			maRasterRange.expand(basegfx::B2DTuple(0.0, 0.0));
556*cdf0e10cSrcweir 			maRasterRange.expand(basegfx::B2DTuple(1.0, 1.0));
557*cdf0e10cSrcweir 		}
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir 		DefaultProcessor3D::~DefaultProcessor3D()
560*cdf0e10cSrcweir 		{
561*cdf0e10cSrcweir 		}
562*cdf0e10cSrcweir 	} // end of namespace processor3d
563*cdf0e10cSrcweir } // end of namespace drawinglayer
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
566*cdf0e10cSrcweir // eof
567