xref: /AOO41X/main/drawinglayer/source/attribute/sdrlightingattribute3d.cxx (revision 4bfbcde8d64cc5d114df10dce4a9ed79eff32278)
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