68ee615eab3f50e3483179783a35baeae31faefb
[occt.git] / src / Visual3d / Visual3d_Light.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <Visual3d_Light.ixx>
16
17 #include <Graphic3d_GraphicDriver.hxx>
18
19 // =======================================================================
20 // function : Visual3d_Light
21 // purpose  :
22 // =======================================================================
23 Visual3d_Light::Visual3d_Light()
24 {
25   myCLight.Type = Visual3d_TOLS_AMBIENT;
26 }
27
28 // =======================================================================
29 // function : Visual3d_Light
30 // purpose  :
31 // =======================================================================
32 Visual3d_Light::Visual3d_Light (const Quantity_Color& theColor)
33 {
34   myCLight.Type      = Visual3d_TOLS_AMBIENT;
35   myCLight.Color.r() = Standard_ShortReal (theColor.Red());
36   myCLight.Color.g() = Standard_ShortReal (theColor.Green());
37   myCLight.Color.b() = Standard_ShortReal (theColor.Blue());
38 }
39
40 // =======================================================================
41 // function : Visual3d_Light
42 // purpose  :
43 // =======================================================================
44 Visual3d_Light::Visual3d_Light (const Quantity_Color&   theColor,
45                                 const Graphic3d_Vector& theDir,
46                                 const Standard_Boolean  theIsHeadlight)
47 {
48   Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(),
49                                           "Bad value for LightDirection");
50   myCLight.Type        = Visual3d_TOLS_DIRECTIONAL;
51   myCLight.IsHeadlight = theIsHeadlight;
52   myCLight.Color.r()   = Standard_ShortReal (theColor.Red());
53   myCLight.Color.g()   = Standard_ShortReal (theColor.Green());
54   myCLight.Color.b()   = Standard_ShortReal (theColor.Blue());
55
56   Standard_Real X, Y, Z;
57   theDir.Coord (X, Y, Z);
58   const Standard_Real aNorm = Sqrt (X * X + Y * Y + Z * Z);
59   myCLight.Direction.x() = Standard_ShortReal (X / aNorm);
60   myCLight.Direction.y() = Standard_ShortReal (Y / aNorm);
61   myCLight.Direction.z() = Standard_ShortReal (Z / aNorm);
62 }
63
64 // =======================================================================
65 // function : Visual3d_Light
66 // purpose  :
67 // =======================================================================
68 Visual3d_Light::Visual3d_Light (const Quantity_Color&   theColor,
69                                 const Graphic3d_Vertex& thePos,
70                                 const Standard_Real     theFact1,
71                                 const Standard_Real     theFact2)
72 {
73   Visual3d_LightDefinitionError_Raise_if ((theFact1 == 0.0 && theFact2 == 0.0)
74                                        || (theFact1  < 0.0 || theFact1 >  1.0)
75                                        || (theFact2  < 0.0 || theFact2 >  1.0),
76                                           "Bad value for LightAttenuation");
77   myCLight.Type         = Visual3d_TOLS_POSITIONAL;
78   myCLight.IsHeadlight  = Standard_False;
79   myCLight.Color.r()    = Standard_ShortReal (theColor.Red());
80   myCLight.Color.g()    = Standard_ShortReal (theColor.Green());
81   myCLight.Color.b()    = Standard_ShortReal (theColor.Blue());
82   myCLight.Position.x() = Standard_ShortReal (thePos.X());
83   myCLight.Position.y() = Standard_ShortReal (thePos.Y());
84   myCLight.Position.z() = Standard_ShortReal (thePos.Z());
85   myCLight.ChangeConstAttenuation()  = Standard_ShortReal (theFact1);
86   myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2);
87 }
88
89 // =======================================================================
90 // function : Visual3d_Light
91 // purpose  :
92 // =======================================================================
93 Visual3d_Light::Visual3d_Light (const Quantity_Color&   theColor,
94                                 const Graphic3d_Vertex& thePos,
95                                 const Graphic3d_Vector& theDir,
96                                 const Standard_Real     theConcentration,
97                                 const Standard_Real     theFact1,
98                                 const Standard_Real     theFact2,
99                                 const Standard_Real     theAngleCone)
100 {
101   Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(),
102                                           "Bad value for LightDirection");
103   Visual3d_LightDefinitionError_Raise_if (theConcentration < 0.0 || theConcentration > 1.0,
104                                           "Bad value for LightConcentration");
105   Visual3d_LightDefinitionError_Raise_if ((theFact1 == 0.0 && theFact2 == 0.0)
106                                        || (theFact1  < 0.0 || theFact1 >  1.0)
107                                        || (theFact2  < 0.0 || theFact2 >  1.0),
108                                           "Bad value for LightAttenuation");
109   Visual3d_LightDefinitionError_Raise_if (!Visual3d_Light::IsValid (theAngleCone),
110                                           "Bad value for LightAngle");
111   myCLight.Type         = Visual3d_TOLS_SPOT;
112   myCLight.IsHeadlight  = Standard_False;
113   myCLight.Color.r()    = Standard_ShortReal (theColor.Red());
114   myCLight.Color.g()    = Standard_ShortReal (theColor.Green());
115   myCLight.Color.b()    = Standard_ShortReal (theColor.Blue());
116   myCLight.Position.x() = Standard_ShortReal (thePos.X());
117   myCLight.Position.y() = Standard_ShortReal (thePos.Y());
118   myCLight.Position.z() = Standard_ShortReal (thePos.Z());
119
120   Standard_Real X, Y, Z;
121   theDir.Coord (X, Y, Z);
122   myCLight.Direction.x() = Standard_ShortReal (X);
123   myCLight.Direction.y() = Standard_ShortReal (Y);
124   myCLight.Direction.z() = Standard_ShortReal (Z);
125
126   myCLight.ChangeConcentration()     = Standard_ShortReal (theConcentration);
127   myCLight.ChangeConstAttenuation()  = Standard_ShortReal (theFact1);
128   myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2);
129   myCLight.ChangeAngle()             = Standard_ShortReal (theAngleCone);
130 }
131
132 // =======================================================================
133 // function : Color
134 // purpose  :
135 // =======================================================================
136 Quantity_Color Visual3d_Light::Color() const
137 {
138   return Quantity_Color (Standard_Real (myCLight.Color.r()),
139                          Standard_Real (myCLight.Color.g()),
140                          Standard_Real (myCLight.Color.b()),
141                          Quantity_TOC_RGB);
142 }
143
144 // =======================================================================
145 // function : LightType
146 // purpose  :
147 // =======================================================================
148 Visual3d_TypeOfLightSource Visual3d_Light::LightType() const
149 {
150   return (Visual3d_TypeOfLightSource )myCLight.Type;
151 }
152
153 // =======================================================================
154 // function : Headlight
155 // purpose  :
156 // =======================================================================
157 Standard_Boolean Visual3d_Light::Headlight() const
158 {
159   return myCLight.IsHeadlight;
160 }
161
162 // =======================================================================
163 // function : SetHeadlight
164 // purpose  :
165 // =======================================================================
166 void Visual3d_Light::SetHeadlight (const Standard_Boolean theValue)
167 {
168   myCLight.IsHeadlight = theValue;
169 }
170
171 // =======================================================================
172 // function : Values
173 // purpose  :
174 // =======================================================================
175 void Visual3d_Light::Values (Quantity_Color& theColor) const
176 {
177   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_AMBIENT,
178                                           "Light Type != Visual3d_TOLS_AMBIENT");
179   theColor.SetValues (Standard_Real (myCLight.Color.r()),
180                       Standard_Real (myCLight.Color.g()),
181                       Standard_Real (myCLight.Color.b()),
182                       Quantity_TOC_RGB);
183 }
184
185 // =======================================================================
186 // function : Values
187 // purpose  :
188 // =======================================================================
189 void Visual3d_Light::Values (Quantity_Color&   theColor,
190                              Graphic3d_Vector& theDir) const
191 {
192   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_DIRECTIONAL,
193                                           "Light Type != Visual3d_TOLS_DIRECTIONAL");
194   theColor.SetValues (Standard_Real (myCLight.Color.r()),
195                       Standard_Real (myCLight.Color.g()),
196                       Standard_Real (myCLight.Color.b()),
197                       Quantity_TOC_RGB);
198   theDir.SetCoord (Standard_Real (myCLight.Direction.x()),
199                    Standard_Real (myCLight.Direction.y()),
200                    Standard_Real (myCLight.Direction.z()));
201 }
202
203 // =======================================================================
204 // function : Values
205 // purpose  :
206 // =======================================================================
207 void Visual3d_Light::Values (Quantity_Color&   theColor,
208                              Graphic3d_Vertex& thePos,
209                              Standard_Real&    theFact1,
210                              Standard_Real&    theFact2) const
211 {
212   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL,
213                                           "Light Type != Visual3d_TOLS_POSITIONAL");
214   theColor.SetValues (Standard_Real (myCLight.Color.r()),
215                       Standard_Real (myCLight.Color.g()),
216                       Standard_Real (myCLight.Color.b()),
217                       Quantity_TOC_RGB);
218   thePos.SetCoord (Standard_Real (myCLight.Position.x()),
219                    Standard_Real (myCLight.Position.y()),
220                    Standard_Real (myCLight.Position.z()));
221   theFact1 = Standard_Real (myCLight.ConstAttenuation());
222   theFact2 = Standard_Real (myCLight.LinearAttenuation());
223 }
224
225 // =======================================================================
226 // function : Values
227 // purpose  :
228 // =======================================================================
229 void Visual3d_Light::Values (Quantity_Color&   theColor,
230                              Graphic3d_Vertex& thePos,
231                              Graphic3d_Vector& theDir,
232                              Standard_Real&    theConcentration,
233                              Standard_Real&    theFact1,
234                              Standard_Real&    theFact2,
235                              Standard_Real&    theAngleCone) const
236 {
237   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT,
238                                           "Light Type != Visual3d_TOLS_SPOT");
239   theColor.SetValues (Standard_Real (myCLight.Color.r()),
240                       Standard_Real (myCLight.Color.g()),
241                       Standard_Real (myCLight.Color.b()),
242                       Quantity_TOC_RGB);
243   thePos.SetCoord (Standard_Real (myCLight.Position.x()),
244                    Standard_Real (myCLight.Position.y()),
245                    Standard_Real (myCLight.Position.z()));
246   theDir.SetCoord (Standard_Real (myCLight.Direction.x()),
247                    Standard_Real (myCLight.Direction.y()),
248                    Standard_Real (myCLight.Direction.z()));
249   theConcentration = Standard_Real (myCLight.Concentration());
250   theFact1         = Standard_Real (myCLight.ConstAttenuation());
251   theFact2         = Standard_Real (myCLight.LinearAttenuation());
252   theAngleCone     = Standard_Real (myCLight.Angle());
253 }
254
255 // =======================================================================
256 // function : SetAngle
257 // purpose  :
258 // =======================================================================
259 void Visual3d_Light::SetAngle (const Standard_Real theAngleCone)
260 {
261   Visual3d_LightDefinitionError_Raise_if (!Visual3d_Light::IsValid (theAngleCone),
262                                           "Bad value for LightAngle");
263   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT,
264                                           "Light Type != Visual3d_TOLS_SPOT");
265   myCLight.ChangeAngle() = Standard_ShortReal (theAngleCone);
266 }
267
268 // =======================================================================
269 // function : SetAttenuation1
270 // purpose  :
271 // =======================================================================
272 void Visual3d_Light::SetAttenuation1 (const Standard_Real theFact1)
273 {
274   Visual3d_LightDefinitionError_Raise_if (theFact1 < 0.0 || theFact1 > 1.0,
275                                           "Bad value for LightAttenuation");
276   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL
277                                        && myCLight.Type != Visual3d_TOLS_SPOT,
278                                           "Light Type != Visual3d_TOLS_SPOT and != Visual3d_TOLS_POSITIONAL");
279   myCLight.ChangeConstAttenuation() = Standard_ShortReal (theFact1);
280 }
281
282 // =======================================================================
283 // function : SetAttenuation2
284 // purpose  :
285 // =======================================================================
286 void Visual3d_Light::SetAttenuation2 (const Standard_Real theFact2)
287 {
288   Visual3d_LightDefinitionError_Raise_if (theFact2 < 0.0 || theFact2 > 1.0,
289                                           "Bad value for LightAttenuation");
290   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_POSITIONAL
291                                        && myCLight.Type != Visual3d_TOLS_SPOT,
292                                           "Light Type != Visual3d_TOLS_SPOT and != Visual3d_TOLS_POSITIONAL");
293   myCLight.ChangeLinearAttenuation() = Standard_ShortReal (theFact2);
294 }
295
296 // =======================================================================
297 // function : SetColor
298 // purpose  :
299 // =======================================================================
300 void Visual3d_Light::SetColor (const Quantity_Color& theColor)
301 {
302   myCLight.Color.r() = float (theColor.Red());
303   myCLight.Color.g() = float (theColor.Green());
304   myCLight.Color.b() = float (theColor.Blue());
305 }
306
307 // =======================================================================
308 // function : SetConcentration
309 // purpose  :
310 // =======================================================================
311 void Visual3d_Light::SetConcentration (const Standard_Real theConcentration)
312 {
313   Visual3d_LightDefinitionError_Raise_if (theConcentration < 0.0 || theConcentration > 1.0,
314                                           "Bad value for LightConcentration");
315   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT,
316                                           "Light Type != Visual3d_TOLS_SPOT");
317   myCLight.ChangeConcentration() = Standard_ShortReal (theConcentration);
318 }
319
320 // =======================================================================
321 // function : SetDirection
322 // purpose  :
323 // =======================================================================
324 void Visual3d_Light::SetDirection (const Graphic3d_Vector& theDir)
325 {
326   Visual3d_LightDefinitionError_Raise_if (theDir.LengthZero(),
327                                           "Bad value for LightDirection");
328   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT
329                                        && myCLight.Type != Visual3d_TOLS_DIRECTIONAL,
330                                           "Light Type != Visual3d_TOLS_DIRECTIONAL and != Visual3d_TOLS_SPOT");
331   Standard_Real X, Y, Z;
332   theDir.Coord (X, Y, Z);
333   const Standard_Real aNorm = Sqrt (X * X + Y * Y + Z * Z);
334   myCLight.Direction.x() = float (X / aNorm);
335   myCLight.Direction.y() = float (Y / aNorm);
336   myCLight.Direction.z() = float (Z / aNorm);
337 }
338
339 // =======================================================================
340 // function : SetPosition
341 // purpose  :
342 // =======================================================================
343 void Visual3d_Light::SetPosition (const Graphic3d_Vertex& thePos)
344 {
345   Visual3d_LightDefinitionError_Raise_if (myCLight.Type != Visual3d_TOLS_SPOT
346                                        && myCLight.Type != Visual3d_TOLS_POSITIONAL,
347                                           "Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT");
348   myCLight.Position.x() = float (thePos.X());
349   myCLight.Position.y() = float (thePos.Y());
350   myCLight.Position.z() = float (thePos.Z());
351 }
352
353 // =======================================================================
354 // function : IsValid
355 // purpose  :
356 // =======================================================================
357 Standard_Boolean Visual3d_Light::IsValid (const Standard_Real theAngle)
358 {
359   return (theAngle <  M_PI)
360       && (theAngle >= 0.0);
361 }
362
363 // =======================================================================
364 // function : CLight
365 // purpose  :
366 // =======================================================================
367 const Graphic3d_CLight& Visual3d_Light::CLight() const
368 {
369   return myCLight;
370 }