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