LCOV - code coverage report
Current view: top level - drawinglayer/source/processor3d - shadow3dextractor.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 53 111 47.7 %
Date: 2012-08-25 Functions: 5 8 62.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 77 291 26.5 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <drawinglayer/processor3d/shadow3dextractor.hxx>
      30                 :            : #include <drawinglayer/primitive3d/shadowprimitive3d.hxx>
      31                 :            : #include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
      32                 :            : #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
      33                 :            : #include <drawinglayer/primitive3d/transformprimitive3d.hxx>
      34                 :            : #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
      35                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      36                 :            : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
      37                 :            : #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
      38                 :            : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      39                 :            : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
      40                 :            : #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
      41                 :            : 
      42                 :            : //////////////////////////////////////////////////////////////////////////////
      43                 :            : 
      44                 :            : using namespace com::sun::star;
      45                 :            : 
      46                 :            : //////////////////////////////////////////////////////////////////////////////
      47                 :            : 
      48                 :            : namespace drawinglayer
      49                 :            : {
      50                 :            :     namespace processor3d
      51                 :            :     {
      52                 :            :         /// helper to convert from BasePrimitive2DVector to primitive2d::Primitive2DSequence
      53                 :         15 :         const primitive2d::Primitive2DSequence Shadow3DExtractingProcessor::getPrimitive2DSequenceFromBasePrimitive2DVector(
      54                 :            :             const BasePrimitive2DVector& rVector) const
      55                 :            :         {
      56                 :         15 :             const sal_uInt32 nCount(rVector.size());
      57                 :         15 :             primitive2d::Primitive2DSequence aRetval(nCount);
      58                 :            : 
      59         [ -  + ]:         15 :             for(sal_uInt32 a(0); a < nCount; a++)
      60                 :            :             {
      61 [ #  # ][ #  # ]:          0 :                 aRetval[a] = rVector[a];
         [ #  # ][ #  # ]
      62                 :            :             }
      63                 :            : 
      64                 :            :             // all entries taken over; no need to delete entries, just reset to
      65                 :            :             // mark as empty
      66                 :         15 :             const_cast< BasePrimitive2DVector& >(rVector).clear();
      67                 :            : 
      68                 :         15 :             return aRetval;
      69                 :            :         }
      70                 :            : 
      71                 :            :         // as tooling, the process() implementation takes over API handling and calls this
      72                 :            :         // virtual render method when the primitive implementation is BasePrimitive3D-based.
      73                 :       2164 :         void Shadow3DExtractingProcessor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate)
      74                 :            :         {
      75                 :            :             // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
      76   [ -  +  +  +  :       2164 :             switch(rCandidate.getPrimitive3DID())
                      + ]
      77                 :            :             {
      78                 :            :                 case PRIMITIVE3D_ID_SHADOWPRIMITIVE3D :
      79                 :            :                 {
      80                 :            :                     // shadow3d object. Call recursive with content and start conversion
      81                 :          0 :                     const primitive3d::ShadowPrimitive3D& rPrimitive = static_cast< const primitive3d::ShadowPrimitive3D& >(rCandidate);
      82                 :            : 
      83                 :            :                     // set new target
      84         [ #  # ]:          0 :                     BasePrimitive2DVector aNewSubList;
      85                 :          0 :                     BasePrimitive2DVector* pLastTargetSequence = mpPrimitive2DSequence;
      86                 :          0 :                     mpPrimitive2DSequence = &aNewSubList;
      87                 :            : 
      88                 :            :                     // activate convert
      89                 :          0 :                     const bool bLastConvert(mbConvert);
      90                 :          0 :                     mbConvert = true;
      91                 :            : 
      92                 :            :                     // set projection flag
      93                 :          0 :                     const bool bLastUseProjection(mbUseProjection);
      94                 :          0 :                     mbUseProjection = rPrimitive.getShadow3D();
      95                 :            : 
      96                 :            :                     // process content
      97 [ #  # ][ #  # ]:          0 :                     process(rPrimitive.getChildren());
                 [ #  # ]
      98                 :            : 
      99                 :            :                     // restore values
     100                 :          0 :                     mbUseProjection = bLastUseProjection;
     101                 :          0 :                     mbConvert = bLastConvert;
     102                 :          0 :                     mpPrimitive2DSequence = pLastTargetSequence;
     103                 :            : 
     104                 :            :                     // create 2d shadow primitive with result. This also fetches all entries
     105                 :            :                     // from aNewSubList, so there is no need to delete them
     106                 :            :                     primitive2d::BasePrimitive2D* pNew = new primitive2d::ShadowPrimitive2D(
     107                 :            :                         rPrimitive.getShadowTransform(),
     108                 :            :                         rPrimitive.getShadowColor(),
     109 [ #  # ][ #  # ]:          0 :                         getPrimitive2DSequenceFromBasePrimitive2DVector(aNewSubList));
                 [ #  # ]
     110                 :            : 
     111         [ #  # ]:          0 :                     if(basegfx::fTools::more(rPrimitive.getShadowTransparence(), 0.0))
     112                 :            :                     {
     113                 :            :                         // create simpleTransparencePrimitive, add created primitives
     114 [ #  # ][ #  # ]:          0 :                         const primitive2d::Primitive2DReference xRef(pNew);
     115         [ #  # ]:          0 :                         const primitive2d::Primitive2DSequence aNewTransPrimitiveVector(&xRef, 1);
     116                 :            : 
     117                 :            :                         pNew = new primitive2d::UnifiedTransparencePrimitive2D(
     118                 :            :                             aNewTransPrimitiveVector,
     119 [ #  # ][ #  # ]:          0 :                             rPrimitive.getShadowTransparence());
     120                 :            :                     }
     121                 :            : 
     122         [ #  # ]:          0 :                     mpPrimitive2DSequence->push_back(pNew);
     123                 :            : 
     124                 :          0 :                     break;
     125                 :            :                 }
     126                 :            :                 case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
     127                 :            :                 {
     128                 :            :                     // transform group. Remember current transformations
     129                 :        198 :                     const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate);
     130         [ +  - ]:        198 :                     const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
     131                 :            : 
     132                 :            :                     // create new transformation; add new object transform from right side
     133                 :            :                     const geometry::ViewInformation3D aNewViewInformation3D(
     134         [ +  - ]:        198 :                         aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(),
     135         [ +  - ]:        198 :                         aLastViewInformation3D.getOrientation(),
     136         [ +  - ]:        198 :                         aLastViewInformation3D.getProjection(),
     137         [ +  - ]:        198 :                         aLastViewInformation3D.getDeviceToView(),
     138                 :            :                         aLastViewInformation3D.getViewTime(),
     139 [ +  - ][ +  - ]:        396 :                         aLastViewInformation3D.getExtendedInformationSequence());
         [ +  - ][ +  - ]
                 [ +  - ]
     140         [ +  - ]:        198 :                     updateViewInformation(aNewViewInformation3D);
     141                 :            : 
     142         [ +  - ]:        198 :                     if(mbShadowProjectionIsValid)
     143                 :            :                     {
     144                 :            :                         // update buffered WorldToEye and EyeToView
     145 [ +  - ][ +  - ]:        198 :                         maWorldToEye = getViewInformation3D().getOrientation() * getViewInformation3D().getObjectTransformation();
         [ +  - ][ +  - ]
                 [ +  - ]
     146 [ +  - ][ +  - ]:        198 :                         maEyeToView = getViewInformation3D().getDeviceToView() * getViewInformation3D().getProjection();
         [ +  - ][ +  - ]
                 [ +  - ]
     147                 :            :                     }
     148                 :            : 
     149                 :            :                     // let break down
     150 [ +  - ][ +  - ]:        198 :                     process(rPrimitive.getChildren());
                 [ +  - ]
     151                 :            : 
     152                 :            :                     // restore transformations
     153         [ +  - ]:        198 :                     updateViewInformation(aLastViewInformation3D);
     154                 :            : 
     155         [ +  - ]:        198 :                     if(mbShadowProjectionIsValid)
     156                 :            :                     {
     157                 :            :                         // update buffered WorldToEye and EyeToView
     158 [ +  - ][ +  - ]:        198 :                         maWorldToEye = getViewInformation3D().getOrientation() * getViewInformation3D().getObjectTransformation();
         [ +  - ][ +  - ]
                 [ +  - ]
     159 [ +  - ][ +  - ]:        198 :                         maEyeToView = getViewInformation3D().getDeviceToView() * getViewInformation3D().getProjection();
         [ +  - ][ +  - ]
                 [ +  - ]
     160                 :            :                     }
     161 [ +  - ][ +  - ]:        198 :                     break;
     162                 :            :                 }
     163                 :            :                 case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
     164                 :            :                 {
     165                 :            :                     // PolygonHairlinePrimitive3D
     166         [ -  + ]:        766 :                     if(mbConvert)
     167                 :            :                     {
     168                 :          0 :                         const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rCandidate);
     169         [ #  # ]:          0 :                         basegfx::B2DPolygon a2DHairline;
     170                 :            : 
     171         [ #  # ]:          0 :                         if(mbUseProjection)
     172                 :            :                         {
     173         [ #  # ]:          0 :                             if(mbShadowProjectionIsValid)
     174                 :            :                             {
     175 [ #  # ][ #  # ]:          0 :                                 a2DHairline = impDoShadowProjection(rPrimitive.getB3DPolygon());
                 [ #  # ]
     176                 :            :                             }
     177                 :            :                         }
     178                 :            :                         else
     179                 :            :                         {
     180 [ #  # ][ #  # ]:          0 :                             a2DHairline = basegfx::tools::createB2DPolygonFromB3DPolygon(rPrimitive.getB3DPolygon(), getViewInformation3D().getObjectToView());
         [ #  # ][ #  # ]
     181                 :            :                         }
     182                 :            : 
     183 [ #  # ][ #  # ]:          0 :                         if(a2DHairline.count())
     184                 :            :                         {
     185         [ #  # ]:          0 :                             a2DHairline.transform(getObjectTransformation());
     186                 :            :                             mpPrimitive2DSequence->push_back(
     187                 :            :                                 new primitive2d::PolygonHairlinePrimitive2D(
     188                 :            :                                     a2DHairline,
     189 [ #  # ][ #  # ]:          0 :                                     maPrimitiveColor));
     190         [ #  # ]:          0 :                         }
     191                 :            :                     }
     192                 :        766 :                     break;
     193                 :            :                 }
     194                 :            :                 case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
     195                 :            :                 {
     196                 :            :                     // PolyPolygonMaterialPrimitive3D
     197         [ -  + ]:        583 :                     if(mbConvert)
     198                 :            :                     {
     199                 :          0 :                         const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate);
     200         [ #  # ]:          0 :                         basegfx::B2DPolyPolygon a2DFill;
     201                 :            : 
     202         [ #  # ]:          0 :                         if(mbUseProjection)
     203                 :            :                         {
     204         [ #  # ]:          0 :                             if(mbShadowProjectionIsValid)
     205                 :            :                             {
     206 [ #  # ][ #  # ]:          0 :                                 a2DFill = impDoShadowProjection(rPrimitive.getB3DPolyPolygon());
                 [ #  # ]
     207                 :            :                             }
     208                 :            :                         }
     209                 :            :                         else
     210                 :            :                         {
     211 [ #  # ][ #  # ]:          0 :                             a2DFill = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rPrimitive.getB3DPolyPolygon(), getViewInformation3D().getObjectToView());
         [ #  # ][ #  # ]
     212                 :            :                         }
     213                 :            : 
     214 [ #  # ][ #  # ]:          0 :                         if(a2DFill.count())
     215                 :            :                         {
     216         [ #  # ]:          0 :                             a2DFill.transform(getObjectTransformation());
     217                 :            :                             mpPrimitive2DSequence->push_back(
     218                 :            :                                 new primitive2d::PolyPolygonColorPrimitive2D(
     219                 :            :                                     a2DFill,
     220 [ #  # ][ #  # ]:          0 :                                     maPrimitiveColor));
     221         [ #  # ]:          0 :                         }
     222                 :            :                     }
     223                 :        583 :                     break;
     224                 :            :                 }
     225                 :            :                 default :
     226                 :            :                 {
     227                 :            :                     // process recursively
     228         [ +  - ]:        617 :                     process(rCandidate.get3DDecomposition(getViewInformation3D()));
     229                 :        617 :                     break;
     230                 :            :                 }
     231                 :            :             }
     232                 :       2164 :         }
     233                 :            : 
     234                 :         15 :         Shadow3DExtractingProcessor::Shadow3DExtractingProcessor(
     235                 :            :             const geometry::ViewInformation3D& rViewInformation,
     236                 :            :             const basegfx::B2DHomMatrix& rObjectTransformation,
     237                 :            :             const basegfx::B3DVector& rLightNormal,
     238                 :            :             double fShadowSlant,
     239                 :            :             const basegfx::B3DRange& rContained3DRange)
     240                 :            :         :   BaseProcessor3D(rViewInformation),
     241                 :            :             maPrimitive2DSequence(),
     242                 :            :             mpPrimitive2DSequence(&maPrimitive2DSequence),
     243                 :            :             maObjectTransformation(rObjectTransformation),
     244                 :            :             maWorldToEye(),
     245                 :            :             maEyeToView(),
     246                 :            :             maLightNormal(rLightNormal),
     247                 :            :             maShadowPlaneNormal(),
     248                 :            :             maPlanePoint(),
     249                 :            :             mfLightPlaneScalar(0.0),
     250                 :            :             maPrimitiveColor(),
     251                 :            :             mbShadowProjectionIsValid(false),
     252                 :            :             mbConvert(false),
     253 [ +  - ][ +  - ]:         15 :             mbUseProjection(false)
         [ +  - ][ +  - ]
     254                 :            :         {
     255                 :            :             // normalize light normal, get and normalize shadow plane normal and calculate scalar from it
     256         [ +  - ]:         15 :             maLightNormal.normalize();
     257         [ +  - ]:         15 :             maShadowPlaneNormal = basegfx::B3DVector(0.0, sin(fShadowSlant), cos(fShadowSlant));
     258         [ +  - ]:         15 :             maShadowPlaneNormal.normalize();
     259                 :         15 :             mfLightPlaneScalar = maLightNormal.scalar(maShadowPlaneNormal);
     260                 :            : 
     261                 :            :             // use only when scalar is > 0.0, so the light is in front of the object
     262         [ +  - ]:         15 :             if(basegfx::fTools::more(mfLightPlaneScalar, 0.0))
     263                 :            :             {
     264                 :            :                 // prepare buffered WorldToEye and EyeToView
     265 [ +  - ][ +  - ]:         15 :                 maWorldToEye = getViewInformation3D().getOrientation() * getViewInformation3D().getObjectTransformation();
         [ +  - ][ +  - ]
                 [ +  - ]
     266 [ +  - ][ +  - ]:         15 :                 maEyeToView = getViewInformation3D().getDeviceToView() * getViewInformation3D().getProjection();
         [ +  - ][ +  - ]
                 [ +  - ]
     267                 :            : 
     268                 :            :                 // calculate range to get front edge around which to rotate the shadow's projection
     269                 :         15 :                 basegfx::B3DRange aContained3DRange(rContained3DRange);
     270         [ +  - ]:         15 :                 aContained3DRange.transform(getWorldToEye());
     271 [ -  + ][ #  # ]:         15 :                 maPlanePoint.setX(maShadowPlaneNormal.getX() < 0.0 ? aContained3DRange.getMinX() : aContained3DRange.getMaxX());
                 [ +  - ]
     272 [ #  # ][ +  - ]:         15 :                 maPlanePoint.setY(maShadowPlaneNormal.getY() > 0.0 ? aContained3DRange.getMinY() : aContained3DRange.getMaxY());
                 [ -  + ]
     273 [ +  - ][ +  - ]:         15 :                 maPlanePoint.setZ(aContained3DRange.getMinZ() - (aContained3DRange.getDepth() / 8.0));
     274                 :            : 
     275                 :            :                 // set flag that shadow projection is prepared and allowed
     276                 :         15 :                 mbShadowProjectionIsValid = true;
     277                 :            :             }
     278                 :         15 :         }
     279                 :            : 
     280 [ +  - ][ +  - ]:         15 :         Shadow3DExtractingProcessor::~Shadow3DExtractingProcessor()
                 [ +  - ]
     281                 :            :         {
     282                 :            :             OSL_ENSURE(0 == maPrimitive2DSequence.size(),
     283                 :            :                 "OOps, someone used Shadow3DExtractingProcessor, but did not fetch the results (!)");
     284         [ -  + ]:         15 :             for(sal_uInt32 a(0); a < maPrimitive2DSequence.size(); a++)
     285                 :            :             {
     286 [ #  # ][ #  # ]:          0 :                 delete maPrimitive2DSequence[a];
                 [ #  # ]
     287                 :            :             }
     288         [ -  + ]:         15 :         }
     289                 :            : 
     290                 :          0 :         basegfx::B2DPolygon Shadow3DExtractingProcessor::impDoShadowProjection(const basegfx::B3DPolygon& rSource)
     291                 :            :         {
     292                 :          0 :             basegfx::B2DPolygon aRetval;
     293                 :            : 
     294 [ #  # ][ #  # ]:          0 :             for(sal_uInt32 a(0L); a < rSource.count(); a++)
     295                 :            :             {
     296                 :            :                 // get point, transform to eye coordinate system
     297         [ #  # ]:          0 :                 basegfx::B3DPoint aCandidate(rSource.getB3DPoint(a));
     298         [ #  # ]:          0 :                 aCandidate *= getWorldToEye();
     299                 :            : 
     300                 :            :                 // we are in eye coordinates
     301                 :            :                 // ray is (aCandidate + fCut * maLightNormal)
     302                 :            :                 // plane is (maPlanePoint, maShadowPlaneNormal)
     303                 :            :                 // maLightNormal.scalar(maShadowPlaneNormal) is already in mfLightPlaneScalar and > 0.0
     304                 :            :                 // get cut point of ray with shadow plane
     305                 :          0 :                 const double fCut(basegfx::B3DVector(maPlanePoint - aCandidate).scalar(maShadowPlaneNormal) / mfLightPlaneScalar);
     306                 :          0 :                 aCandidate += maLightNormal * fCut;
     307                 :            : 
     308                 :            :                 // transform to view, use 2d coordinates
     309         [ #  # ]:          0 :                 aCandidate *= getEyeToView();
     310         [ #  # ]:          0 :                 aRetval.append(basegfx::B2DPoint(aCandidate.getX(), aCandidate.getY()));
     311                 :          0 :             }
     312                 :            : 
     313                 :            :             // copy closed flag
     314 [ #  # ][ #  # ]:          0 :             aRetval.setClosed(rSource.isClosed());
     315                 :            : 
     316                 :          0 :             return aRetval;
     317                 :            :         }
     318                 :            : 
     319                 :          0 :         basegfx::B2DPolyPolygon Shadow3DExtractingProcessor::impDoShadowProjection(const basegfx::B3DPolyPolygon& rSource)
     320                 :            :         {
     321                 :          0 :             basegfx::B2DPolyPolygon aRetval;
     322                 :            : 
     323 [ #  # ][ #  # ]:          0 :             for(sal_uInt32 a(0L); a < rSource.count(); a++)
     324                 :            :             {
     325 [ #  # ][ #  # ]:          0 :                 aRetval.append(impDoShadowProjection(rSource.getB3DPolygon(a)));
         [ #  # ][ #  # ]
                 [ #  # ]
     326                 :            :             }
     327                 :            : 
     328                 :          0 :             return aRetval;
     329                 :            :         }
     330                 :            : 
     331                 :         15 :         const primitive2d::Primitive2DSequence Shadow3DExtractingProcessor::getPrimitive2DSequence() const
     332                 :            :         {
     333                 :         15 :             return getPrimitive2DSequenceFromBasePrimitive2DVector(maPrimitive2DSequence);
     334                 :            :         }
     335                 :            : 
     336                 :            :     } // end of namespace processor3d
     337                 :            : } // end of namespace drawinglayer
     338                 :            : 
     339                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10