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