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