1 //******************************************************************************
2 ///
3 /// @file core/scene/atmosphere.cpp
4 ///
5 /// Implementations related to atmospheric effects and sky spheres.
6 ///
7 /// @copyright
8 /// @parblock
9 ///
10 /// Persistence of Vision Ray Tracer ('POV-Ray') version 3.8.
11 /// Copyright 1991-2018 Persistence of Vision Raytracer Pty. Ltd.
12 ///
13 /// POV-Ray is free software: you can redistribute it and/or modify
14 /// it under the terms of the GNU Affero General Public License as
15 /// published by the Free Software Foundation, either version 3 of the
16 /// License, or (at your option) any later version.
17 ///
18 /// POV-Ray is distributed in the hope that it will be useful,
19 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
20 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 /// GNU Affero General Public License for more details.
22 ///
23 /// You should have received a copy of the GNU Affero General Public License
24 /// along with this program.  If not, see <http://www.gnu.org/licenses/>.
25 ///
26 /// ----------------------------------------------------------------------------
27 ///
28 /// POV-Ray is based on the popular DKB raytracer version 2.12.
29 /// DKBTrace was originally written by David K. Buck.
30 /// DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
31 ///
32 /// @endparblock
33 ///
34 //******************************************************************************
35 
36 // Unit header file must be the first file included within POV-Ray *.cpp files (pulls in config)
37 #include "core/scene/atmosphere.h"
38 
39 #include <algorithm>
40 
41 #include "core/material/pattern.h"
42 #include "core/material/warp.h"
43 #include "core/material/pigment.h"
44 #include "core/material/texture.h"
45 #include "core/math/matrix.h"
46 
47 // this must be the last file included
48 #include "base/povdebug.h"
49 
50 namespace pov
51 {
52 
Fog_Struct()53 Fog_Struct::Fog_Struct() :
54     Turb(nullptr),
55     Next(nullptr)
56 {}
57 
~Fog_Struct()58 Fog_Struct::~Fog_Struct()
59 {
60     if (Turb) delete Turb;
61 }
62 
63 /*****************************************************************************
64 *
65 * FUNCTION
66 *
67 *   Create_Fog
68 *
69 * INPUT
70 *
71 * OUTPUT
72 *
73 * RETURNS
74 *
75 *   FOG * - created fog
76 *
77 * AUTHOR
78 *
79 *   Dieter Bayer
80 *
81 * DESCRIPTION
82 *
83 *   Create a fog.
84 *
85 * CHANGES
86 *
87 *   Dec 1994 : Creation.
88 *
89 ******************************************************************************/
90 
Create_Fog()91 FOG *Create_Fog()
92 {
93     FOG *New;
94 
95     New = new FOG;
96 
97     New->Type = ORIG_FOG;
98 
99     New->Distance = 0.0;
100     New->Alt      = 0.0;
101     New->Offset   = 0.0;
102 
103     New->colour.Clear();
104 
105     New->Up = Vector3d(0.0, 1.0, 0.0);
106 
107     New->Turb = nullptr;
108     New->Turb_Depth = 0.5;
109 
110     New->Next = nullptr;
111 
112     return (New);
113 }
114 
115 
116 
117 /*****************************************************************************
118 *
119 * FUNCTION
120 *
121 *   Copy_Fog
122 *
123 * INPUT
124 *
125 *   Old - fog to copy
126 *
127 * OUTPUT
128 *
129 * RETURNS
130 *
131 *   FOG * - new fog
132 *
133 * AUTHOR
134 *
135 *   Dieter Bayer
136 *
137 * DESCRIPTION
138 *
139 *   Copy a fog.
140 *
141 * CHANGES
142 *
143 *   Dec 1994 : Creation.
144 *
145 ******************************************************************************/
146 
Copy_Fog(const FOG * Old)147 FOG *Copy_Fog(const FOG *Old)
148 {
149     FOG *New;
150 
151     New = Create_Fog();
152 
153     *New = *Old;
154 
155     New->Turb = new TurbulenceWarp();
156 
157     return (New);
158 }
159 
160 
161 
162 /*****************************************************************************
163 *
164 * FUNCTION
165 *
166 *   Destroy_Fog
167 *
168 * INPUT
169 *
170 *   Fog - fog to destroy
171 *
172 * OUTPUT
173 *
174 * RETURNS
175 *
176 * AUTHOR
177 *
178 *   Dieter Bayer
179 *
180 * DESCRIPTION
181 *
182 *   Destroy a fog.
183 *
184 * CHANGES
185 *
186 *   Dec 1994 : Creation.
187 *
188 ******************************************************************************/
189 
Destroy_Fog(FOG * Fog)190 void Destroy_Fog(FOG *Fog)
191 {
192     if (Fog != nullptr)
193         delete Fog;
194 }
195 
196 
197 
198 /*****************************************************************************
199 *
200 * FUNCTION
201 *
202 *   Create_Rainbow
203 *
204 * INPUT
205 *
206 * OUTPUT
207 *
208 * RETURNS
209 *
210 *   RAINBOW * - created rainbow
211 *
212 * AUTHOR
213 *
214 *   Dieter Bayer
215 *
216 * DESCRIPTION
217 *
218 *   Create a rainbow.
219 *
220 * CHANGES
221 *
222 *   Dec 1994 : Creation.
223 *
224 ******************************************************************************/
225 
Create_Rainbow()226 RAINBOW *Create_Rainbow()
227 {
228     RAINBOW *New;
229 
230     New = new RAINBOW;
231 
232     New->Distance = MAX_DISTANCE;
233     New->Jitter   = 0.0;
234     New->Angle    = 0.0;
235     New->Width    = 0.0;
236 
237     New->Falloff_Width  = 0.0;
238     New->Arc_Angle      = 180.0;
239     New->Falloff_Angle  = 180.0;
240 
241     New->Pigment = nullptr;
242 
243     New->Antisolar_Vector = Vector3d(0.0, 0.0, 0.0);
244 
245     New->Right_Vector = Vector3d(1.0, 0.0, 0.0);
246     New->Up_Vector = Vector3d(0.0, 1.0, 0.0);
247 
248     New->Next = nullptr;
249 
250     return (New);
251 }
252 
253 
254 
255 /*****************************************************************************
256 *
257 * FUNCTION
258 *
259 *   Copy_Rainbow
260 *
261 * INPUT
262 *
263 *   Old - rainbow to copy
264 *
265 * OUTPUT
266 *
267 * RETURNS
268 *
269 *   RAINBOW * - new rainbow
270 *
271 * AUTHOR
272 *
273 *   Dieter Bayer
274 *
275 * DESCRIPTION
276 *
277 *   Copy a rainbow.
278 *
279 * CHANGES
280 *
281 *   Dec 1994 : Creation.
282 *
283 ******************************************************************************/
284 
Copy_Rainbow(const RAINBOW * Old)285 RAINBOW *Copy_Rainbow(const RAINBOW *Old)
286 {
287     RAINBOW *New;
288 
289     New = Create_Rainbow();
290 
291     *New = *Old;
292 
293     return (New);
294 }
295 
296 
297 
298 /*****************************************************************************
299 *
300 * FUNCTION
301 *
302 *   Destroy_Rainbow
303 *
304 * INPUT
305 *
306 *   Rainbow - rainbow to destroy
307 *
308 * OUTPUT
309 *
310 * RETURNS
311 *
312 * AUTHOR
313 *
314 *   Dieter Bayer
315 *
316 * DESCRIPTION
317 *
318 *   Destroy a rainbow.
319 *
320 * CHANGES
321 *
322 *   Dec 1994 : Creation.
323 *
324 ******************************************************************************/
325 
Destroy_Rainbow(RAINBOW * Rainbow)326 void Destroy_Rainbow(RAINBOW *Rainbow)
327 {
328     if (Rainbow != nullptr)
329         delete Rainbow;
330 }
331 
332 
333 
334 /*****************************************************************************
335 *
336 * FUNCTION
337 *
338 *   Create_Skysphere
339 *
340 * INPUT
341 *
342 * OUTPUT
343 *
344 * RETURNS
345 *
346 *   SKYSPHERE * - created skysphere
347 *
348 * AUTHOR
349 *
350 *   Dieter Bayer
351 *
352 * DESCRIPTION
353 *
354 *   Create a skysphere.
355 *
356 * CHANGES
357 *
358 *   Dec 1994 : Creation.
359 *
360 ******************************************************************************/
361 
Create_Skysphere()362 SKYSPHERE *Create_Skysphere()
363 {
364     SKYSPHERE *New;
365 
366     New = new SKYSPHERE;
367 
368     New->Emission = MathColour(1.0);
369 
370     New->Trans = Create_Transform();
371 
372     return (New);
373 }
374 
375 
376 
377 /*****************************************************************************
378 *
379 * FUNCTION
380 *
381 *   Copy_Skysphere
382 *
383 * INPUT
384 *
385 *   Old - skysphere to copy
386 *
387 * OUTPUT
388 *
389 * RETURNS
390 *
391 *   SKYSPHERE * - copied skysphere
392 *
393 * AUTHOR
394 *
395 *   Dieter Bayer
396 *
397 * DESCRIPTION
398 *
399 *   Copy a skysphere.
400 *
401 * CHANGES
402 *
403 *   Dec 1994 : Creation.
404 *
405 ******************************************************************************/
406 
Copy_Skysphere(const SKYSPHERE * Old)407 SKYSPHERE *Copy_Skysphere(const SKYSPHERE *Old)
408 {
409     SKYSPHERE *New;
410 
411     New = Create_Skysphere();
412 
413     Destroy_Transform(New->Trans);
414 
415     *New = *Old;
416 
417     New->Trans = Copy_Transform(Old->Trans);
418 
419     // The standard assignment operator of SKYSPHERE has created a shallow copy of the Pigments vector, but we need a
420     // deep copy in case Old gets destroyed.
421     for (vector<PIGMENT*>::iterator i = New->Pigments.begin(); i != New->Pigments.end(); ++ i)
422     {
423         *i = Copy_Pigment(*i);
424     }
425 
426     return (New);
427 }
428 
429 
430 
431 /*****************************************************************************
432 *
433 * FUNCTION
434 *
435 *   Destroy_Skysphere
436 *
437 * INPUT
438 *
439 *   Skysphere - skysphere to destroy
440 *
441 * OUTPUT
442 *
443 * RETURNS
444 *
445 * AUTHOR
446 *
447 *   Dieter Bayer
448 *
449 * DESCRIPTION
450 *
451 *   Destroy a skysphere.
452 *
453 * CHANGES
454 *
455 *   Dec 1994 : Creation.
456 *
457 ******************************************************************************/
458 
Destroy_Skysphere(SKYSPHERE * Skysphere)459 void Destroy_Skysphere(SKYSPHERE *Skysphere)
460 {
461     if (Skysphere != nullptr)
462         delete Skysphere;
463 }
464 
~Skysphere_Struct()465 Skysphere_Struct::~Skysphere_Struct()
466 {
467     for (vector<PIGMENT*>::iterator i = Pigments.begin(); i != Pigments.end(); ++ i)
468         delete *i;
469     Destroy_Transform(Trans);
470 }
471 
472 
473 /*****************************************************************************
474 *
475 * FUNCTION
476 *
477 *   Rotate_Skysphere
478 *
479 * INPUT
480 *
481 *   Vector - Rotation vector
482 *
483 * OUTPUT
484 *
485 *   Skysphere - Pointer to skysphere structure
486 *
487 * RETURNS
488 *
489 * AUTHOR
490 *
491 *   Dieter Bayer
492 *
493 * DESCRIPTION
494 *
495 *   Rotate a skysphere.
496 *
497 * CHANGES
498 *
499 *   Feb 1996 : Creation.
500 *
501 ******************************************************************************/
502 
Rotate_Skysphere(SKYSPHERE * Skysphere,const Vector3d & Vector)503 void Rotate_Skysphere(SKYSPHERE *Skysphere, const Vector3d& Vector)
504 {
505     TRANSFORM Trans;
506 
507     Compute_Rotation_Transform(&Trans, Vector);
508 
509     Transform_Skysphere(Skysphere, &Trans);
510 }
511 
512 
513 
514 /*****************************************************************************
515 *
516 * FUNCTION
517 *
518 *   Scale_Skysphere
519 *
520 * INPUT
521 *
522 *   Vector - Scaling vector
523 *
524 * OUTPUT
525 *
526 *   Skysphere - Pointer to skysphere structure
527 *
528 * RETURNS
529 *
530 * AUTHOR
531 *
532 *   Dieter Bayer
533 *
534 * DESCRIPTION
535 *
536 *   Scale a skysphere.
537 *
538 * CHANGES
539 *
540 *   Feb 1996 : Creation.
541 *
542 ******************************************************************************/
543 
Scale_Skysphere(SKYSPHERE * Skysphere,const Vector3d & Vector)544 void Scale_Skysphere(SKYSPHERE *Skysphere, const Vector3d& Vector)
545 {
546     TRANSFORM Trans;
547 
548     Compute_Scaling_Transform(&Trans, Vector);
549 
550     Transform_Skysphere(Skysphere, &Trans);
551 }
552 
553 
554 
555 /*****************************************************************************
556 *
557 * FUNCTION
558 *
559 *   Translate_Skysphere
560 *
561 * INPUT
562 *
563 *   Vector - Translation vector
564 *
565 * OUTPUT
566 *
567 *   Skysphere - Pointer to skysphere structure
568 *
569 * RETURNS
570 *
571 * AUTHOR
572 *
573 *   Dieter Bayer
574 *
575 * DESCRIPTION
576 *
577 *   Translate a skysphere.
578 *
579 * CHANGES
580 *
581 *   Feb 1996 : Creation.
582 *
583 ******************************************************************************/
584 
Translate_Skysphere(SKYSPHERE * Skysphere,const Vector3d & Vector)585 void Translate_Skysphere(SKYSPHERE *Skysphere, const Vector3d& Vector)
586 {
587     TRANSFORM Trans;
588 
589     Compute_Translation_Transform(&Trans, Vector);
590 
591     Transform_Skysphere(Skysphere, &Trans);
592 }
593 
594 
595 
596 /*****************************************************************************
597 *
598 * FUNCTION
599 *
600 *   Transform_Skysphere
601 *
602 * INPUT
603 *
604 *   Trans  - Pointer to transformation
605 *
606 * OUTPUT
607 *
608 *   Skysphere - Pointer to skysphere structure
609 *
610 * RETURNS
611 *
612 * AUTHOR
613 *
614 *   Dieter Bayer
615 *
616 * DESCRIPTION
617 *
618 *   Transform a skysphere.
619 *
620 * CHANGES
621 *
622 *   Feb 1996 : Creation.
623 *
624 ******************************************************************************/
625 
Transform_Skysphere(SKYSPHERE * Skysphere,const TRANSFORM * Trans)626 void Transform_Skysphere(SKYSPHERE *Skysphere, const TRANSFORM *Trans)
627 {
628     if (Skysphere->Trans == nullptr)
629     {
630         Skysphere->Trans = Create_Transform();
631     }
632 
633     Compose_Transforms(Skysphere->Trans, Trans);
634 }
635 
636 }
637