1 /************************************************************************* 2 * 3 * OpenOffice.org - a multi-platform office productivity suite 4 * 5 * $RCSfile: sdrattribute3d.cxx,v $ 6 * 7 * $Revision: 1.5 $ 8 * 9 * last change: $Author: aw $ $Date: 2008-05-27 14:11:19 $ 10 * 11 * The Contents of this file are made available subject to 12 * the terms of GNU Lesser General Public License Version 2.1. 13 * 14 * 15 * GNU Lesser General Public License Version 2.1 16 * ============================================= 17 * Copyright 2005 by Sun Microsystems, Inc. 18 * 901 San Antonio Road, Palo Alto, CA 94303, USA 19 * 20 * This library is free software; you can redistribute it and/or 21 * modify it under the terms of the GNU Lesser General Public 22 * License version 2.1, as published by the Free Software Foundation. 23 * 24 * This library is distributed in the hope that it will be useful, 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 27 * Lesser General Public License for more details. 28 * 29 * You should have received a copy of the GNU Lesser General Public 30 * License along with this library; if not, write to the Free Software 31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 32 * MA 02111-1307 USA 33 * 34 ************************************************************************/ 35 36 // MARKER(update_precomp.py): autogen include statement, do not remove 37 #include "precompiled_drawinglayer.hxx" 38 39 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx> 40 #include <basegfx/color/bcolor.hxx> 41 #include <basegfx/vector/b3dvector.hxx> 42 #include <drawinglayer/attribute/sdrlightattribute3d.hxx> 43 44 ////////////////////////////////////////////////////////////////////////////// 45 46 namespace drawinglayer 47 { 48 namespace attribute 49 { 50 class ImpSdrLightingAttribute 51 { 52 public: 53 // refcounter 54 sal_uInt32 mnRefCount; 55 56 // 3D light attribute definitions 57 basegfx::BColor maAmbientLight; 58 ::std::vector< Sdr3DLightAttribute > maLightVector; 59 60 ImpSdrLightingAttribute( 61 const basegfx::BColor& rAmbientLight, 62 const ::std::vector< Sdr3DLightAttribute >& rLightVector) 63 : mnRefCount(0), 64 maAmbientLight(rAmbientLight), 65 maLightVector(rLightVector) 66 { 67 } 68 69 // data read access 70 const basegfx::BColor& getAmbientLight() const { return maAmbientLight; } 71 const ::std::vector< Sdr3DLightAttribute >& getLightVector() const { return maLightVector; } 72 73 bool operator==(const ImpSdrLightingAttribute& rCandidate) const 74 { 75 return (getAmbientLight() == rCandidate.getAmbientLight() 76 && getLightVector() == rCandidate.getLightVector()); 77 } 78 79 static ImpSdrLightingAttribute* get_global_default() 80 { 81 static ImpSdrLightingAttribute* pDefault = 0; 82 83 if(!pDefault) 84 { 85 pDefault = new ImpSdrLightingAttribute( 86 basegfx::BColor(), 87 std::vector< Sdr3DLightAttribute >()); 88 89 // never delete; start with RefCount 1, not 0 90 pDefault->mnRefCount++; 91 } 92 93 return pDefault; 94 } 95 }; 96 97 SdrLightingAttribute::SdrLightingAttribute( 98 const basegfx::BColor& rAmbientLight, 99 const ::std::vector< Sdr3DLightAttribute >& rLightVector) 100 : mpSdrLightingAttribute(new ImpSdrLightingAttribute( 101 rAmbientLight, rLightVector)) 102 { 103 } 104 105 SdrLightingAttribute::SdrLightingAttribute() 106 : mpSdrLightingAttribute(ImpSdrLightingAttribute::get_global_default()) 107 { 108 mpSdrLightingAttribute->mnRefCount++; 109 } 110 111 SdrLightingAttribute::SdrLightingAttribute(const SdrLightingAttribute& rCandidate) 112 : mpSdrLightingAttribute(rCandidate.mpSdrLightingAttribute) 113 { 114 mpSdrLightingAttribute->mnRefCount++; 115 } 116 117 SdrLightingAttribute::~SdrLightingAttribute() 118 { 119 if(mpSdrLightingAttribute->mnRefCount) 120 { 121 mpSdrLightingAttribute->mnRefCount--; 122 } 123 else 124 { 125 delete mpSdrLightingAttribute; 126 } 127 } 128 129 bool SdrLightingAttribute::isDefault() const 130 { 131 return mpSdrLightingAttribute == ImpSdrLightingAttribute::get_global_default(); 132 } 133 134 SdrLightingAttribute& SdrLightingAttribute::operator=(const SdrLightingAttribute& rCandidate) 135 { 136 if(rCandidate.mpSdrLightingAttribute != mpSdrLightingAttribute) 137 { 138 if(mpSdrLightingAttribute->mnRefCount) 139 { 140 mpSdrLightingAttribute->mnRefCount--; 141 } 142 else 143 { 144 delete mpSdrLightingAttribute; 145 } 146 147 mpSdrLightingAttribute = rCandidate.mpSdrLightingAttribute; 148 mpSdrLightingAttribute->mnRefCount++; 149 } 150 151 return *this; 152 } 153 154 bool SdrLightingAttribute::operator==(const SdrLightingAttribute& rCandidate) const 155 { 156 if(rCandidate.mpSdrLightingAttribute == mpSdrLightingAttribute) 157 { 158 return true; 159 } 160 161 if(rCandidate.isDefault() != isDefault()) 162 { 163 return false; 164 } 165 166 return (*rCandidate.mpSdrLightingAttribute == *mpSdrLightingAttribute); 167 } 168 169 const basegfx::BColor& SdrLightingAttribute::getAmbientLight() const 170 { 171 return mpSdrLightingAttribute->getAmbientLight(); 172 } 173 174 const ::std::vector< Sdr3DLightAttribute >& SdrLightingAttribute::getLightVector() const 175 { 176 return mpSdrLightingAttribute->getLightVector(); 177 } 178 179 // color model solver 180 basegfx::BColor SdrLightingAttribute::solveColorModel( 181 const basegfx::B3DVector& rNormalInEyeCoordinates, 182 const basegfx::BColor& rColor, const basegfx::BColor& rSpecular, 183 const basegfx::BColor& rEmission, sal_uInt16 nSpecularIntensity) const 184 { 185 // initialize with emissive color 186 basegfx::BColor aRetval(rEmission); 187 188 // take care of global ambient light 189 aRetval += mpSdrLightingAttribute->getAmbientLight() * rColor; 190 191 // prepare light access. Is there a light? 192 const sal_uInt32 nLightCount(mpSdrLightingAttribute->getLightVector().size()); 193 194 if(nLightCount && !rNormalInEyeCoordinates.equalZero()) 195 { 196 // prepare normal 197 basegfx::B3DVector aEyeNormal(rNormalInEyeCoordinates); 198 aEyeNormal.normalize(); 199 200 for(sal_uInt32 a(0L); a < nLightCount; a++) 201 { 202 const Sdr3DLightAttribute& rLight(mpSdrLightingAttribute->getLightVector()[a]); 203 const double fCosFac(rLight.getDirection().scalar(aEyeNormal)); 204 205 if(basegfx::fTools::more(fCosFac, 0.0)) 206 { 207 aRetval += ((rLight.getColor() * rColor) * fCosFac); 208 209 if(rLight.getSpecular()) 210 { 211 // expand by (0.0, 0.0, 1.0) in Z 212 basegfx::B3DVector aSpecularNormal(rLight.getDirection().getX(), rLight.getDirection().getY(), rLight.getDirection().getZ() + 1.0); 213 aSpecularNormal.normalize(); 214 double fCosFac2(aSpecularNormal.scalar(aEyeNormal)); 215 216 if(basegfx::fTools::more(fCosFac2, 0.0)) 217 { 218 fCosFac2 = pow(fCosFac2, (double)nSpecularIntensity); 219 aRetval += (rSpecular * fCosFac2); 220 } 221 } 222 } 223 } 224 } 225 226 // clamp to color space before usage 227 aRetval.clamp(); 228 229 return aRetval; 230 } 231 } // end of namespace attribute 232 } // end of namespace drawinglayer 233 234 ////////////////////////////////////////////////////////////////////////////// 235 // eof 236