4687a9ee99303ebfaaa06dd480b8090d1e9e52db
[occt.git] / src / Visual3d / Visual3d_Light.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #include <Visual3d_Light.ixx>
20
21 #include <Graphic3d_GraphicDriver.hxx>
22
23 // =======================================================================
24 // function : Visual3d_Light
25 // purpose  :
26 // =======================================================================
27 Visual3d_Light::Visual3d_Light()
28 {
29   myCLight.Type = Visual3d_TOLS_AMBIENT;
30 }
31
32 // =======================================================================
33 // function : Visual3d_Light
34 // purpose  :
35 // =======================================================================
36 Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor)
37 {
38   myCLight.Type      = Visual3d_TOLS_AMBIENT;
39   myCLight.Color.r() = Standard_ShortReal (theColor.Red());
40   myCLight.Color.g() = Standard_ShortReal (theColor.Green());
41   myCLight.Color.b() = Standard_ShortReal (theColor.Blue());
42 }
43
44 // =======================================================================
45 // function : Visual3d_Light
46 // purpose  :
47 // =======================================================================
48 Visual3d_Light::Visual3d_Light (const Quantity_Color&   theColor,
49                                 const Graphic3d_Vector& theDir,
50                                 const Standard_Boolean  theIsHeadlight)
51 {
52   Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(),
53                                           "Bad value for LightDirection");
54   myCLight.Type        = Visual3d_TOLS_DIRECTIONAL;
55   myCLight.IsHeadlight = theIsHeadlight;
56   myCLight.Color.r()   = Standard_ShortReal (theColor.Red());
57   myCLight.Color.g()   = Standard_ShortReal (theColor.Green());
58   myCLight.Color.b()   = Standard_ShortReal (theColor.Blue());
59
60   Standard_Real X, Y, Z;
61   theDir.Coord (X, Y, Z);
62   const Standard_Real aNorm = Sqrt (X * X + Y * Y + Z * Z);
63   myCLight.Direction.x() = Standard_ShortReal (X / aNorm);
64   myCLight.Direction.y() = Standard_ShortReal (Y / aNorm);
65   myCLight.Direction.z() = Standard_ShortReal (Z / aNorm);
66 }
67
68 // =======================================================================
69 // function : Visual3d_Light
70 // purpose  :
71 // =======================================================================
72 Visual3d_Light::Visual3d_Light (const Quantity_Color&   theColor,
73                                 const Graphic3d_Vertex& thePos,
74                                 const Standard_Real     theFact1,
75                                 const Standard_Real     theFact2)
76 {
77   Visual3d_LightDefinitionError_Raise_if ((theFact1 == 0.0 && theFact2 == 0.0)
78                                        || (theFact1  < 0.0 || theFact1 >  1.0)
79                                        || (theFact2  < 0.0 || theFact2 >  1.0),
80                                           "Bad value for LightAttenuation");
81   myCLight.Type         = Visual3d_TOLS_POSITIONAL;
82   myCLight.IsHeadlight  = Standard_False;
83   myCLight.Color.r()    = Standard_ShortReal (theColor.Red());
84   myCLight.Color.g()    = Standard_ShortReal (theColor.Green());
85   myCLight.Color.b()    = Standard_ShortReal (theColor.Blue());
86   myCLight.Position.x() = Standard_ShortReal (thePos.X());
87   myCLight.Position.y() = Standard_ShortReal (thePos.Y());
88   myCLight.Position.z() = Standard_ShortReal (thePos.Z());
89   myCLight.ChangeConstAttenuation()  = Standard_ShortReal (theFact1);
90   myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2);
91 }
92
93 // =======================================================================
94 // function : Visual3d_Light
95 // purpose  :
96 // =======================================================================
97 Visual3d_Light::Visual3d_Light (const Quantity_Color&   theColor,
98                                 const Graphic3d_Vertex& thePos,
99                                 const Graphic3d_Vector& theDir,
100                                 const Standard_Real     theConcentration,
101                                 const Standard_Real     theFact1,
102                                 const Standard_Real     theFact2,
103                                 const Standard_Real     theAngleCone)
104 {
105   Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(),
106                                           "Bad value for LightDirection");
107   Visual3d_LightDefinitionError_Raise_if (theConcentration < 0.0 || theConcentration > 1.0,
108                                           "Bad value for LightConcentration");
109   Visual3d_LightDefinitionError_Raise_if ((theFact1 == 0.0 && theFact2 == 0.0)
110                                        || (theFact1  < 0.0 || theFact1 >  1.0)
111                                        || (theFact2  < 0.0 || theFact2 >  1.0),
112                                           "Bad value for LightAttenuation");
113   Visual3d_LightDefinitionError_Raise_if (!Visual3d_Light::IsValid (theAngleCone),
114                                           "Bad value for LightAngle");
115   myCLight.Type         = Visual3d_TOLS_SPOT;
116   myCLight.IsHeadlight  = Standard_False;
117   myCLight.Color.r()    = Standard_ShortReal (theColor.Red());
118   myCLight.Color.g()    = Standard_ShortReal (theColor.Green());
119   myCLight.Color.b()    = Standard_ShortReal (theColor.Blue());
120   myCLight.Position.x() = Standard_ShortReal (thePos.X());
121   myCLight.Position.y() = Standard_ShortReal (thePos.Y());
122   myCLight.Position.z() = Standard_ShortReal (thePos.Z());
123
124   Standard_Real X, Y, Z;
125   theDir.Coord (X, Y, Z);
126   myCLight.Direction.x() = Standard_ShortReal (X);
127   myCLight.Direction.y() = Standard_ShortReal (Y);
128   myCLight.Direction.z() = Standard_ShortReal (Z);
129
130   myCLight.ChangeConcentration()     = Standard_ShortReal (theConcentration);
131   myCLight.ChangeConstAttenuation()  = Standard_ShortReal (theFact1);
132   myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2);
133   myCLight.ChangeAngle()             = Standard_ShortReal (theAngleCone);
134 }
135
136 // =======================================================================
137 // function : Color
138 // purpose  :
139 // =======================================================================
140 Quantity_Color Visual3d_Light::Color() const
141 {
142   return Quantity_Color (Standard_Real (myCLight.Color.r()),
143                          Standard_Real (myCLight.Color.g()),
144                          Standard_Real (myCLight.Color.b()),
145                          Quantity_TOC_RGB);
146 }
147
148 // =======================================================================
149 // function : LightType
150 // purpose  :
151 // =======================================================================
152 Visual3d_TypeOfLightSource Visual3d_Light::LightType() const
153 {
154   return (Visual3d_TypeOfLightSource )myCLight.Type;
155 }
156
157 // =======================================================================
158 // function : Headlight
159 // purpose  :
160 // =======================================================================
161 Standard_Boolean Visual3d_Light::Headlight() const
162 {
163   return myCLight.IsHeadlight;
164 }
165
166 // =======================================================================
167 // function : SetHeadlight
168 // purpose  :
169 // =======================================================================
170 void Visual3d_Light::SetHeadlight (const Standard_Boolean theValue)
171 {
172   myCLight.IsHeadlight = theValue;
173 }
174
175 // =======================================================================
176 // function : Values
177 // purpose  :
178 // =======================================================================
179 void Visual3d_Light::Values (Quantity_Color& theColor) const
180 {
181   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_AMBIENT,
182                                           "Light Type != Visual3d_TOLS_AMBIENT");
183   theColor.SetValues (Standard_Real (myCLight.Color.r()),
184                       Standard_Real (myCLight.Color.g()),
185                       Standard_Real (myCLight.Color.b()),
186                       Quantity_TOC_RGB);
187 }
188
189 // =======================================================================
190 // function : Values
191 // purpose  :
192 // =======================================================================
193 void Visual3d_Light::Values (Quantity_Color&   theColor,
194                              Graphic3d_Vector& theDir) const
195 {
196   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_DIRECTIONAL,
197                                           "Light Type != Visual3d_TOLS_DIRECTIONAL");
198   theColor.SetValues (Standard_Real (myCLight.Color.r()),
199                       Standard_Real (myCLight.Color.g()),
200                       Standard_Real (myCLight.Color.b()),
201                       Quantity_TOC_RGB);
202   theDir.SetCoord (Standard_Real (myCLight.Direction.x()),
203                    Standard_Real (myCLight.Direction.y()),
204                    Standard_Real (myCLight.Direction.z()));
205 }
206
207 // =======================================================================
208 // function : Values
209 // purpose  :
210 // =======================================================================
211 void Visual3d_Light::Values (Quantity_Color&   theColor,
212                              Graphic3d_Vertex& thePos,
213                              Standard_Real&    theFact1,
214                              Standard_Real&    theFact2) const
215 {
216   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL,
217                                           "Light Type != Visual3d_TOLS_POSITIONAL");
218   theColor.SetValues (Standard_Real (myCLight.Color.r()),
219                       Standard_Real (myCLight.Color.g()),
220                       Standard_Real (myCLight.Color.b()),
221                       Quantity_TOC_RGB);
222   thePos.SetCoord (Standard_Real (myCLight.Position.x()),
223                    Standard_Real (myCLight.Position.y()),
224                    Standard_Real (myCLight.Position.z()));
225   theFact1 = Standard_Real (myCLight.ConstAttenuation());
226   theFact2 = Standard_Real (myCLight.LinearAttenuation());
227 }
228
229 // =======================================================================
230 // function : Values
231 // purpose  :
232 // =======================================================================
233 void Visual3d_Light::Values (Quantity_Color&   theColor,
234                              Graphic3d_Vertex& thePos,
235                              Graphic3d_Vector& theDir,
236                              Standard_Real&    theConcentration,
237                              Standard_Real&    theFact1,
238                              Standard_Real&    theFact2,
239                              Standard_Real&    theAngleCone) const
240 {
241   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT,
242                                           "Light Type != Visual3d_TOLS_SPOT");
243   theColor.SetValues (Standard_Real (myCLight.Color.r()),
244                       Standard_Real (myCLight.Color.g()),
245                       Standard_Real (myCLight.Color.b()),
246                       Quantity_TOC_RGB);
247   thePos.SetCoord (Standard_Real (myCLight.Position.x()),
248                    Standard_Real (myCLight.Position.y()),
249                    Standard_Real (myCLight.Position.z()));
250   theDir.SetCoord (Standard_Real (myCLight.Direction.x()),
251                    Standard_Real (myCLight.Direction.y()),
252                    Standard_Real (myCLight.Direction.z()));
253   theConcentration = Standard_Real (myCLight.Concentration());
254   theFact1         = Standard_Real (myCLight.ConstAttenuation());
255   theFact2         = Standard_Real (myCLight.LinearAttenuation());
256   theAngleCone     = Standard_Real (myCLight.Angle());
257 }
258
259 // =======================================================================
260 // function : SetAngle
261 // purpose  :
262 // =======================================================================
263 void Visual3d_Light::SetAngle (const Standard_Real theAngleCone)
264 {
265   Visual3d_LightDefinitionError_Raise_if (!Visual3d_Light::IsValid (theAngleCone),
266                                           "Bad value for LightAngle");
267   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT,
268                                           "Light Type != Visual3d_TOLS_SPOT");
269   myCLight.ChangeAngle() = Standard_ShortReal (theAngleCone);
270 }
271
272 // =======================================================================
273 // function : SetAttenuation1
274 // purpose  :
275 // =======================================================================
276 void Visual3d_Light::SetAttenuation1 (const Standard_Real theFact1)
277 {
278   Visual3d_LightDefinitionError_Raise_if (theFact1 < 0.0 || theFact1 > 1.0,
279                                           "Bad value for LightAttenuation");
280   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL
281                                        && myCLight.Type != Visual3d_TOLS_SPOT,
282                                           "Light Type != Visual3d_TOLS_SPOT and != Visual3d_TOLS_POSITIONAL");
283   myCLight.ChangeConstAttenuation() = Standard_ShortReal (theFact1);
284 }
285
286 // =======================================================================
287 // function : SetAttenuation2
288 // purpose  :
289 // =======================================================================
290 void Visual3d_Light::SetAttenuation2 (const Standard_Real theFact2)
291 {
292   Visual3d_LightDefinitionError_Raise_if (theFact2 < 0.0 || theFact2 > 1.0,
293                                           "Bad value for LightAttenuation");
294   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL
295                                        && myCLight.Type != Visual3d_TOLS_SPOT,
296                                           "Light Type != Visual3d_TOLS_SPOT and != Visual3d_TOLS_POSITIONAL");
297   myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2);
298 }
299
300 // =======================================================================
301 // function : SetColor
302 // purpose  :
303 // =======================================================================
304 void Visual3d_Light::SetColor (const Quantity_Color& theColor)
305 {
306   myCLight.Color.r() = float (theColor.Red());
307   myCLight.Color.g() = float (theColor.Green());
308   myCLight.Color.b() = float (theColor.Blue());
309 }
310
311 // =======================================================================
312 // function : SetConcentration
313 // purpose  :
314 // =======================================================================
315 void Visual3d_Light::SetConcentration (const Standard_Real theConcentration)
316 {
317   Visual3d_LightDefinitionError_Raise_if (theConcentration < 0.0 || theConcentration > 1.0,
318                                           "Bad value for LightConcentration");
319   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT,
320                                           "Light Type != Visual3d_TOLS_SPOT");
321   myCLight.ChangeConcentration() = Standard_ShortReal (theConcentration);
322 }
323
324 // =======================================================================
325 // function : SetDirection
326 // purpose  :
327 // =======================================================================
328 void Visual3d_Light::SetDirection (const Graphic3d_Vector& theDir)
329 {
330   Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(),
331                                           "Bad value for LightDirection");
332   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT
333                                        && myCLight.Type != Visual3d_TOLS_DIRECTIONAL,
334                                           "Light Type != Visual3d_TOLS_DIRECTIONAL and != Visual3d_TOLS_SPOT");
335   Standard_Real X, Y, Z;
336   theDir.Coord (X, Y, Z);
337   const Standard_Real aNorm = Sqrt (X * X + Y * Y + Z * Z);
338   myCLight.Direction.x() = float (X / aNorm);
339   myCLight.Direction.y() = float (Y / aNorm);
340   myCLight.Direction.z() = float (Z / aNorm);
341 }
342
343 // =======================================================================
344 // function : SetPosition
345 // purpose  :
346 // =======================================================================
347 void Visual3d_Light::SetPosition (const Graphic3d_Vertex& thePos)
348 {
349   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT
350                                        && myCLight.Type != Visual3d_TOLS_POSITIONAL,
351                                           "Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT");
352   myCLight.Position.x() = float (thePos.X());
353   myCLight.Position.y() = float (thePos.Y());
354   myCLight.Position.z() = float (thePos.Z());
355 }
356
357 // =======================================================================
358 // function : Limit
359 // purpose  :
360 // =======================================================================
361 Standard_Integer Visual3d_Light::Limit()
362 {
363   // Old method, replaced by GraphicDriver::InquireLightLimit()
364   return 0;
365 }
366
367 // =======================================================================
368 // function : Identification
369 // purpose  :
370 // =======================================================================
371 Standard_Integer Visual3d_Light::Identification() const
372 {
373   return 0;
374 }
375
376 // =======================================================================
377 // function : IsValid
378 // purpose  :
379 // =======================================================================
380 Standard_Boolean Visual3d_Light::IsValid (const Standard_Real theAngle)
381 {
382   return (theAngle <  M_PI)
383       && (theAngle >= 0.0);
384 }
385
386 // =======================================================================
387 // function : CLight
388 // purpose  :
389 // =======================================================================
390 const Graphic3d_CLight& Visual3d_Light::CLight() const
391 {
392   return myCLight;
393 }