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