1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 23*b1cdbd2cSJim Jagielski #include "precompiled_drawinglayer.hxx" 24*b1cdbd2cSJim Jagielski 25*b1cdbd2cSJim Jagielski #include <drawinglayer/attribute/sdrlightingattribute3d.hxx> 26*b1cdbd2cSJim Jagielski #include <basegfx/color/bcolor.hxx> 27*b1cdbd2cSJim Jagielski #include <basegfx/vector/b3dvector.hxx> 28*b1cdbd2cSJim Jagielski #include <drawinglayer/attribute/sdrlightattribute3d.hxx> 29*b1cdbd2cSJim Jagielski 30*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 31*b1cdbd2cSJim Jagielski 32*b1cdbd2cSJim Jagielski namespace drawinglayer 33*b1cdbd2cSJim Jagielski { 34*b1cdbd2cSJim Jagielski namespace attribute 35*b1cdbd2cSJim Jagielski { 36*b1cdbd2cSJim Jagielski class ImpSdrLightingAttribute 37*b1cdbd2cSJim Jagielski { 38*b1cdbd2cSJim Jagielski public: 39*b1cdbd2cSJim Jagielski // refcounter 40*b1cdbd2cSJim Jagielski sal_uInt32 mnRefCount; 41*b1cdbd2cSJim Jagielski 42*b1cdbd2cSJim Jagielski // 3D light attribute definitions 43*b1cdbd2cSJim Jagielski basegfx::BColor maAmbientLight; 44*b1cdbd2cSJim Jagielski ::std::vector< Sdr3DLightAttribute > maLightVector; 45*b1cdbd2cSJim Jagielski ImpSdrLightingAttribute(const basegfx::BColor & rAmbientLight,const::std::vector<Sdr3DLightAttribute> & rLightVector)46*b1cdbd2cSJim Jagielski ImpSdrLightingAttribute( 47*b1cdbd2cSJim Jagielski const basegfx::BColor& rAmbientLight, 48*b1cdbd2cSJim Jagielski const ::std::vector< Sdr3DLightAttribute >& rLightVector) 49*b1cdbd2cSJim Jagielski : mnRefCount(0), 50*b1cdbd2cSJim Jagielski maAmbientLight(rAmbientLight), 51*b1cdbd2cSJim Jagielski maLightVector(rLightVector) 52*b1cdbd2cSJim Jagielski { 53*b1cdbd2cSJim Jagielski } 54*b1cdbd2cSJim Jagielski 55*b1cdbd2cSJim Jagielski // data read access getAmbientLight() const56*b1cdbd2cSJim Jagielski const basegfx::BColor& getAmbientLight() const { return maAmbientLight; } getLightVector() const57*b1cdbd2cSJim Jagielski const ::std::vector< Sdr3DLightAttribute >& getLightVector() const { return maLightVector; } 58*b1cdbd2cSJim Jagielski operator ==(const ImpSdrLightingAttribute & rCandidate) const59*b1cdbd2cSJim Jagielski bool operator==(const ImpSdrLightingAttribute& rCandidate) const 60*b1cdbd2cSJim Jagielski { 61*b1cdbd2cSJim Jagielski return (getAmbientLight() == rCandidate.getAmbientLight() 62*b1cdbd2cSJim Jagielski && getLightVector() == rCandidate.getLightVector()); 63*b1cdbd2cSJim Jagielski } 64*b1cdbd2cSJim Jagielski get_global_default()65*b1cdbd2cSJim Jagielski static ImpSdrLightingAttribute* get_global_default() 66*b1cdbd2cSJim Jagielski { 67*b1cdbd2cSJim Jagielski static ImpSdrLightingAttribute* pDefault = 0; 68*b1cdbd2cSJim Jagielski 69*b1cdbd2cSJim Jagielski if(!pDefault) 70*b1cdbd2cSJim Jagielski { 71*b1cdbd2cSJim Jagielski pDefault = new ImpSdrLightingAttribute( 72*b1cdbd2cSJim Jagielski basegfx::BColor(), 73*b1cdbd2cSJim Jagielski std::vector< Sdr3DLightAttribute >()); 74*b1cdbd2cSJim Jagielski 75*b1cdbd2cSJim Jagielski // never delete; start with RefCount 1, not 0 76*b1cdbd2cSJim Jagielski pDefault->mnRefCount++; 77*b1cdbd2cSJim Jagielski } 78*b1cdbd2cSJim Jagielski 79*b1cdbd2cSJim Jagielski return pDefault; 80*b1cdbd2cSJim Jagielski } 81*b1cdbd2cSJim Jagielski }; 82*b1cdbd2cSJim Jagielski SdrLightingAttribute(const basegfx::BColor & rAmbientLight,const::std::vector<Sdr3DLightAttribute> & rLightVector)83*b1cdbd2cSJim Jagielski SdrLightingAttribute::SdrLightingAttribute( 84*b1cdbd2cSJim Jagielski const basegfx::BColor& rAmbientLight, 85*b1cdbd2cSJim Jagielski const ::std::vector< Sdr3DLightAttribute >& rLightVector) 86*b1cdbd2cSJim Jagielski : mpSdrLightingAttribute(new ImpSdrLightingAttribute( 87*b1cdbd2cSJim Jagielski rAmbientLight, rLightVector)) 88*b1cdbd2cSJim Jagielski { 89*b1cdbd2cSJim Jagielski } 90*b1cdbd2cSJim Jagielski SdrLightingAttribute()91*b1cdbd2cSJim Jagielski SdrLightingAttribute::SdrLightingAttribute() 92*b1cdbd2cSJim Jagielski : mpSdrLightingAttribute(ImpSdrLightingAttribute::get_global_default()) 93*b1cdbd2cSJim Jagielski { 94*b1cdbd2cSJim Jagielski mpSdrLightingAttribute->mnRefCount++; 95*b1cdbd2cSJim Jagielski } 96*b1cdbd2cSJim Jagielski SdrLightingAttribute(const SdrLightingAttribute & rCandidate)97*b1cdbd2cSJim Jagielski SdrLightingAttribute::SdrLightingAttribute(const SdrLightingAttribute& rCandidate) 98*b1cdbd2cSJim Jagielski : mpSdrLightingAttribute(rCandidate.mpSdrLightingAttribute) 99*b1cdbd2cSJim Jagielski { 100*b1cdbd2cSJim Jagielski mpSdrLightingAttribute->mnRefCount++; 101*b1cdbd2cSJim Jagielski } 102*b1cdbd2cSJim Jagielski ~SdrLightingAttribute()103*b1cdbd2cSJim Jagielski SdrLightingAttribute::~SdrLightingAttribute() 104*b1cdbd2cSJim Jagielski { 105*b1cdbd2cSJim Jagielski if(mpSdrLightingAttribute->mnRefCount) 106*b1cdbd2cSJim Jagielski { 107*b1cdbd2cSJim Jagielski mpSdrLightingAttribute->mnRefCount--; 108*b1cdbd2cSJim Jagielski } 109*b1cdbd2cSJim Jagielski else 110*b1cdbd2cSJim Jagielski { 111*b1cdbd2cSJim Jagielski delete mpSdrLightingAttribute; 112*b1cdbd2cSJim Jagielski } 113*b1cdbd2cSJim Jagielski } 114*b1cdbd2cSJim Jagielski isDefault() const115*b1cdbd2cSJim Jagielski bool SdrLightingAttribute::isDefault() const 116*b1cdbd2cSJim Jagielski { 117*b1cdbd2cSJim Jagielski return mpSdrLightingAttribute == ImpSdrLightingAttribute::get_global_default(); 118*b1cdbd2cSJim Jagielski } 119*b1cdbd2cSJim Jagielski operator =(const SdrLightingAttribute & rCandidate)120*b1cdbd2cSJim Jagielski SdrLightingAttribute& SdrLightingAttribute::operator=(const SdrLightingAttribute& rCandidate) 121*b1cdbd2cSJim Jagielski { 122*b1cdbd2cSJim Jagielski if(rCandidate.mpSdrLightingAttribute != mpSdrLightingAttribute) 123*b1cdbd2cSJim Jagielski { 124*b1cdbd2cSJim Jagielski if(mpSdrLightingAttribute->mnRefCount) 125*b1cdbd2cSJim Jagielski { 126*b1cdbd2cSJim Jagielski mpSdrLightingAttribute->mnRefCount--; 127*b1cdbd2cSJim Jagielski } 128*b1cdbd2cSJim Jagielski else 129*b1cdbd2cSJim Jagielski { 130*b1cdbd2cSJim Jagielski delete mpSdrLightingAttribute; 131*b1cdbd2cSJim Jagielski } 132*b1cdbd2cSJim Jagielski 133*b1cdbd2cSJim Jagielski mpSdrLightingAttribute = rCandidate.mpSdrLightingAttribute; 134*b1cdbd2cSJim Jagielski mpSdrLightingAttribute->mnRefCount++; 135*b1cdbd2cSJim Jagielski } 136*b1cdbd2cSJim Jagielski 137*b1cdbd2cSJim Jagielski return *this; 138*b1cdbd2cSJim Jagielski } 139*b1cdbd2cSJim Jagielski operator ==(const SdrLightingAttribute & rCandidate) const140*b1cdbd2cSJim Jagielski bool SdrLightingAttribute::operator==(const SdrLightingAttribute& rCandidate) const 141*b1cdbd2cSJim Jagielski { 142*b1cdbd2cSJim Jagielski if(rCandidate.mpSdrLightingAttribute == mpSdrLightingAttribute) 143*b1cdbd2cSJim Jagielski { 144*b1cdbd2cSJim Jagielski return true; 145*b1cdbd2cSJim Jagielski } 146*b1cdbd2cSJim Jagielski 147*b1cdbd2cSJim Jagielski if(rCandidate.isDefault() != isDefault()) 148*b1cdbd2cSJim Jagielski { 149*b1cdbd2cSJim Jagielski return false; 150*b1cdbd2cSJim Jagielski } 151*b1cdbd2cSJim Jagielski 152*b1cdbd2cSJim Jagielski return (*rCandidate.mpSdrLightingAttribute == *mpSdrLightingAttribute); 153*b1cdbd2cSJim Jagielski } 154*b1cdbd2cSJim Jagielski getAmbientLight() const155*b1cdbd2cSJim Jagielski const basegfx::BColor& SdrLightingAttribute::getAmbientLight() const 156*b1cdbd2cSJim Jagielski { 157*b1cdbd2cSJim Jagielski return mpSdrLightingAttribute->getAmbientLight(); 158*b1cdbd2cSJim Jagielski } 159*b1cdbd2cSJim Jagielski getLightVector() const160*b1cdbd2cSJim Jagielski const ::std::vector< Sdr3DLightAttribute >& SdrLightingAttribute::getLightVector() const 161*b1cdbd2cSJim Jagielski { 162*b1cdbd2cSJim Jagielski return mpSdrLightingAttribute->getLightVector(); 163*b1cdbd2cSJim Jagielski } 164*b1cdbd2cSJim Jagielski 165*b1cdbd2cSJim Jagielski // color model solver solveColorModel(const basegfx::B3DVector & rNormalInEyeCoordinates,const basegfx::BColor & rColor,const basegfx::BColor & rSpecular,const basegfx::BColor & rEmission,sal_uInt16 nSpecularIntensity) const166*b1cdbd2cSJim Jagielski basegfx::BColor SdrLightingAttribute::solveColorModel( 167*b1cdbd2cSJim Jagielski const basegfx::B3DVector& rNormalInEyeCoordinates, 168*b1cdbd2cSJim Jagielski const basegfx::BColor& rColor, const basegfx::BColor& rSpecular, 169*b1cdbd2cSJim Jagielski const basegfx::BColor& rEmission, sal_uInt16 nSpecularIntensity) const 170*b1cdbd2cSJim Jagielski { 171*b1cdbd2cSJim Jagielski // initialize with emissive color 172*b1cdbd2cSJim Jagielski basegfx::BColor aRetval(rEmission); 173*b1cdbd2cSJim Jagielski 174*b1cdbd2cSJim Jagielski // take care of global ambient light 175*b1cdbd2cSJim Jagielski aRetval += mpSdrLightingAttribute->getAmbientLight() * rColor; 176*b1cdbd2cSJim Jagielski 177*b1cdbd2cSJim Jagielski // prepare light access. Is there a light? 178*b1cdbd2cSJim Jagielski const sal_uInt32 nLightCount(mpSdrLightingAttribute->getLightVector().size()); 179*b1cdbd2cSJim Jagielski 180*b1cdbd2cSJim Jagielski if(nLightCount && !rNormalInEyeCoordinates.equalZero()) 181*b1cdbd2cSJim Jagielski { 182*b1cdbd2cSJim Jagielski // prepare normal 183*b1cdbd2cSJim Jagielski basegfx::B3DVector aEyeNormal(rNormalInEyeCoordinates); 184*b1cdbd2cSJim Jagielski aEyeNormal.normalize(); 185*b1cdbd2cSJim Jagielski 186*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0L); a < nLightCount; a++) 187*b1cdbd2cSJim Jagielski { 188*b1cdbd2cSJim Jagielski const Sdr3DLightAttribute& rLight(mpSdrLightingAttribute->getLightVector()[a]); 189*b1cdbd2cSJim Jagielski const double fCosFac(rLight.getDirection().scalar(aEyeNormal)); 190*b1cdbd2cSJim Jagielski 191*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fCosFac, 0.0)) 192*b1cdbd2cSJim Jagielski { 193*b1cdbd2cSJim Jagielski aRetval += ((rLight.getColor() * rColor) * fCosFac); 194*b1cdbd2cSJim Jagielski 195*b1cdbd2cSJim Jagielski if(rLight.getSpecular()) 196*b1cdbd2cSJim Jagielski { 197*b1cdbd2cSJim Jagielski // expand by (0.0, 0.0, 1.0) in Z 198*b1cdbd2cSJim Jagielski basegfx::B3DVector aSpecularNormal(rLight.getDirection().getX(), rLight.getDirection().getY(), rLight.getDirection().getZ() + 1.0); 199*b1cdbd2cSJim Jagielski aSpecularNormal.normalize(); 200*b1cdbd2cSJim Jagielski double fCosFac2(aSpecularNormal.scalar(aEyeNormal)); 201*b1cdbd2cSJim Jagielski 202*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fCosFac2, 0.0)) 203*b1cdbd2cSJim Jagielski { 204*b1cdbd2cSJim Jagielski fCosFac2 = pow(fCosFac2, (double)nSpecularIntensity); 205*b1cdbd2cSJim Jagielski aRetval += (rSpecular * fCosFac2); 206*b1cdbd2cSJim Jagielski } 207*b1cdbd2cSJim Jagielski } 208*b1cdbd2cSJim Jagielski } 209*b1cdbd2cSJim Jagielski } 210*b1cdbd2cSJim Jagielski } 211*b1cdbd2cSJim Jagielski 212*b1cdbd2cSJim Jagielski // clamp to color space before usage 213*b1cdbd2cSJim Jagielski aRetval.clamp(); 214*b1cdbd2cSJim Jagielski 215*b1cdbd2cSJim Jagielski return aRetval; 216*b1cdbd2cSJim Jagielski } 217*b1cdbd2cSJim Jagielski } // end of namespace attribute 218*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer 219*b1cdbd2cSJim Jagielski 220*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 221*b1cdbd2cSJim Jagielski // eof 222