1 /****************************************************************************
2 * cones.cpp
3 *
4 * This module implements the cone primitive.
5 * This file was written by Alexander Enzmann. He wrote the code for
6 * cones and generously provided us these enhancements.
7 *
8 * from Persistence of Vision(tm) Ray Tracer version 3.6.
9 * Copyright 1991-2003 Persistence of Vision Team
10 * Copyright 2003-2004 Persistence of Vision Raytracer Pty. Ltd.
11 *---------------------------------------------------------------------------
12 * NOTICE: This source code file is provided so that users may experiment
13 * with enhancements to POV-Ray and to port the software to platforms other
14 * than those supported by the POV-Ray developers. There are strict rules
15 * regarding how you are permitted to use this file. These rules are contained
16 * in the distribution and derivative versions licenses which should have been
17 * provided with this file.
18 *
19 * These licences may be found online, linked from the end-user license
20 * agreement that is located at http://www.povray.org/povlegal.html
21 *---------------------------------------------------------------------------
22 * This program is based on the popular DKB raytracer version 2.12.
23 * DKBTrace was originally written by David K. Buck.
24 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
25 *---------------------------------------------------------------------------
26 *
27 *===========================================================================
28 * This file is part of MegaPOV, a modified and unofficial version of POV-Ray
29 * For more information on MegaPOV visit our website:
30 * http://megapov.inetart.net/
31 *===========================================================================
32 *
33 * $RCSfile: cones.cpp,v $
34 * $Revision: 1.10 $
35 * $Author: chris $
36 *
37 *****************************************************************************/
38
39 #include "frame.h"
40 #include "povray.h"
41 #include "vector.h"
42 #include "bbox.h"
43 #include "cones.h"
44 #include "matrices.h"
45 #include "objects.h"
46
47 BEGIN_POV_NAMESPACE
48
49 /*****************************************************************************
50 * Local preprocessor defines
51 ******************************************************************************/
52
53 const DBL Cone_Tolerance = 1.0e-6;
54
55 #define close(x, y) (fabs(x-y) < EPSILON ? 1 : 0)
56
57 /* Part of the cone/cylinder hit. [DB 9/94] */
58
59 const int BASE_HIT = 1;
60 const int CAP_HIT = 2;
61 const int SIDE_HIT = 3;
62
63
64
65 /*****************************************************************************
66 * Local typedefs
67 ******************************************************************************/
68
69 typedef struct Cone_Intersection_Structure CONE_INT;
70
71 struct Cone_Intersection_Structure
72 {
73 DBL d; /* Distance of intersection point */
74 int t; /* Type of intersection: base/cap plane or side */
75 };
76
77
78
79 /*****************************************************************************
80 * Static functions
81 ******************************************************************************/
82
83 static int intersect_cone (RAY *Ray, CONE *Cone, CONE_INT *Depths);
84 static void Destroy_Cone (OBJECT *Object);
85 static int All_Cone_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
86 static int Inside_Cone (VECTOR point, OBJECT *Object);
87 static void Cone_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
88 static CONE *Copy_Cone (OBJECT *Object);
89 static void Translate_Cone (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
90 static void Rotate_Cone (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
91 static void Scale_Cone (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
92 static void Transform_Cone (OBJECT *Object, TRANSFORM *Trans);
93 static void Invert_Cone (OBJECT *Object);
94
95
96 /*****************************************************************************
97 * Local variables
98 ******************************************************************************/
99
100 METHODS Cone_Methods =
101 {
102 All_Cone_Intersections,
103 Inside_Cone, Cone_Normal, Default_UVCoord,
104 (COPY_METHOD)Copy_Cone, Translate_Cone, Rotate_Cone, Scale_Cone, Transform_Cone,
105 Invert_Cone, Destroy_Cone
106 };
107
108
109
110 /*****************************************************************************
111 *
112 * FUNCTION
113 *
114 * All_Cone_Intersections
115 *
116 * INPUT
117 *
118 * OUTPUT
119 *
120 * RETURNS
121 *
122 * AUTHOR
123 *
124 * Alexander Enzmann
125 *
126 * DESCRIPTION
127 *
128 * -
129 *
130 * CHANGES
131 *
132 * -
133 *
134 ******************************************************************************/
135
All_Cone_Intersections(OBJECT * Object,RAY * Ray,ISTACK * Depth_Stack)136 static int All_Cone_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
137 {
138 int Intersection_Found, cnt, i;
139 VECTOR IPoint;
140 CONE_INT I[4];
141
142 Intersection_Found = false;
143
144 if ((cnt = intersect_cone(Ray, (CONE *)Object, I)) != 0)
145 {
146 for (i = 0; i < cnt; i++)
147 {
148 VEvaluateRay(IPoint, Ray->Initial, I[i].d, Ray->Direction);
149
150 if (Point_In_Clip(IPoint, Object->Clip))
151 {
152 push_entry_i1(I[i].d,IPoint,Object,I[i].t,Depth_Stack);
153
154 Intersection_Found = true;
155 }
156 }
157 }
158
159 return (Intersection_Found);
160 }
161
162
163
164 /*****************************************************************************
165 *
166 * FUNCTION
167 *
168 * intersect_cone
169 *
170 * INPUT
171 *
172 * OUTPUT
173 *
174 * RETURNS
175 *
176 * AUTHOR
177 *
178 * Alexander Enzmann
179 *
180 * DESCRIPTION
181 *
182 * -
183 *
184 * CHANGES
185 *
186 * -
187 *
188 ******************************************************************************/
189
intersect_cone(RAY * Ray,CONE * Cone,CONE_INT * Intersection)190 static int intersect_cone(RAY *Ray, CONE *Cone, CONE_INT *Intersection)
191 {
192 int i = 0;
193 DBL a, b, c, z, t1, t2, len;
194 DBL d;
195 VECTOR P, D;
196
197 Increase_Counter(stats[Ray_Cone_Tests]);
198
199 /* Transform the ray into the cones space */
200
201 MInvTransPoint(P, Ray->Initial, Cone->Trans);
202 MInvTransDirection(D, Ray->Direction, Cone->Trans);
203
204 VLength(len, D);
205 VInverseScaleEq(D, len);
206
207 if (Test_Flag(Cone, CYLINDER_FLAG))
208 {
209 /* Solve intersections with a cylinder */
210
211 a = D[X] * D[X] + D[Y] * D[Y];
212
213 if (a > EPSILON)
214 {
215 b = P[X] * D[X] + P[Y] * D[Y];
216
217 c = P[X] * P[X] + P[Y] * P[Y] - 1.0;
218
219 d = b * b - a * c;
220
221 if (d >= 0.0)
222 {
223 d = sqrt(d);
224
225 t1 = (-b + d) / a;
226 t2 = (-b - d) / a;
227
228 z = P[Z] + t1 * D[Z];
229
230 if ((t1 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= 0.0) && (z <= 1.0))
231 {
232 Intersection[i].d = t1 / len;
233 Intersection[i++].t = SIDE_HIT;
234 }
235
236 z = P[Z] + t2 * D[Z];
237
238 if ((t2 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= 0.0) && (z <= 1.0))
239 {
240 Intersection[i].d = t2 / len;
241 Intersection[i++].t = SIDE_HIT;
242 }
243 }
244 }
245 }
246 else
247 {
248 /* Solve intersections with a cone */
249
250 a = D[X] * D[X] + D[Y] * D[Y] - D[Z] * D[Z];
251
252 b = D[X] * P[X] + D[Y] * P[Y] - D[Z] * P[Z];
253
254 c = P[X] * P[X] + P[Y] * P[Y] - P[Z] * P[Z];
255
256 if (fabs(a) < EPSILON)
257 {
258 if (fabs(b) > EPSILON)
259 {
260 /* One intersection */
261
262 t1 = -0.5 * c / b;
263
264 z = P[Z] + t1 * D[Z];
265
266 if ((t1 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= Cone->dist) && (z <= 1.0))
267 {
268 Intersection[i].d = t1 / len;
269 Intersection[i++].t = SIDE_HIT;
270 }
271 }
272 }
273 else
274 {
275 /* Check hits against the side of the cone */
276
277 d = b * b - a * c;
278
279 if (d >= 0.0)
280 {
281 d = sqrt(d);
282
283 t1 = (-b - d) / a;
284 t2 = (-b + d) / a;
285
286 z = P[Z] + t1 * D[Z];
287
288 if ((t1 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= Cone->dist) && (z <= 1.0))
289 {
290 Intersection[i].d = t1 / len;
291 Intersection[i++].t = SIDE_HIT;
292 }
293
294 z = P[Z] + t2 * D[Z];
295
296 if ((t2 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= Cone->dist) && (z <= 1.0))
297 {
298 Intersection[i].d = t2 / len;
299 Intersection[i++].t = SIDE_HIT;
300 }
301 }
302 }
303 }
304
305 if (Test_Flag(Cone, CLOSED_FLAG) && (fabs(D[Z]) > EPSILON))
306 {
307 d = (1.0 - P[Z]) / D[Z];
308
309 a = (P[X] + d * D[X]);
310
311 b = (P[Y] + d * D[Y]);
312
313 if (((Sqr(a) + Sqr(b)) <= 1.0) && (d > Cone_Tolerance) && (d < Max_Distance))
314 {
315 Intersection[i].d = d / len;
316 Intersection[i++].t = CAP_HIT;
317 }
318
319 d = (Cone->dist - P[Z]) / D[Z];
320
321 a = (P[X] + d * D[X]);
322
323 b = (P[Y] + d * D[Y]);
324
325 if ((Sqr(a) + Sqr(b)) <= (Test_Flag(Cone, CYLINDER_FLAG) ? 1.0 : Sqr(Cone->dist))
326 && (d > Cone_Tolerance) && (d < Max_Distance))
327 {
328 Intersection[i].d = d / len;
329 Intersection[i++].t = BASE_HIT;
330 }
331 }
332
333 if (i)
334 {
335 Increase_Counter(stats[Ray_Cone_Tests_Succeeded]);
336 }
337
338 return (i);
339 }
340
341
342
343 /*****************************************************************************
344 *
345 * FUNCTION
346 *
347 * Inside_Cone
348 *
349 * INPUT
350 *
351 * OUTPUT
352 *
353 * RETURNS
354 *
355 * AUTHOR
356 *
357 * Alexander Enzmann
358 *
359 * DESCRIPTION
360 *
361 * -
362 *
363 * CHANGES
364 *
365 * -
366 *
367 ******************************************************************************/
368
Inside_Cone(VECTOR IPoint,OBJECT * Object)369 static int Inside_Cone(VECTOR IPoint, OBJECT *Object)
370 {
371 CONE *Cone = (CONE *)Object;
372 DBL w2, z2, offset = (Test_Flag(Cone, CLOSED_FLAG) ? -EPSILON : EPSILON);
373 VECTOR New_Point;
374
375 /* Transform the point into the cones space */
376
377 MInvTransPoint(New_Point, IPoint, Cone->Trans);
378
379 /* Test to see if we are inside the cone */
380
381 w2 = New_Point[X] * New_Point[X] + New_Point[Y] * New_Point[Y];
382
383 if (Test_Flag(Cone, CYLINDER_FLAG))
384 {
385 /* Check to see if we are inside a cylinder */
386
387 if ((w2 > 1.0 + offset) ||
388 (New_Point[Z] < 0.0 - offset) ||
389 (New_Point[Z] > 1.0 + offset))
390 {
391 return (Test_Flag(Cone, INVERTED_FLAG));
392 }
393 else
394 {
395 return (!Test_Flag(Cone, INVERTED_FLAG));
396 }
397 }
398 else
399 {
400 /* Check to see if we are inside a cone */
401
402 z2 = New_Point[Z] * New_Point[Z];
403
404 if ((w2 > z2 + offset) ||
405 (New_Point[Z] < Cone->dist - offset) ||
406 (New_Point[Z] > 1.0+offset))
407 {
408 return (Test_Flag(Cone, INVERTED_FLAG));
409 }
410 else
411 {
412 return (!Test_Flag(Cone, INVERTED_FLAG));
413 }
414 }
415 }
416
417
418
419 /*****************************************************************************
420 *
421 * FUNCTION
422 *
423 * Cone_Normal
424 *
425 * INPUT
426 *
427 * OUTPUT
428 *
429 * RETURNS
430 *
431 * AUTHOR
432 *
433 * Alexander Enzmann
434 *
435 * DESCRIPTION
436 *
437 * -
438 *
439 * CHANGES
440 *
441 * -
442 *
443 ******************************************************************************/
444
Cone_Normal(VECTOR Result,OBJECT * Object,INTERSECTION * Inter)445 static void Cone_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
446 {
447 CONE *Cone = (CONE *)Object;
448
449 /* Transform the point into the cones space */
450
451 MInvTransPoint(Result, Inter->IPoint, Cone->Trans);
452
453 /* Calculating the normal is real simple in canonical cone space */
454
455 switch (Inter->i1)
456 {
457 case SIDE_HIT:
458
459 if (Test_Flag(Cone, CYLINDER_FLAG))
460 {
461 Result[Z] = 0.0;
462 }
463 else
464 {
465 Result[Z] = -Result[Z];
466 }
467
468 break;
469
470 case BASE_HIT:
471
472 Make_Vector(Result, 0.0, 0.0, -1.0);
473
474 break;
475
476 case CAP_HIT:
477
478 Make_Vector(Result, 0.0, 0.0, 1.0);
479
480 break;
481 }
482
483 /* Transform the point out of the cones space */
484
485 MTransNormal(Result, Result, Cone->Trans);
486
487 VNormalize(Result, Result);
488 }
489
490
491
492 /*****************************************************************************
493 *
494 * FUNCTION
495 *
496 * Translate_Cone
497 *
498 * INPUT
499 *
500 * OUTPUT
501 *
502 * RETURNS
503 *
504 * AUTHOR
505 *
506 * Alexander Enzmann
507 *
508 * DESCRIPTION
509 *
510 * -
511 *
512 * CHANGES
513 *
514 * -
515 *
516 ******************************************************************************/
517
Translate_Cone(OBJECT * Object,VECTOR,TRANSFORM * Trans)518 static void Translate_Cone(OBJECT *Object, VECTOR, TRANSFORM *Trans)
519 {
520 Transform_Cone(Object, Trans);
521 }
522
523
524
525 /*****************************************************************************
526 *
527 * FUNCTION
528 *
529 * Rotate_Cone
530 *
531 * INPUT
532 *
533 * OUTPUT
534 *
535 * RETURNS
536 *
537 * AUTHOR
538 *
539 * Alexander Enzmann
540 *
541 * DESCRIPTION
542 *
543 * -
544 *
545 * CHANGES
546 *
547 * -
548 *
549 ******************************************************************************/
550
Rotate_Cone(OBJECT * Object,VECTOR,TRANSFORM * Trans)551 static void Rotate_Cone(OBJECT *Object, VECTOR, TRANSFORM *Trans)
552 {
553 Transform_Cone(Object, Trans);
554 }
555
556
557
558 /*****************************************************************************
559 *
560 * FUNCTION
561 *
562 * Scale_Cone
563 *
564 * INPUT
565 *
566 * OUTPUT
567 *
568 * RETURNS
569 *
570 * AUTHOR
571 *
572 * Alexander Enzmann
573 *
574 * DESCRIPTION
575 *
576 * -
577 *
578 * CHANGES
579 *
580 * -
581 *
582 ******************************************************************************/
583
Scale_Cone(OBJECT * Object,VECTOR,TRANSFORM * Trans)584 static void Scale_Cone(OBJECT *Object, VECTOR, TRANSFORM *Trans)
585 {
586 Transform_Cone(Object, Trans);
587 }
588
589
590
591 /*****************************************************************************
592 *
593 * FUNCTION
594 *
595 * Transform_Cone
596 *
597 * INPUT
598 *
599 * OUTPUT
600 *
601 * RETURNS
602 *
603 * AUTHOR
604 *
605 * Alexander Enzmann
606 *
607 * DESCRIPTION
608 *
609 * -
610 *
611 * CHANGES
612 *
613 * -
614 *
615 ******************************************************************************/
616
Transform_Cone(OBJECT * Object,TRANSFORM * Trans)617 static void Transform_Cone(OBJECT *Object, TRANSFORM *Trans)
618 {
619 CONE *Cone = (CONE *)Object;
620
621 Compose_Transforms(Cone->Trans, Trans);
622
623 Compute_Cone_BBox(Cone);
624 }
625
626
627
628 /*****************************************************************************
629 *
630 * FUNCTION
631 *
632 * Invert_Cone
633 *
634 * INPUT
635 *
636 * OUTPUT
637 *
638 * RETURNS
639 *
640 * AUTHOR
641 *
642 * Alexander Enzmann
643 *
644 * DESCRIPTION
645 *
646 * -
647 *
648 * CHANGES
649 *
650 * -
651 *
652 ******************************************************************************/
653
Invert_Cone(OBJECT * Object)654 static void Invert_Cone(OBJECT *Object)
655 {
656 Invert_Flag(Object, INVERTED_FLAG);
657 }
658
659
660
661 /*****************************************************************************
662 *
663 * FUNCTION
664 *
665 * Create_Cone
666 *
667 * INPUT
668 *
669 * OUTPUT
670 *
671 * RETURNS
672 *
673 * AUTHOR
674 *
675 * Alexander Enzmann
676 *
677 * DESCRIPTION
678 *
679 * -
680 *
681 * CHANGES
682 *
683 * -
684 *
685 ******************************************************************************/
686
Create_Cone()687 CONE *Create_Cone()
688 {
689 CONE *New;
690
691 New = (CONE *)POV_MALLOC(sizeof(CONE), "cone");
692
693 INIT_OBJECT_FIELDS(New, CONE_OBJECT, &Cone_Methods)
694
695 Make_Vector(New->apex, 0.0, 0.0, 1.0);
696 Make_Vector(New->base, 0.0, 0.0, 0.0);
697
698 New->apex_radius = 1.0;
699 New->base_radius = 0.0;
700
701 New->dist = 0.0;
702
703 New->Trans = Create_Transform();
704
705 /* Cone/Cylinder has capped ends by default. */
706
707 Set_Flag(New, CLOSED_FLAG);
708
709 /* Default bounds */
710
711 Make_BBox(New->BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0);
712
713 return (New);
714 }
715
716
717
718 /*****************************************************************************
719 *
720 * FUNCTION
721 *
722 * Copy_Cone
723 *
724 * INPUT
725 *
726 * OUTPUT
727 *
728 * RETURNS
729 *
730 * AUTHOR
731 *
732 * Alexander Enzmann
733 *
734 * DESCRIPTION
735 *
736 * -
737 *
738 * CHANGES
739 *
740 * -
741 *
742 ******************************************************************************/
743
Copy_Cone(OBJECT * Object)744 static CONE *Copy_Cone(OBJECT *Object)
745 {
746 CONE *New;
747
748 New = Create_Cone();
749
750 /* Get rid of the transformation created in Create_Cone(). */
751
752 Destroy_Transform(New->Trans);
753
754 /* Copy cone. */
755
756 *New = *((CONE *)Object);
757
758 New->Trans = Copy_Transform(((CONE *)Object)->Trans);
759
760 return (New);
761 }
762
763
764
765 /*****************************************************************************
766 *
767 * FUNCTION
768 *
769 * Create_Cylinder
770 *
771 * INPUT
772 *
773 * OUTPUT
774 *
775 * RETURNS
776 *
777 * AUTHOR
778 *
779 * Alexander Enzmann
780 *
781 * DESCRIPTION
782 *
783 * -
784 *
785 * CHANGES
786 *
787 * -
788 *
789 ******************************************************************************/
790
Create_Cylinder()791 CONE *Create_Cylinder()
792 {
793 CONE *New;
794
795 New = (CONE *)POV_MALLOC(sizeof(CONE), "cone");
796
797 INIT_OBJECT_FIELDS(New, CONE_OBJECT, &Cone_Methods)
798
799 Make_Vector(New->apex, 0.0, 0.0, 1.0);
800 Make_Vector(New->base, 0.0, 0.0, 0.0);
801
802 New->apex_radius = 1.0;
803 New->base_radius = 1.0;
804 New->dist = 0.0;
805
806 New->Trans = Create_Transform();
807
808 Set_Flag(New, CYLINDER_FLAG); /* This is a cylinder. */
809 Set_Flag(New, CLOSED_FLAG); /* Has capped ends. */
810
811 /* Default bounds */
812
813 Make_BBox(New->BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0);
814
815 return (New);
816 }
817
818
819
820 /*****************************************************************************
821 *
822 * FUNCTION
823 *
824 * Compute_Cone_Data
825 *
826 * INPUT
827 *
828 * OUTPUT
829 *
830 * RETURNS
831 *
832 * AUTHOR
833 *
834 * Alexander Enzmann
835 *
836 * DESCRIPTION
837 *
838 * -
839 *
840 * CHANGES
841 *
842 * Feb 1996: check for equal sized ends (cylinder) first [AED]
843 *
844 ******************************************************************************/
845
Compute_Cone_Data(OBJECT * Object)846 void Compute_Cone_Data(OBJECT *Object)
847 {
848 DBL tlen, len, tmpf;
849 VECTOR tmpv, axis, origin;
850 CONE *Cone = (CONE *)Object;
851
852 /* Process the primitive specific information */
853
854 if (fabs(Cone->apex_radius - Cone->base_radius) < EPSILON)
855 {
856 /* What we are dealing with here is really a cylinder */
857
858 Set_Flag(Cone, CYLINDER_FLAG);
859
860 Compute_Cylinder_Data(Object);
861
862 return;
863 }
864
865 if (Cone->apex_radius < Cone->base_radius)
866 {
867 /* Want the bigger end at the top */
868
869 Assign_Vector(tmpv,Cone->base);
870 Assign_Vector(Cone->base,Cone->apex);
871 Assign_Vector(Cone->apex,tmpv);
872
873 tmpf = Cone->base_radius;
874 Cone->base_radius = Cone->apex_radius;
875 Cone->apex_radius = tmpf;
876 }
877
878 /* Find the axis and axis length */
879
880 VSub(axis, Cone->apex, Cone->base);
881
882 VLength(len, axis);
883
884 if (len < EPSILON)
885 {
886 Error("Degenerate cone/cylinder.");
887 }
888 else
889 {
890 VInverseScaleEq(axis, len);
891 }
892
893 /* Determine alignment */
894
895 tmpf = Cone->base_radius * len / (Cone->apex_radius - Cone->base_radius);
896
897 VScale(origin, axis, tmpf);
898
899 VSub(origin, Cone->base, origin);
900
901 tlen = tmpf + len;
902
903 Cone->dist = tmpf / tlen;
904
905 Compute_Coordinate_Transform(Cone->Trans, origin, axis, Cone->apex_radius, tlen);
906
907 /* Recalculate the bounds */
908
909 Compute_Cone_BBox(Cone);
910 }
911
912
913
914 /*****************************************************************************
915 *
916 * FUNCTION
917 *
918 * Compute_Cylinder_Data
919 *
920 * INPUT
921 *
922 * OUTPUT
923 *
924 * RETURNS
925 *
926 * AUTHOR
927 *
928 * Alexander Enzmann
929 *
930 * DESCRIPTION
931 *
932 * -
933 *
934 * CHANGES
935 *
936 * -
937 *
938 ******************************************************************************/
939
Compute_Cylinder_Data(OBJECT * Object)940 void Compute_Cylinder_Data(OBJECT *Object)
941 {
942 DBL tmpf;
943 VECTOR axis;
944 CONE *Cone = (CONE *)Object;
945
946 VSub(axis, Cone->apex, Cone->base);
947
948 VLength(tmpf, axis);
949
950 if (tmpf < EPSILON)
951 {
952 Error("Degenerate cylinder, base point = apex point.");
953 }
954 else
955 {
956 VInverseScaleEq(axis, tmpf);
957
958 Compute_Coordinate_Transform(Cone->Trans, Cone->base, axis, Cone->apex_radius, tmpf);
959 }
960
961 Cone->dist = 0.0;
962
963 /* Recalculate the bounds */
964
965 Compute_Cone_BBox(Cone);
966 }
967
968
969
970
971 /*****************************************************************************
972 *
973 * FUNCTION
974 *
975 * Destroy_Cone
976 *
977 * INPUT
978 *
979 * OUTPUT
980 *
981 * RETURNS
982 *
983 * AUTHOR
984 *
985 * Alexander Enzmann
986 *
987 * DESCRIPTION
988 *
989 * -
990 *
991 * CHANGES
992 *
993 * -
994 *
995 ******************************************************************************/
996
Destroy_Cone(OBJECT * Object)997 static void Destroy_Cone(OBJECT *Object)
998 {
999 #if(DUMP_OBJECT_DATA == 1)
1000 Debug_Info("{ // CONE \n");
1001 DUMP_OBJECT_FIELDS(Object);
1002 Debug_Info("\t{ %f, %f, %f }, // apex\n", \
1003 (DBL)((CONE *)Object)->apex[X], \
1004 (DBL)((CONE *)Object)->apex[Y], \
1005 (DBL)((CONE *)Object)->apex[Z]); \
1006 Debug_Info("\t{ %f, %f, %f }, // base\n", \
1007 (DBL)((CONE *)Object)->base[X], \
1008 (DBL)((CONE *)Object)->base[Y], \
1009 (DBL)((CONE *)Object)->base[Z]); \
1010 Debug_Info("\t%f, // apex_radius\n", (DBL)((CONE *)Object)->apex_radius);
1011 Debug_Info("\t%f, // base_radius\n", (DBL)((CONE *)Object)->base_radius);
1012 Debug_Info("\t%f // dist\n", (DBL)((CONE *)Object)->dist);
1013 Debug_Info("}\n");
1014 #endif
1015
1016 Destroy_Transform(((CONE *)Object)->Trans);
1017
1018 POV_FREE (Object);
1019 }
1020
1021
1022
1023 /*****************************************************************************
1024 *
1025 * FUNCTION
1026 *
1027 * Compute_Cone_BBox
1028 *
1029 * INPUT
1030 *
1031 * Cone - Cone/Cylinder
1032 *
1033 * OUTPUT
1034 *
1035 * Cone
1036 *
1037 * RETURNS
1038 *
1039 * AUTHOR
1040 *
1041 * Dieter Bayer
1042 *
1043 * DESCRIPTION
1044 *
1045 * Calculate the bounding box of a cone or cylinder.
1046 *
1047 * CHANGES
1048 *
1049 * Aug 1994 : Creation.
1050 * 2000 : cone bounding fix
1051 *
1052 ******************************************************************************/
1053
Compute_Cone_BBox(CONE * Cone)1054 void Compute_Cone_BBox(CONE *Cone)
1055 {
1056 Make_BBox(Cone->BBox, -1.0, -1.0, Cone->dist, 2.0, 2.0, 1.0-Cone->dist);
1057
1058 Recompute_BBox(&Cone->BBox, Cone->Trans);
1059 }
1060
1061 END_POV_NAMESPACE
1062