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