1 /****************************************************************************
4 * This module parses textures and atmosphere effects.
6 * from Persistence of Vision(tm) Ray Tracer
7 * Copyright 1996,1999 Persistence of Vision Team
8 *---------------------------------------------------------------------------
9 * NOTICE: This source code file is provided so that users may experiment
10 * with enhancements to POV-Ray and to port the software to platforms other
11 * than those supported by the POV-Ray Team. There are strict rules under
12 * which you are permitted to use this file. The rules are in the file
13 * named POVLEGAL.DOC which should be distributed with this file.
14 * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
15 * Team Coordinator by email to team-coord@povray.org or visit us on the web at
16 * http://www.povray.org. The latest version of POV-Ray may be found at this site.
18 * This program is based on the popular DKB raytracer version 2.12.
19 * DKBTrace was originally written by David K. Buck.
20 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
22 * Modifications by Thomas Willhalm, March 1999, used with permission.
24 *****************************************************************************/
49 /*****************************************************************************
50 * Local preprocessor defines
51 ******************************************************************************/
53 #define ADD_TNORMAL if (Tnormal == NULL) {if ((Default_Texture->Tnormal) != NULL) \
54 Tnormal = Copy_Tnormal ((Default_Texture->Tnormal)); else Tnormal = Create_Tnormal ();\
55 Texture->Tnormal=Tnormal;};
57 /*****************************************************************************
59 ******************************************************************************/
63 /*****************************************************************************
65 ******************************************************************************/
67 TEXTURE
*Default_Texture
;
71 /*****************************************************************************
73 ******************************************************************************/
75 static void Parse_Bump_Map (TNORMAL
*Tnormal
);
76 static void Parse_Image_Map (PIGMENT
*Pigment
);
77 static void Parse_Pattern (TPATTERN
*New
, int TPat_Type
);
78 static TEXTURE
*Parse_Vers1_Texture (void);
79 static TEXTURE
*Parse_Tiles (void);
80 static TEXTURE
*Parse_Material_Map (void);
81 static void Parse_Texture_Transform (TEXTURE
*Texture
);
82 static TURB
*Check_Turb (WARP
**Warps_Ptr
);
83 static void Parse_Warp (WARP
**Warp_Ptr
);
84 static void Check_BH_Parameters (BLACK_HOLE
*bh
);
85 static void Warn_Interior (char *s
);
89 /*****************************************************************************
107 ******************************************************************************/
109 IMAGE
*Parse_Image (int Legal
)
115 Image
= Create_Image ();
117 Image
->Image_Type
= Legal
;
119 if (Legal
& GRAD_FILE
)
123 Warn(1.5, "Old style orientation vector or map type not supported. Ignoring value.");
124 Parse_Vector (Local_Vector
);
136 Image
->File_Type
= IFF_FILE
;
138 Read_Iff_Image (Image
, Name
);
144 Image
->File_Type
= GIF_FILE
;
146 Read_Gif_Image(Image
, Name
);
152 Image
->File_Type
= POT_FILE
;
154 Read_Gif_Image(Image
, Name
);
160 Image
->File_Type
= SYS_FILE
;
162 READ_SYS_IMAGE(Image
, Name
);
168 Image
->File_Type
= TGA_FILE
;
170 Read_Targa_Image(Image
, Name
);
176 Image
->File_Type
= PNG_FILE
;
178 Read_Png_Image(Image
, Name
);
184 Image
->File_Type
= PGM_FILE
;
186 Read_PGM_Image(Image
, Name
);
192 Image
->File_Type
= PPM_FILE
;
194 Read_PPM_Image(Image
, Name
);
200 Parse_Error_Str ("map file spec");
204 if (!(Image
->File_Type
& Legal
))
205 Error ("File type not supported here.");
211 /*****************************************************************************
229 ******************************************************************************/
231 static void Parse_Image_Map (PIGMENT
*Pigment
)
238 Image
= Parse_Image (IMAGE_FILE
);
239 Image
->Use_Colour_Flag
= TRUE
;
241 EXPECT
/* Look for image_attribs */
243 Image
->Once_Flag
=TRUE
;
246 CASE (INTERPOLATE_TOKEN
)
247 Image
->Interpolation_Type
= (int)Parse_Float();
250 CASE (MAP_TYPE_TOKEN
)
251 Image
->Map_Type
= (int) Parse_Float ();
254 CASE (USE_COLOUR_TOKEN
)
255 Image
->Use_Colour_Flag
= TRUE
;
258 CASE (USE_INDEX_TOKEN
)
259 Image
->Use_Colour_Flag
= FALSE
;
263 Warn(1.55, "Keyword ALPHA discontinued. Use FILTER instead.");
265 CASE (COLOUR_KEY_TOKEN
)
266 switch(Token
.Function_Id
)
273 filter
= Parse_Float();
274 for (reg
= 0 ; reg
< Image
->Colour_Map_Size
; reg
++)
275 Image
->Colour_Map
[reg
].Filter
276 = (unsigned short) (filter
*255.0);
283 reg
= (int)(Parse_Float() + 0.01);
284 if (Image
->Colour_Map
== NULL
)
285 Not_With ("filter","non color-mapped image");
286 if ((reg
< 0) || (reg
>= Image
->Colour_Map_Size
))
287 Error ("FILTER color register value out of range.");
290 Image
->Colour_Map
[reg
].Filter
291 = (unsigned short) (255.0 * Parse_Float());
296 Pigment
->Flags
|= HAS_FILTER
;
304 transmit
= Parse_Float();
305 for (reg
= 0 ; reg
< Image
->Colour_Map_Size
; reg
++)
306 Image
->Colour_Map
[reg
].Transmit
307 = (unsigned short) (transmit
*255.0);
314 reg
= (int)(Parse_Float() + 0.01);
315 if (Image
->Colour_Map
== NULL
)
316 Not_With ("transmit","non color-mapped image");
317 if ((reg
< 0) || (reg
>= Image
->Colour_Map_Size
))
318 Error ("TRANSMIT color register value out of range.");
321 Image
->Colour_Map
[reg
].Transmit
322 = (unsigned short) (255.0 * Parse_Float());
327 Pigment
->Flags
|= HAS_FILTER
;
332 Parse_Error_Str ("filter or transmit");
343 Pigment
->Vals
.Image
=Image
;
349 /*****************************************************************************
367 ******************************************************************************/
369 static void Parse_Bump_Map (TNORMAL
*Tnormal
)
375 Image
= Parse_Image(IMAGE_FILE
);
376 Image
->Use_Colour_Flag
= TRUE
;
380 Image
->Once_Flag
=TRUE
;
383 CASE (MAP_TYPE_TOKEN
)
384 Image
->Map_Type
= (int) Parse_Float ();
387 CASE (INTERPOLATE_TOKEN
)
388 Image
->Interpolation_Type
= (int)Parse_Float();
391 CASE (BUMP_SIZE_TOKEN
)
392 Tnormal
->Amount
= Parse_Float ();
395 CASE (USE_COLOUR_TOKEN
)
396 Image
->Use_Colour_Flag
= TRUE
;
399 CASE (USE_INDEX_TOKEN
)
400 Image
->Use_Colour_Flag
= FALSE
;
409 Tnormal
->Vals
.Image
=Image
;
416 /*****************************************************************************
434 ******************************************************************************/
436 void Parse_Pigment (PIGMENT
**Pigment_Ptr
)
438 EXPECT
/* Look for [pigment_id] */
439 CASE (PIGMENT_ID_TOKEN
)
440 Destroy_Pigment(*Pigment_Ptr
);
441 *Pigment_Ptr
= Copy_Pigment ((PIGMENT
*) Token
.Data
);
449 END_EXPECT
/* End pigment_id */
451 Parse_Pattern((TPATTERN
*)(*Pigment_Ptr
),PIGMENT_TYPE
);
453 if (Not_In_Default
&& ((*Pigment_Ptr
)->Type
== NO_PATTERN
))
455 Warn(1.7, "Pigment type unspecified or not 1st item.");
461 /*****************************************************************************
479 ******************************************************************************/
481 static void Parse_Pattern (TPATTERN
*New
, int TPat_Type
)
486 TRANSFORM Local_Trans
;
488 unsigned short Old_Type
=New
->Type
;
489 IMAGE
*Old_Image
= NULL
;
490 DENSITY_FILE
*Old_Density_File
= NULL
;
492 if (Old_Type
==BITMAP_PATTERN
)
494 Old_Image
=New
->Vals
.Image
;
497 if (Old_Type
==DENSITY_FILE_PATTERN
)
499 Old_Density_File
=New
->Vals
.Density_File
;
504 New
->Type
= AGATE_PATTERN
;
505 Check_Turb(&(New
->Warps
));
506 New
->Vals
.Agate_Turb_Scale
= 1.0;
511 New
->Type
= BOZO_PATTERN
;
516 New
->Type
= GRANITE_PATTERN
;
521 New
->Type
= LEOPARD_PATTERN
;
526 New
->Type
= MARBLE_PATTERN
;
527 New
->Wave_Type
= TRIANGLE_WAVE
;
532 New
->Type
= MANDEL_PATTERN
;
533 New
->Vals
.Iterations
= (int)Parse_Float();
538 New
->Type
= ONION_PATTERN
;
543 New
->Type
= SPIRAL1_PATTERN
;
544 New
->Vals
.Arms
= (short)Parse_Float ();
545 New
->Wave_Type
= TRIANGLE_WAVE
;
550 New
->Type
= SPIRAL2_PATTERN
;
551 New
->Vals
.Arms
= (short)Parse_Float ();
552 New
->Wave_Type
= TRIANGLE_WAVE
;
557 New
->Type
= SPOTTED_PATTERN
;
562 New
->Type
= WOOD_PATTERN
;
563 New
->Wave_Type
= TRIANGLE_WAVE
;
567 CASE (GRADIENT_TOKEN
)
568 New
->Type
= GRADIENT_PATTERN
;
569 Parse_Vector (New
->Vals
.Gradient
);
574 New
->Type
= RADIAL_PATTERN
;
579 New
->Type
= CRACKLE_PATTERN
;
584 if ((TPat_Type
!= PIGMENT_TYPE
) && (TPat_Type
!= DENSITY_TYPE
))
586 Only_In("color","pigment or density");
588 New
->Type
= PLAIN_PATTERN
;
589 Parse_Colour (((PIGMENT
*)New
)->Colour
);
594 New
->Type
= CHECKER_PATTERN
;
595 New
->Frequency
= 0.0;
596 Destroy_Blend_Map(New
->Blend_Map
);
597 New
->Blend_Map
= Parse_Blend_List(2,&Check_Default_Map
,TPat_Type
);
602 if (New
->Type
!=BRICK_PATTERN
)
604 Make_Vector(New
->Vals
.Brick
.Size
,8.0,3.0,4.5);
605 New
->Vals
.Brick
.Mortar
=0.5-Small_Tolerance
*2.0;
606 New
->Type
= BRICK_PATTERN
;
608 New
->Frequency
= 0.0;
609 Destroy_Blend_Map(New
->Blend_Map
);
610 New
->Blend_Map
= Parse_Blend_List(2,&Brick_Default_Map
,TPat_Type
);
615 New
->Type
= HEXAGON_PATTERN
;
616 New
->Frequency
= 0.0;
617 Destroy_Blend_Map(New
->Blend_Map
);
618 New
->Blend_Map
= Parse_Blend_List(3,&Hex_Default_Map
,TPat_Type
);
622 CASE (IMAGE_MAP_TOKEN
)
623 if (TPat_Type
!= PIGMENT_TYPE
)
625 Only_In("image_map","pigment");
628 if (Old_Type
==BITMAP_PATTERN
)
630 Destroy_Image(Old_Image
);
633 New
->Type
= BITMAP_PATTERN
;
634 New
->Frequency
= 0.0;
635 Parse_Image_Map ((PIGMENT
*)New
);
639 CASE (BUMP_MAP_TOKEN
)
640 if (TPat_Type
!= NORMAL_TYPE
)
642 Only_In("bump_map","normal");
645 if (Old_Type
==BITMAP_PATTERN
)
647 Destroy_Image(Old_Image
);
650 New
->Type
= BITMAP_PATTERN
;
651 New
->Frequency
= 0.0;
652 Parse_Bump_Map ((TNORMAL
*)New
);
657 New
->Type
= WAVES_PATTERN
;
662 New
->Type
= RIPPLES_PATTERN
;
666 CASE (WRINKLES_TOKEN
)
667 New
->Type
= WRINKLES_PATTERN
;
672 New
->Type
= BUMPS_PATTERN
;
677 New
->Type
= DENTS_PATTERN
;
682 New
->Type
= QUILTED_PATTERN
;
683 New
->Vals
.Quilted
.Control0
= 1.0;
684 New
->Vals
.Quilted
.Control1
= 1.0;
685 New
->Frequency
= 0.0;
690 New
->Type
= AVERAGE_PATTERN
;
695 New
->Type
= PLANAR_PATTERN
;
700 New
->Type
= BOXED_PATTERN
;
704 CASE (SPHERICAL_TOKEN
)
705 New
->Type
= SPHERICAL_PATTERN
;
709 CASE (CYLINDRICAL_TOKEN
)
710 New
->Type
= CYLINDRICAL_PATTERN
;
714 CASE (DENSITY_FILE_TOKEN
)
715 if (Old_Type
==DENSITY_FILE_PATTERN
)
717 Destroy_Density_File(Old_Density_File
);
719 New
->Type
= DENSITY_FILE_PATTERN
;
720 New
->Vals
.Density_File
= Create_Density_File();
722 New
->Vals
.Density_File
->Data
->Name
= Parse_String();
723 Read_Density_File(New
->Vals
.Density_File
);
731 END_EXPECT
/* Concludes pattern_body */
733 if ((Old_Type
==BITMAP_PATTERN
) && (New
->Type
!=BITMAP_PATTERN
))
735 Destroy_Image(Old_Image
);
738 if ((Old_Type
==DENSITY_FILE_PATTERN
) && (New
->Type
!=DENSITY_FILE_PATTERN
))
740 Destroy_Density_File(Old_Density_File
);
743 if (TPat_Type
== NORMAL_TYPE
)
746 ((TNORMAL
*)New
)->Amount
= Allow_Float (((TNORMAL
*)New
)->Amount
);
749 EXPECT
/* Look for pattern_modifier */
750 CASE (TURBULENCE_TOKEN
)
751 Local_Turb
=Check_Turb(&(New
->Warps
));
752 Parse_Vector(Local_Turb
->Turbulence
);
755 CASE (COLOUR_MAP_TOKEN
)
756 if ((TPat_Type
!= PIGMENT_TYPE
) && (TPat_Type
!= DENSITY_TYPE
))
758 Only_In("color_map","pigment");
760 if (New
->Type
== CHECKER_PATTERN
||
761 New
->Type
== BRICK_PATTERN
||
762 New
->Type
== HEXAGON_PATTERN
||
763 New
->Type
== PLAIN_PATTERN
||
764 New
->Type
== AVERAGE_PATTERN
||
765 New
->Type
== BITMAP_PATTERN
)
767 Error("Cannot use color_map with this pattern type.");
769 Destroy_Blend_Map(New
->Blend_Map
);
770 New
->Blend_Map
= Parse_Colour_Map ();
773 CASE (PIGMENT_MAP_TOKEN
)
774 if (TPat_Type
!= PIGMENT_TYPE
)
776 Only_In("pigment_map","pigment");
778 if (New
->Type
== CHECKER_PATTERN
||
779 New
->Type
== BRICK_PATTERN
||
780 New
->Type
== HEXAGON_PATTERN
||
781 New
->Type
== PLAIN_PATTERN
||
782 New
->Type
== BITMAP_PATTERN
)
783 Not_With ("pigment_map","this pigment type");
784 Destroy_Blend_Map(New
->Blend_Map
);
785 New
->Blend_Map
= Parse_Blend_Map (PIGMENT_TYPE
,New
->Type
);
788 CASE (DENSITY_MAP_TOKEN
)
789 if (TPat_Type
!= DENSITY_TYPE
)
791 Only_In("density_map","density");
793 if (New
->Type
== CHECKER_PATTERN
||
794 New
->Type
== BRICK_PATTERN
||
795 New
->Type
== HEXAGON_PATTERN
||
796 New
->Type
== PLAIN_PATTERN
||
797 New
->Type
== BITMAP_PATTERN
)
798 Not_With ("density_map","this density type");
799 Destroy_Blend_Map(New
->Blend_Map
);
800 New
->Blend_Map
= Parse_Blend_Map (DENSITY_TYPE
,New
->Type
);
803 CASE (SLOPE_MAP_TOKEN
)
804 if (TPat_Type
!= NORMAL_TYPE
)
806 Only_In("slope_map","normal");
808 if (New
->Type
== CHECKER_PATTERN
||
809 New
->Type
== BRICK_PATTERN
||
810 New
->Type
== HEXAGON_PATTERN
||
811 New
->Type
== PLAIN_PATTERN
||
812 New
->Type
== AVERAGE_PATTERN
||
813 New
->Type
== BITMAP_PATTERN
)
814 Not_With ("slope_map","this normal type");
815 Destroy_Blend_Map(New
->Blend_Map
);
816 New
->Blend_Map
= Parse_Blend_Map (SLOPE_TYPE
,New
->Type
);
819 CASE (NORMAL_MAP_TOKEN
)
820 if (TPat_Type
!= NORMAL_TYPE
)
822 Only_In("normal_map","normal");
824 if (New
->Type
== CHECKER_PATTERN
||
825 New
->Type
== BRICK_PATTERN
||
826 New
->Type
== HEXAGON_PATTERN
||
827 New
->Type
== PLAIN_PATTERN
||
828 New
->Type
== BITMAP_PATTERN
)
829 Not_With ("normal_map","this normal type");
830 Destroy_Blend_Map(New
->Blend_Map
);
831 New
->Blend_Map
= Parse_Blend_Map (NORMAL_TYPE
,New
->Type
);
834 CASE (TEXTURE_MAP_TOKEN
)
835 if (TPat_Type
!= TEXTURE_TYPE
)
837 Only_In("texture_map","texture");
839 if (New
->Type
== CHECKER_PATTERN
||
840 New
->Type
== BRICK_PATTERN
||
841 New
->Type
== HEXAGON_PATTERN
||
842 New
->Type
== PLAIN_PATTERN
||
843 New
->Type
== BITMAP_PATTERN
)
844 Not_With ("texture_map","this pattern type");
845 Destroy_Blend_Map(New
->Blend_Map
);
846 New
->Blend_Map
= Parse_Blend_Map (TEXTURE_TYPE
,New
->Type
);
849 CASE (QUICK_COLOUR_TOKEN
)
850 if (TPat_Type
!= PIGMENT_TYPE
)
852 Only_In("quick_color","pigment");
854 Parse_Colour (Local_Colour
);
855 if (opts
.Quality_Flags
& Q_QUICKC
)
857 New
->Type
= PLAIN_PATTERN
;
858 Assign_Colour(((PIGMENT
*)New
)->Colour
,Local_Colour
);
862 CASE (CONTROL0_TOKEN
)
863 if (New
->Type
== QUILTED_PATTERN
)
865 New
->Vals
.Quilted
.Control0
= Parse_Float ();
869 Not_With ("control0","this normal");
873 CASE (CONTROL1_TOKEN
)
874 if (New
->Type
== QUILTED_PATTERN
)
876 New
->Vals
.Quilted
.Control1
= Parse_Float ();
880 Not_With ("control1","this normal");
885 Local_Turb
=Check_Turb(&(New
->Warps
));
886 Local_Turb
->Octaves
= (int)Parse_Float();
887 if(Local_Turb
->Octaves
< 1)
888 Local_Turb
->Octaves
= 1;
889 if(Local_Turb
->Octaves
> 10) /* Avoid DOMAIN errors */
890 Local_Turb
->Octaves
= 10;
894 Local_Turb
=Check_Turb(&(New
->Warps
));
895 Local_Turb
->Omega
= Parse_Float();
899 Local_Turb
=Check_Turb(&(New
->Warps
));
900 Local_Turb
->Lambda
= Parse_Float();
903 CASE (FREQUENCY_TOKEN
)
904 New
->Frequency
= Parse_Float();
907 CASE (RAMP_WAVE_TOKEN
)
908 New
->Wave_Type
= RAMP_WAVE
;
911 CASE (TRIANGLE_WAVE_TOKEN
)
912 New
->Wave_Type
= TRIANGLE_WAVE
;
915 CASE (SINE_WAVE_TOKEN
)
916 New
->Wave_Type
= SINE_WAVE
;
919 CASE (SCALLOP_WAVE_TOKEN
)
920 New
->Wave_Type
= SCALLOP_WAVE
;
923 CASE (CUBIC_WAVE_TOKEN
)
924 New
->Wave_Type
= CUBIC_WAVE
;
927 CASE (POLY_WAVE_TOKEN
)
928 New
->Wave_Type
= POLY_WAVE
;
929 New
->Exponent
= Allow_Float(New
->Exponent
);
933 New
->Phase
= Parse_Float();
936 CASE (BUMP_SIZE_TOKEN
)
937 if (TPat_Type
!= NORMAL_TYPE
)
938 Only_In ("bump_size","normal");
939 ((TNORMAL
*)New
)->Amount
= Parse_Float ();
942 CASE (AGATE_TURB_TOKEN
)
943 if (New
->Type
!= AGATE_PATTERN
)
944 Not_With ("agate_turb","non-agate");
945 New
->Vals
.Agate_Turb_Scale
= Parse_Float();
946 Check_Turb(&(New
->Warps
)); /* agate needs Octaves, Lambda etc. */
949 CASE (BRICK_SIZE_TOKEN
)
950 if (New
->Type
!= BRICK_PATTERN
)
951 Not_With ("brick_size","non-brick");
952 Parse_Vector(New
->Vals
.Brick
.Size
);
956 if (New
->Type
!= BRICK_PATTERN
)
957 Not_With ("mortar","non-brick");
958 New
->Vals
.Brick
.Mortar
= Parse_Float()-Small_Tolerance
*2.0;
961 CASE (INTERPOLATE_TOKEN
)
962 if (New
->Type
!= DENSITY_FILE_PATTERN
)
963 Not_With ("interpolate","non-density_file");
964 New
->Vals
.Density_File
->Interpolation
= (int)Parse_Float();
968 Parse_Warp(&(New
->Warps
));
971 CASE (TRANSLATE_TOKEN
)
972 Parse_Vector (Local_Vector
);
973 Translate_Tpattern (New
, Local_Vector
);
977 Parse_Vector (Local_Vector
);
978 Rotate_Tpattern (New
, Local_Vector
);
982 Parse_Scale_Vector (Local_Vector
);
983 Scale_Tpattern (New
, Local_Vector
);
987 Parse_Matrix(Local_Matrix
);
988 Compute_Matrix_Transform(&Local_Trans
, Local_Matrix
);
989 Transform_Tpattern (New
, &Local_Trans
);
992 CASE (TRANSFORM_TOKEN
)
993 GET(TRANSFORM_ID_TOKEN
)
994 Transform_Tpattern (New
, (TRANSFORM
*)Token
.Data
);
1003 if ((New
->Type
==AVERAGE_PATTERN
) && (New
->Blend_Map
==NULL
))
1005 Error("Average must have map.");
1008 if ((TPat_Type
==TEXTURE_TYPE
) && (New
->Type
!=PLAIN_PATTERN
) &&
1009 (New
->Blend_Map
==NULL
))
1011 Error("Patterned texture must have texture_map.");
1017 /*****************************************************************************
1035 ******************************************************************************/
1037 void Parse_Tnormal (TNORMAL
**Tnormal_Ptr
)
1039 EXPECT
/* Look for [tnormal_id] */
1040 CASE (TNORMAL_ID_TOKEN
)
1041 Destroy_Tnormal(*Tnormal_Ptr
);
1042 *Tnormal_Ptr
= Copy_Tnormal ((TNORMAL
*) Token
.Data
);
1050 END_EXPECT
/* End [tnormal_id] */
1052 if (*Tnormal_Ptr
== NULL
)
1054 if ((Default_Texture
->Tnormal
) != NULL
)
1055 *Tnormal_Ptr
= Copy_Tnormal ((Default_Texture
->Tnormal
));
1057 *Tnormal_Ptr
= Create_Tnormal ();
1060 Parse_Pattern((TPATTERN
*)*Tnormal_Ptr
,NORMAL_TYPE
);
1065 /*****************************************************************************
1083 ******************************************************************************/
1085 void Parse_Finish (FINISH
**Finish_Ptr
)
1089 VECTOR Local_Vector
;
1093 EXPECT
/* Look for zero or one finish_id */
1094 CASE (FINISH_ID_TOKEN
)
1095 Destroy_Finish(*Finish_Ptr
);
1096 *Finish_Ptr
= Copy_Finish ((FINISH
*) Token
.Data
);
1104 END_EXPECT
/* End finish_id */
1108 EXPECT
/* Look for zero or more finish_body */
1109 CASE (AMBIENT_TOKEN
)
1110 Parse_Colour(Temp_Colour
);
1111 New
->Ambient
[RED
] = Temp_Colour
[RED
];
1112 New
->Ambient
[GREEN
] = Temp_Colour
[GREEN
];
1113 New
->Ambient
[BLUE
] = Temp_Colour
[BLUE
];
1116 CASE (BRILLIANCE_TOKEN
)
1117 New
->Brilliance
= Parse_Float ();
1120 CASE (DIFFUSE_TOKEN
)
1121 New
->Diffuse
= Parse_Float ();
1124 CASE (REFLECTION_TOKEN
)
1125 Parse_Colour(Temp_Colour
);
1126 New
->Reflection
[RED
] = Temp_Colour
[RED
];
1127 New
->Reflection
[GREEN
] = Temp_Colour
[GREEN
];
1128 New
->Reflection
[BLUE
] = Temp_Colour
[BLUE
];
1131 CASE (REFLECTION_EXPONENT_TOKEN
)
1132 New
->Reflect_Exp
= 1.0 / Parse_Float ();
1136 New
->Phong
= Parse_Float ();
1139 CASE (PHONG_SIZE_TOKEN
)
1140 New
->Phong_Size
= Parse_Float ();
1143 CASE (SPECULAR_TOKEN
)
1144 New
->Specular
= Parse_Float ();
1147 CASE (ROUGHNESS_TOKEN
)
1148 New
->Roughness
= Parse_Float ();
1149 if (New
->Roughness
!= 0.0)
1150 New
->Roughness
= 1.0/New
->Roughness
; /* CEY 12/92 */
1152 Warn(0.0, "Zero roughness used.");
1155 CASE (METALLIC_TOKEN
)
1156 New
->Metallic
= 1.0;
1159 New
->Metallic
= Parse_Float();
1171 New
->Crand
= Parse_Float();
1174 CASE (IRID_TOKEN
) /* DMF */
1176 New
->Irid
= Parse_Float();
1179 CASE (THICKNESS_TOKEN
) /* DMF */
1180 New
->Irid_Film_Thickness
= Parse_Float();
1183 CASE (TURBULENCE_TOKEN
) /* DMF */
1184 Parse_Vector(Local_Vector
);
1185 New
->Irid_Turb
= Local_Vector
[X
];
1197 New
->Temp_IOR
= Parse_Float();
1198 Warn_Interior("Index of refraction value");
1201 CASE (CAUSTICS_TOKEN
)
1202 New
->Temp_Caustics
= Parse_Float();
1203 Warn_Interior("Caustics value");
1206 CASE (REFRACTION_TOKEN
)
1207 New
->Temp_Refract
= Parse_Float();
1208 Warn_Interior("Refraction value unnecessary to turn on refraction.\nTo attenuate, the fade_power and fade_distance keywords ");
1216 END_EXPECT
/* End of finish_body */
1218 EXPECT
/* Look for finish_mods */
1220 /* CASE none implemented
1227 END_EXPECT
/* End of finish_mods */
1234 /*****************************************************************************
1252 ******************************************************************************/
1254 TEXTURE
*Parse_Texture ()
1256 VECTOR Local_Vector
;
1257 MATRIX Local_Matrix
;
1258 TRANSFORM Local_Trans
;
1262 if (opts
.Language_Version
< 3.0)
1264 return(Parse_Vers1_Texture());
1267 Modified_Pnf
= FALSE
;
1269 EXPECT
/* First allow a texture identifier */
1270 CASE (TEXTURE_ID_TOKEN
)
1271 Texture
= Copy_Textures((TEXTURE
*) Token
.Data
);
1272 Modified_Pnf
= TRUE
;
1278 Texture
= Copy_Textures (Default_Texture
);
1283 /* If the texture identifer or the default texture was a PLAIN_PATTERN
1284 then allow its pigment, normal or finish to be overridden by
1285 pigment identifier, normal identifier and finish identifiers.
1286 This is a consession to backwards compatibility so that
1287 "texture{PIGMENT_IDENTIFIER}" etc. is legal even though it should
1288 be "texture{pigment{PIGMENT_IDENTIFIER}}"
1291 /* Look for [pnf_texture] */
1292 if (Texture
->Type
== PLAIN_PATTERN
)
1294 EXPECT
/* Look for [pnf_ids] */
1295 CASE (PIGMENT_ID_TOKEN
)
1296 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1297 Destroy_Pigment(Texture
->Pigment
);
1298 Texture
->Pigment
= Copy_Pigment ((PIGMENT
*) Token
.Data
);
1299 Modified_Pnf
= TRUE
;
1302 CASE (TNORMAL_ID_TOKEN
)
1303 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1304 Destroy_Tnormal(Texture
->Tnormal
);
1305 Texture
->Tnormal
= Copy_Tnormal ((TNORMAL
*) Token
.Data
);
1306 Modified_Pnf
= TRUE
;
1309 CASE (FINISH_ID_TOKEN
)
1310 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1311 Destroy_Finish(Texture
->Finish
);
1312 Texture
->Finish
= Copy_Finish ((FINISH
*) Token
.Data
);
1313 Modified_Pnf
= TRUE
;
1322 /* If the texture identifer or the default texture was a PLAIN_PATTERN
1323 then allow its pigment, normal or finish to be overridden by
1324 pigment, normal or finish statement. Also allow transformations.
1327 EXPECT
/* Modify previous pnf */
1328 CASE (PIGMENT_TOKEN
)
1330 Parse_Pigment ( &(Texture
->Pigment
) );
1332 Modified_Pnf
= TRUE
;
1335 CASE (TNORMAL_TOKEN
)
1337 Parse_Tnormal ( &(Texture
->Tnormal
) );
1339 Modified_Pnf
= TRUE
;
1343 Parse_Finish ( &(Texture
->Finish
) );
1344 Modified_Pnf
= TRUE
;
1347 CASE (TRANSLATE_TOKEN
)
1348 Parse_Vector (Local_Vector
);
1349 Compute_Translation_Transform(&Local_Trans
, Local_Vector
);
1350 Transform_Textures (Texture
, &Local_Trans
);
1351 Modified_Pnf
= TRUE
;
1355 Parse_Vector (Local_Vector
);
1356 Compute_Rotation_Transform(&Local_Trans
, Local_Vector
);
1357 Transform_Textures (Texture
, &Local_Trans
);
1358 Modified_Pnf
= TRUE
;
1362 Parse_Scale_Vector (Local_Vector
);
1363 Compute_Scaling_Transform(&Local_Trans
, Local_Vector
);
1364 Transform_Textures (Texture
, &Local_Trans
);
1365 Modified_Pnf
= TRUE
;
1369 Parse_Matrix(Local_Matrix
);
1370 Compute_Matrix_Transform(&Local_Trans
, Local_Matrix
);
1371 Transform_Textures (Texture
, &Local_Trans
);
1372 Modified_Pnf
= TRUE
;
1375 CASE (TRANSFORM_TOKEN
)
1376 GET(TRANSFORM_ID_TOKEN
)
1377 Transform_Textures (Texture
, (TRANSFORM
*)Token
.Data
);
1378 Modified_Pnf
= TRUE
;
1389 /* Here it is not a PLAIN_PATTERN texture and since default textures
1390 must be plain then this was a texture identifier that was a special
1391 texture. Allow transforms. The "if(!Modified_Pnf)..." below
1392 will always fail if we came here. So we return after the
1394 Parse_Texture_Transform(Texture
);
1397 /* If we've modified the default texture with a p,n, or f then this
1398 has to stay a PLAIN_PATTERN pnf texture. We won't allow
1399 a texture_map or pattern. Therefore quit now.
1404 /* At this point we've either got a texture statement that had
1405 no p, n or f. Nor any texture identifier. Its probably
1406 a patterned texture_map texture. It could be an empty
1407 statement such as "texture{}" */
1411 Destroy_Textures (Texture
);
1412 Texture
= Parse_Tiles();
1413 Parse_Texture_Transform(Texture
);
1417 CASE (MATERIAL_MAP_TOKEN
)
1418 Destroy_Textures (Texture
);
1419 Texture
= Parse_Material_Map ();
1420 Parse_Texture_Transform(Texture
);
1426 Destroy_Pigment(Texture
->Pigment
);
1427 Destroy_Tnormal(Texture
->Tnormal
);
1428 Destroy_Finish(Texture
->Finish
);
1429 Texture
->Pigment
= NULL
;
1430 Texture
->Tnormal
= NULL
;
1431 Texture
->Finish
= NULL
;
1432 Parse_Pattern((TPATTERN
*)Texture
,TEXTURE_TYPE
);
1433 /* if following is true, parsed "texture{}" so restore
1436 if (Texture
->Type
<= PLAIN_PATTERN
)
1438 Destroy_Textures(Texture
);
1439 Texture
= Copy_Textures (Default_Texture
);
1451 /*****************************************************************************
1469 ******************************************************************************/
1471 static TEXTURE
*Parse_Tiles()
1473 TEXTURE
*Texture
, *Local_Texture
;
1474 BLEND_MAP_ENTRY
*Entry
;
1478 Texture
= Create_Texture ();
1479 Destroy_Pigment(Texture
->Pigment
);
1480 Destroy_Tnormal(Texture
->Tnormal
);
1481 Destroy_Finish(Texture
->Finish
);
1482 Texture
->Pigment
= NULL
;
1483 Texture
->Tnormal
= NULL
;
1484 Texture
->Finish
= NULL
;
1485 Texture
->Type
= CHECKER_PATTERN
;
1487 Texture
->Blend_Map
= Create_Blend_Map();
1488 Texture
->Blend_Map
->Number_Of_Entries
= 2;
1489 Texture
->Blend_Map
->Blend_Map_Entries
= Entry
= Create_BMap_Entries (2);
1490 Texture
->Blend_Map
->Type
= TEXTURE_TYPE
;
1491 Entry
[0].Vals
.Texture
=NULL
;
1493 Entry
[0].Same
=FALSE
;
1494 Entry
[1].Vals
.Texture
=NULL
;
1496 Entry
[1].Same
=FALSE
;
1498 /* Note first tile is 1, 2nd tile is 0 to keep compatible with old tiles */
1501 CASE (TEXTURE_TOKEN
)
1503 Local_Texture
= Parse_Texture ();
1504 Link_Textures(&(Entry
[1].Vals
.Texture
),Local_Texture
);
1517 CASE (TEXTURE_TOKEN
)
1519 Local_Texture
= Parse_Texture ();
1520 Link_Textures(&(Entry
[0].Vals
.Texture
),Local_Texture
);
1537 /*****************************************************************************
1555 ******************************************************************************/
1557 static TEXTURE
*Parse_Material_Map()
1559 TEXTURE
*Texture
, *Local_Texture
;
1562 Texture
= Create_Texture ();
1563 Destroy_Pigment(Texture
->Pigment
);
1564 Destroy_Tnormal(Texture
->Tnormal
);
1565 Destroy_Finish(Texture
->Finish
);
1566 Texture
->Pigment
= NULL
;
1567 Texture
->Tnormal
= NULL
;
1568 Texture
->Finish
= NULL
;
1569 Texture
->Type
= BITMAP_PATTERN
;
1571 Texture
->Vals
.Image
= Parse_Image(MATERIAL_FILE
);
1572 Texture
->Vals
.Image
->Use_Colour_Flag
= FALSE
;
1576 Texture
->Vals
.Image
->Once_Flag
=TRUE
;
1579 CASE (INTERPOLATE_TOKEN
)
1580 Texture
->Vals
.Image
->Interpolation_Type
=(int)Parse_Float();
1583 CASE (MAP_TYPE_TOKEN
)
1584 Texture
->Vals
.Image
->Map_Type
= (int) Parse_Float ();
1593 GET (TEXTURE_TOKEN
) /* First material */
1595 Texture
->Materials
= Local_Texture
= Parse_Texture ();
1597 Texture
->Num_Of_Mats
++;
1599 EXPECT
/* Subsequent materials */
1600 CASE (TEXTURE_TOKEN
)
1602 Local_Texture
->Next_Material
= Parse_Texture ();
1604 Local_Texture
= Local_Texture
->Next_Material
;
1605 Texture
->Num_Of_Mats
++;
1621 /*****************************************************************************
1639 ******************************************************************************/
1641 static TEXTURE
*Parse_Vers1_Texture ()
1643 VECTOR Local_Vector
;
1644 COLOUR Local_Colour
;
1645 MATRIX Local_Matrix
;
1646 TRANSFORM Local_Trans
;
1653 EXPECT
/* Look for texture_body */
1655 Texture
= Parse_Tiles();
1659 CASE (MATERIAL_MAP_TOKEN
)
1660 Texture
= Parse_Material_Map ();
1664 CASE (TEXTURE_ID_TOKEN
)
1665 Texture
= Copy_Textures((TEXTURE
*) Token
.Data
);
1671 Texture
= Copy_Textures (Default_Texture
);
1676 /* Look for [pnf_texture] */
1677 if (Texture
->Type
== PLAIN_PATTERN
)
1679 EXPECT
/* Look for [pnf_ids] */
1680 CASE (PIGMENT_ID_TOKEN
)
1681 Destroy_Pigment(Texture
->Pigment
);
1682 Texture
->Pigment
= Copy_Pigment ((PIGMENT
*) Token
.Data
);
1685 CASE (TNORMAL_ID_TOKEN
)
1686 Destroy_Tnormal(Texture
->Tnormal
);
1687 Texture
->Tnormal
= Copy_Tnormal ((TNORMAL
*) Token
.Data
);
1690 CASE (FINISH_ID_TOKEN
)
1691 Destroy_Finish(Texture
->Finish
);
1692 Texture
->Finish
= Copy_Finish ((FINISH
*) Token
.Data
);
1701 Pigment
= Texture
->Pigment
;
1702 Tnormal
= Texture
->Tnormal
;
1703 Finish
= Texture
->Finish
;
1706 CASE (PIGMENT_TOKEN
)
1708 Parse_Pigment ( &(Texture
->Pigment
) );
1712 CASE (TNORMAL_TOKEN
)
1714 Parse_Tnormal ( &(Texture
->Tnormal
) );
1719 Parse_Finish ( &(Texture
->Finish
) );
1722 /***********************************************************************
1723 PIGMENT STUFF OUTSIDE PIGMENT{}
1724 NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
1725 ***********************************************************************/
1727 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1728 Pigment
->Type
= AGATE_PATTERN
;
1729 Pigment
->Vals
.Agate_Turb_Scale
= 1.0;
1730 Check_Turb(&(Pigment
->Warps
)); /* agate needs Octaves, Lambda etc. */
1734 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1735 Pigment
->Type
= BOZO_PATTERN
;
1738 CASE (GRANITE_TOKEN
)
1739 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1740 Pigment
->Type
= GRANITE_PATTERN
;
1743 CASE (LEOPARD_TOKEN
)
1744 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1745 Pigment
->Type
= LEOPARD_PATTERN
;
1749 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1750 Pigment
->Type
= MARBLE_PATTERN
;
1754 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1755 Pigment
->Type
= MANDEL_PATTERN
;
1756 Pigment
->Vals
.Iterations
= (int)Parse_Float();
1760 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1761 Pigment
->Type
= ONION_PATTERN
;
1764 CASE (SPOTTED_TOKEN
)
1765 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1766 Pigment
->Type
= SPOTTED_PATTERN
;
1770 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1771 Pigment
->Type
= WOOD_PATTERN
;
1774 CASE (GRADIENT_TOKEN
)
1775 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1776 Pigment
->Type
= GRADIENT_PATTERN
;
1777 Parse_Vector (Pigment
->Vals
.Gradient
);
1781 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1782 Pigment
->Type
= PLAIN_PATTERN
;
1783 Parse_Colour (Pigment
->Colour
);
1786 CASE (CHECKER_TOKEN
)
1787 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1788 Pigment
->Type
= CHECKER_PATTERN
;
1789 Pigment
->Frequency
= 0.0;
1790 Destroy_Blend_Map(Pigment
->Blend_Map
);
1791 Pigment
->Blend_Map
= Parse_Blend_List(2,&Check_Default_Map
,COLOUR_TYPE
);
1794 CASE (HEXAGON_TOKEN
)
1795 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1796 Pigment
->Type
= HEXAGON_PATTERN
;
1797 Pigment
->Frequency
= 0.0;
1798 Destroy_Blend_Map(Pigment
->Blend_Map
);
1799 Pigment
->Blend_Map
= Parse_Blend_List(3,&Hex_Default_Map
,COLOUR_TYPE
);
1802 CASE (IMAGE_MAP_TOKEN
)
1803 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1804 Pigment
->Type
= BITMAP_PATTERN
;
1805 Pigment
->Frequency
= 0.0;
1806 Parse_Image_Map (Pigment
);
1809 CASE (TURBULENCE_TOKEN
)
1810 Local_Turb
=Check_Turb(&(Pigment
->Warps
));
1811 Parse_Vector(Local_Turb
->Turbulence
);
1814 CASE (COLOUR_MAP_TOKEN
)
1815 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1816 if (Pigment
->Type
== CHECKER_PATTERN
||
1817 Pigment
->Type
== HEXAGON_PATTERN
||
1818 Pigment
->Type
== PLAIN_PATTERN
||
1819 Pigment
->Type
== BITMAP_PATTERN
)
1820 Warn(1.5, "Cannot use color map with this pigment type.");
1821 Destroy_Blend_Map(Pigment
->Blend_Map
);
1822 Pigment
->Blend_Map
= Parse_Colour_Map ();
1825 CASE (QUICK_COLOUR_TOKEN
)
1826 Warn_State(Token
.Token_Id
, PIGMENT_TOKEN
);
1827 Parse_Colour (Local_Colour
);
1828 if (opts
.Quality_Flags
& Q_QUICKC
)
1830 Assign_Colour(Pigment
->Colour
,Local_Colour
);
1834 CASE (OCTAVES_TOKEN
)
1835 Local_Turb
=Check_Turb(&(Pigment
->Warps
));
1836 Local_Turb
->Octaves
= (int)Parse_Float();
1837 if(Local_Turb
->Octaves
< 1)
1838 Local_Turb
->Octaves
= 1;
1839 if(Local_Turb
->Octaves
> 10) /* Avoid DOMAIN errors */
1840 Local_Turb
->Octaves
= 10;
1844 Local_Turb
=Check_Turb(&(Pigment
->Warps
));
1845 Local_Turb
->Omega
= Parse_Float();
1849 Local_Turb
=Check_Turb(&(Pigment
->Warps
));
1850 Local_Turb
->Lambda
= Parse_Float();
1853 /***********************************************************************
1854 TNORMAL STUFF OUTSIDE NORMAL{}
1855 NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
1856 ***********************************************************************/
1858 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1860 Tnormal
->Type
= BUMPS_PATTERN
;
1861 Tnormal
->Amount
= Parse_Float ();
1865 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1867 Tnormal
->Type
= DENTS_PATTERN
;
1868 Tnormal
->Amount
= Parse_Float ();
1871 CASE (RIPPLES_TOKEN
)
1872 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1874 Tnormal
->Type
= RIPPLES_PATTERN
;
1875 Tnormal
->Amount
= Parse_Float ();
1879 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1881 Tnormal
->Type
= WAVES_PATTERN
;
1882 Tnormal
->Amount
= Parse_Float ();
1885 CASE (WRINKLES_TOKEN
)
1886 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1888 Tnormal
->Type
= WRINKLES_PATTERN
;
1889 Tnormal
->Amount
= Parse_Float ();
1892 CASE (BUMP_MAP_TOKEN
)
1893 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1895 Tnormal
->Type
= BITMAP_PATTERN
;
1896 Tnormal
->Frequency
= 0.0;
1897 Parse_Bump_Map (Tnormal
);
1900 CASE (FREQUENCY_TOKEN
)
1901 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1903 if (!(Tnormal
->Type
== RIPPLES_PATTERN
|| Tnormal
->Type
== WAVES_PATTERN
))
1904 if (opts
.Language_Version
>= 1.5)
1905 Warn(1.5, "Cannot use frequency with this normal.");
1906 Tnormal
->Frequency
= Parse_Float();
1910 Warn_State(Token
.Token_Id
, TNORMAL_TOKEN
);
1912 if (!(Tnormal
->Type
== RIPPLES_PATTERN
|| Tnormal
->Type
== WAVES_PATTERN
))
1913 if (opts
.Language_Version
>= 1.5)
1914 Warn(1.5, "Cannot use phase with this normal.");
1915 Tnormal
->Phase
= Parse_Float();
1919 /***********************************************************************
1920 FINISH STUFF OUTSIDE FINISH{}
1921 NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
1922 ***********************************************************************/
1923 CASE (AMBIENT_TOKEN
)
1924 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1925 Finish
->Ambient
[RED
] =
1926 Finish
->Ambient
[GREEN
] =
1927 Finish
->Ambient
[BLUE
] = Parse_Float ();
1930 CASE (BRILLIANCE_TOKEN
)
1931 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1932 Finish
->Brilliance
= Parse_Float ();
1935 CASE (DIFFUSE_TOKEN
)
1936 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1937 Finish
->Diffuse
= Parse_Float ();
1940 CASE (REFLECTION_TOKEN
)
1941 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1942 Finish
->Reflection
[RED
] =
1943 Finish
->Reflection
[GREEN
] =
1944 Finish
->Reflection
[BLUE
] = Parse_Float ();
1948 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1949 Finish
->Phong
= Parse_Float ();
1952 CASE (PHONG_SIZE_TOKEN
)
1953 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1954 Finish
->Phong_Size
= Parse_Float ();
1957 CASE (SPECULAR_TOKEN
)
1958 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1959 Finish
->Specular
= Parse_Float ();
1962 CASE (ROUGHNESS_TOKEN
)
1963 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1964 Finish
->Roughness
= Parse_Float ();
1965 if (Finish
->Roughness
!= 0.0)
1966 Finish
->Roughness
= 1.0/Finish
->Roughness
; /* CEY 12/92 */
1968 Warn(0.0, "Zero roughness used.");
1971 CASE (METALLIC_TOKEN
)
1972 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1973 Finish
->Metallic
= 1.0;
1977 Warn_State(Token
.Token_Id
, FINISH_TOKEN
);
1978 Finish
->Crand
= Parse_Float();
1982 Finish
->Crand
= Parse_Float();
1983 Warn(1.5, "Should use crand keyword in finish statement.");
1987 Warn_State(Token
.Token_Id
, INTERIOR_TOKEN
);
1988 Finish
->Temp_IOR
= Parse_Float();
1989 Warn_Interior("Index of refraction value");
1992 CASE (REFRACTION_TOKEN
)
1993 Warn_State(Token
.Token_Id
, INTERIOR_TOKEN
);
1994 Finish
->Temp_Refract
= Parse_Float();
1995 Warn_Interior("Refraction value unnecessary to turn on refraction.\nTo attenuate, the fade_power and fade_distance keywords ");
1998 CASE (TRANSLATE_TOKEN
)
1999 Parse_Vector (Local_Vector
);
2000 Compute_Translation_Transform(&Local_Trans
, Local_Vector
);
2001 Transform_Textures (Texture
, &Local_Trans
);
2005 Parse_Vector (Local_Vector
);
2006 Compute_Rotation_Transform(&Local_Trans
, Local_Vector
);
2007 Transform_Textures (Texture
, &Local_Trans
);
2011 Parse_Scale_Vector (Local_Vector
);
2012 Compute_Scaling_Transform(&Local_Trans
, Local_Vector
);
2013 Transform_Textures (Texture
, &Local_Trans
);
2017 Parse_Matrix(Local_Matrix
);
2018 Compute_Matrix_Transform(&Local_Trans
, Local_Matrix
);
2019 Transform_Textures (Texture
, &Local_Trans
);
2022 CASE (TRANSFORM_TOKEN
)
2023 GET(TRANSFORM_ID_TOKEN
)
2024 Transform_Textures (Texture
, (TRANSFORM
*)Token
.Data
);
2027 CASE (TEXTURE_ID_TOKEN
)
2028 Warn(0.0, "Texture identifier overwriting previous values.");
2029 Destroy_Textures(Texture
);
2030 Texture
= Copy_Textures((TEXTURE
*) Token
.Data
);
2031 Pigment
= Texture
->Pigment
;
2032 Tnormal
= Texture
->Tnormal
;
2033 Finish
= Texture
->Finish
;
2041 /***********************************************************************/
2045 if (Not_In_Default
&& (Texture
->Pigment
->Type
== NO_PATTERN
) &&
2046 !(opts
.Language_Version
< 1.5))
2047 Parse_Error(PIGMENT_ID_TOKEN
);
2051 Parse_Texture_Transform(Texture
);
2058 /*****************************************************************************
2076 ******************************************************************************/
2078 static void Parse_Texture_Transform (TEXTURE
*Texture
)
2080 VECTOR Local_Vector
;
2081 MATRIX Local_Matrix
;
2082 TRANSFORM Local_Trans
;
2085 CASE (TRANSLATE_TOKEN
)
2086 Parse_Vector (Local_Vector
);
2087 Compute_Translation_Transform(&Local_Trans
, Local_Vector
);
2088 Transform_Textures (Texture
, &Local_Trans
);
2092 Parse_Vector (Local_Vector
);
2093 Compute_Rotation_Transform(&Local_Trans
, Local_Vector
);
2094 Transform_Textures (Texture
, &Local_Trans
);
2098 Parse_Scale_Vector (Local_Vector
);
2099 Compute_Scaling_Transform(&Local_Trans
, Local_Vector
);
2100 Transform_Textures (Texture
, &Local_Trans
);
2104 Parse_Matrix(Local_Matrix
);
2105 Compute_Matrix_Transform(&Local_Trans
, Local_Matrix
);
2106 Transform_Textures (Texture
, &Local_Trans
);
2109 CASE (TRANSFORM_TOKEN
)
2110 GET(TRANSFORM_ID_TOKEN
)
2111 Transform_Textures (Texture
, (TRANSFORM
*)Token
.Data
);
2122 /*****************************************************************************
2144 * Dec 1996 : Creation.
2146 ******************************************************************************/
2148 void Parse_Media(IMEDIA
**Media_Ptr
)
2150 IMEDIA
*IMedia
, *Next_Media
;
2151 TRANSFORM Local_Trans
;
2152 VECTOR Local_Vector
;
2153 MATRIX Local_Matrix
;
2155 Next_Media
= *Media_Ptr
;
2160 CASE(MEDIA_ID_TOKEN
)
2161 IMedia
= Copy_Media((IMEDIA
*)Token
.Data
);
2167 IMedia
= Create_Media();
2173 CASE (INTERVALS_TOKEN
)
2174 if ((IMedia
->Intervals
= (int)Parse_Float()) < 1)
2176 Error("At least one interval is needed in media.\n");
2180 CASE (SAMPLES_TOKEN
)
2181 IMedia
->Min_Samples
= (int)Parse_Float();
2183 IMedia
->Max_Samples
= (int)Parse_Float();
2184 if (IMedia
->Min_Samples
< 1)
2186 Error("At least one sample per interval is needed in media.\n");
2188 if (IMedia
->Max_Samples
< IMedia
->Min_Samples
)
2190 Error("Maximum number of samples per interval smaller than minimum number.\n");
2194 CASE (ABSORPTION_TOKEN
)
2195 Parse_Colour(IMedia
->Absorption
);
2198 CASE (EMISSION_TOKEN
)
2199 Parse_Colour(IMedia
->Emission
);
2202 CASE (SCATTERING_TOKEN
)
2204 IMedia
->Type
= (int)Parse_Float();
2205 if ((IMedia
->Type
< 1) || (IMedia
->Type
> SCATTERING_TYPES
))
2207 Warn(0.0, "Unknown atmospheric scattering type.");
2210 Parse_Colour(IMedia
->Scattering
);
2213 CASE (ECCENTRICITY_TOKEN
)
2214 if (IMedia
->Type
!= HENYEY_GREENSTEIN_SCATTERING
)
2216 Error("Eccentricity cannot be used with this scattering type.");
2218 IMedia
->Eccentricity
= Parse_Float();
2221 CASE (EXTINCTION_TOKEN
)
2222 IMedia
->sc_ext
= Parse_Float();
2234 CASE (CONFIDENCE_TOKEN
)
2235 IMedia
->Confidence
= Parse_Float();
2236 if ((IMedia
->Confidence
<= 0.0) || (IMedia
->Confidence
>= 1.0))
2238 Error("Illegal confidence value in media.\n");
2242 CASE (VARIANCE_TOKEN
)
2243 IMedia
->Variance
= Parse_Float();
2247 IMedia
->Ratio
= Parse_Float();
2250 CASE (DENSITY_TOKEN
)
2252 Parse_Media_Density_Pattern(&(IMedia
->Density
));
2256 CASE (TRANSLATE_TOKEN
)
2257 Parse_Vector (Local_Vector
);
2258 Compute_Translation_Transform(&Local_Trans
, Local_Vector
);
2259 Transform_Density (IMedia
->Density
, &Local_Trans
);
2263 Parse_Vector (Local_Vector
);
2264 Compute_Rotation_Transform(&Local_Trans
, Local_Vector
);
2265 Transform_Density (IMedia
->Density
, &Local_Trans
);
2269 Parse_Scale_Vector (Local_Vector
);
2270 Compute_Scaling_Transform(&Local_Trans
, Local_Vector
);
2271 Transform_Density (IMedia
->Density
, &Local_Trans
);
2275 Parse_Matrix(Local_Matrix
);
2276 Compute_Matrix_Transform(&Local_Trans
, Local_Matrix
);
2277 Transform_Density (IMedia
->Density
, &Local_Trans
);
2280 CASE (TRANSFORM_TOKEN
)
2281 GET(TRANSFORM_ID_TOKEN
)
2282 Transform_Density (IMedia
->Density
, &Local_Trans
);
2293 IMedia
->Next_Media
= Next_Media
;
2295 *Media_Ptr
= IMedia
;
2300 /*****************************************************************************
2322 * Jan 1997 : Creation.
2324 ******************************************************************************/
2326 void Parse_Interior(INTERIOR
**Interior_Ptr
)
2333 CASE(INTERIOR_ID_TOKEN
)
2334 Destroy_Interior(*Interior_Ptr
);
2335 *Interior_Ptr
= Copy_Interior((INTERIOR
*)Token
.Data
);
2345 if(*Interior_Ptr
== NULL
)
2347 *Interior_Ptr
= Create_Interior();
2350 Interior
= *Interior_Ptr
;
2354 Interior
->IOR
= Parse_Float();
2357 CASE (CAUSTICS_TOKEN
)
2358 Interior
->Caustics
= Parse_Float() * 45.0;
2361 CASE (FADE_DISTANCE_TOKEN
)
2362 Interior
->Fade_Distance
= Parse_Float();
2365 CASE (FADE_POWER_TOKEN
)
2366 Interior
->Fade_Power
= Parse_Float();
2370 Parse_Media((IMEDIA
**)(&Interior
->IMedia
));
2373 CASE (REFRACTION_TOKEN
)
2374 Interior
->Old_Refract
= Parse_Float();
2375 Warn_Interior("Refraction value unnecessary to turn on refraction.\nTo attenuate, the fade_power and fade_distance keywords ");
2386 Init_Interior(Interior
);
2391 /*****************************************************************************
2395 * Parse_Media_Density_Pattern
2413 * Dez 1996 : Creation.
2415 ******************************************************************************/
2417 void Parse_Media_Density_Pattern(PIGMENT
**Density_Ptr
)
2422 CASE (DENSITY_ID_TOKEN
)
2423 New
= Copy_Pigment ((PIGMENT
*) Token
.Data
);
2428 New
= Create_Pigment();
2434 Parse_Pattern((TPATTERN
*)New
,DENSITY_TYPE
);
2436 New
->Next
= (TPATTERN
*)(*Density_Ptr
);
2446 /*****************************************************************************
2464 ******************************************************************************/
2477 Fog
= Copy_Fog ((FOG
*) Token
.Data
);
2490 Parse_Colour(Fog
->Colour
);
2493 CASE (DISTANCE_TOKEN
)
2494 Fog
->Distance
= Parse_Float();
2498 Warn(1.5, "Should use distance keyword.");
2499 Fog
->Distance
= Parse_Float();
2502 CASE (FOG_TYPE_TOKEN
)
2503 Fog
->Type
= (int)Parse_Float();
2504 if ((Fog
->Type
< ORIG_FOG
) || (Fog
->Type
> FOG_TYPES
))
2506 Warn(0.0, "Unknown fog type.");
2510 CASE (FOG_ALT_TOKEN
)
2511 Fog
->Alt
= Parse_Float();
2514 CASE (FOG_OFFSET_TOKEN
)
2515 Fog
->Offset
= Parse_Float();
2518 CASE (TURB_DEPTH_TOKEN
)
2519 Fog
->Turb_Depth
= Parse_Float();
2523 Parse_Vector(Fog
->Up
);
2526 CASE (TURBULENCE_TOKEN
)
2527 if (Fog
->Turb
== NULL
)
2529 Fog
->Turb
=(TURB
*)Create_Warp(CLASSIC_TURB_WARP
);
2531 Parse_Vector(Fog
->Turb
->Turbulence
);
2534 CASE (OCTAVES_TOKEN
)
2535 if (Fog
->Turb
== NULL
)
2537 Fog
->Turb
=(TURB
*)Create_Warp(CLASSIC_TURB_WARP
);
2539 Fog
->Turb
->Octaves
= (int)Parse_Float();
2540 if(Fog
->Turb
->Octaves
< 1)
2541 Fog
->Turb
->Octaves
= 1;
2542 if(Fog
->Turb
->Octaves
> 10)
2543 Fog
->Turb
->Octaves
= 10;
2547 if (Fog
->Turb
== NULL
)
2549 Fog
->Turb
=(TURB
*)Create_Warp(CLASSIC_TURB_WARP
);
2551 Fog
->Turb
->Omega
= Parse_Float();
2555 if (Fog
->Turb
== NULL
)
2557 Fog
->Turb
=(TURB
*)Create_Warp(CLASSIC_TURB_WARP
);
2559 Fog
->Turb
->Lambda
= Parse_Float();
2563 Parse_Vector(Vector
);
2564 Compute_Rotation_Transform(&Trans
, Vector
);
2565 MTransDirection(Fog
->Up
, Fog
->Up
, &Trans
);
2569 Parse_Vector(Vector
);
2570 Compute_Scaling_Transform(&Trans
, Vector
);
2571 MTransDirection(Fog
->Up
, Fog
->Up
, &Trans
);
2574 CASE (TRANSLATE_TOKEN
)
2575 Parse_Vector(Vector
);
2576 Warn(0.0, "A fog's up vector can't be translated.");
2578 Compute_Translation_Transform(&Trans, Vector);
2579 MTransDirection(Fog->Up, Fog->Up, &Trans);
2584 Parse_Matrix(Matrix
);
2585 Compute_Matrix_Transform(&Trans
, Matrix
);
2586 MTransDirection(Fog
->Up
, Fog
->Up
, &Trans
);
2589 CASE (TRANSFORM_TOKEN
)
2590 GET(TRANSFORM_ID_TOKEN
)
2591 MTransDirection(Fog
->Up
, Fog
->Up
, (TRANSFORM
*)Token
.Data
);
2602 /* Make sure the up vector is normalized. */
2604 VNormalize(Fog
->Up
, Fog
->Up
);
2611 /*****************************************************************************
2633 * Jul 1994 : Creation.
2635 * Dec 1994 : Modified to work with multiple rainbows. [DB]
2637 * Apr 1995 : Added code for rainbow arcs. [DB]
2639 ******************************************************************************/
2641 RAINBOW
*Parse_Rainbow()
2647 Angle1
= Angle2
= FALSE
;
2652 CASE(RAINBOW_ID_TOKEN
)
2653 Rainbow
= Copy_Rainbow ((RAINBOW
*) Token
.Data
);
2659 Rainbow
= Create_Rainbow();
2666 Rainbow
->Angle
= Parse_Float();
2669 CASE (DIRECTION_TOKEN
)
2670 Parse_Vector(Rainbow
->Antisolar_Vector
);
2673 CASE (COLOUR_MAP_TOKEN
)
2674 Rainbow
->Pigment
= Create_Pigment();
2675 Rainbow
->Pigment
->Blend_Map
= Parse_Colour_Map();
2676 Rainbow
->Pigment
->Type
= GRADIENT_PATTERN
;
2677 Make_Vector (Rainbow
->Pigment
->Vals
.Gradient
,1.0,0.0,0.0);
2680 CASE (DISTANCE_TOKEN
)
2681 Rainbow
->Distance
= Parse_Float();
2685 Rainbow
->Jitter
= Parse_Float();
2689 Rainbow
->Width
= Parse_Float();
2693 Parse_Vector(Rainbow
->Up_Vector
);
2696 CASE (FALLOFF_ANGLE_TOKEN
)
2698 Rainbow
->Falloff_Angle
= Parse_Float();
2699 if ((Rainbow
->Falloff_Angle
< 0.0) || (Rainbow
->Falloff_Angle
> 360.0))
2701 Error("Illegal falloff angle in rainbow (Use value from 0 to 360 degrees).\n");
2703 Rainbow
->Falloff_Angle
*= M_PI_360
;
2706 CASE (ARC_ANGLE_TOKEN
)
2708 Rainbow
->Arc_Angle
= Parse_Float();
2709 if ((Rainbow
->Arc_Angle
< 0.0) || (Rainbow
->Arc_Angle
> 360.0))
2711 Error("Illegal arc angle in rainbow (Use value from 0 to 360 degrees).\n");
2713 Rainbow
->Arc_Angle
*= M_PI_360
;
2724 /* Setup falloff angle. */
2726 if (Angle2
&& !Angle1
)
2728 Rainbow
->Falloff_Angle
= Rainbow
->Arc_Angle
;
2731 /* Test if arc angle is greater or equal to falloff angle. */
2733 if (Rainbow
->Arc_Angle
< Rainbow
->Falloff_Angle
)
2735 Error("Arc angle is smaller than falloff angle in rainbow.\n");
2738 /* Get falloff region width.*/
2740 Rainbow
->Falloff_Width
= Rainbow
->Arc_Angle
- Rainbow
->Falloff_Angle
;
2742 /* Check for illegal vectors. */
2744 VDot(dot
, Rainbow
->Antisolar_Vector
, Rainbow
->Antisolar_Vector
);
2746 if (fabs(dot
) < EPSILON
)
2748 Error("Rainbow's direction vector is zero.\n");
2751 VDot(dot
, Rainbow
->Up_Vector
, Rainbow
->Up_Vector
);
2753 if (fabs(dot
) < EPSILON
)
2755 Error("Rainbow's up vector is zero.\n");
2758 VNormalizeEq(Rainbow
->Antisolar_Vector
);
2759 VNormalizeEq(Rainbow
->Up_Vector
);
2761 VDot(dot
, Rainbow
->Up_Vector
, Rainbow
->Antisolar_Vector
);
2763 if (fabs(1.0 - fabs(dot
)) < EPSILON
)
2765 Error("Rainbow's up and direction vector are co-linear.\n");
2768 /* Make sure that up and antisolar vector are perpendicular. */
2770 VCross(Rainbow
->Right_Vector
, Rainbow
->Up_Vector
, Rainbow
->Antisolar_Vector
);
2772 VCross(Rainbow
->Up_Vector
, Rainbow
->Antisolar_Vector
, Rainbow
->Right_Vector
);
2774 VNormalizeEq(Rainbow
->Up_Vector
);
2775 VNormalizeEq(Rainbow
->Right_Vector
);
2777 /* Adjust rainbow angle and width. */
2779 Rainbow
->Angle
-= 0.5 * Rainbow
->Width
;
2781 Rainbow
->Angle
*= M_PI_180
;
2782 Rainbow
->Width
*= M_PI_180
;
2789 /*****************************************************************************
2811 * Jul 1994 : Creation.
2813 * Dec 1994 : Modified to work with multiple skyspheres. [DB]
2815 ******************************************************************************/
2817 SKYSPHERE
*Parse_Skysphere()
2819 VECTOR Local_Vector
;
2820 MATRIX Local_Matrix
;
2821 TRANSFORM Local_Trans
;
2822 SKYSPHERE
*Skysphere
;
2827 CASE(SKYSPHERE_ID_TOKEN
)
2828 Skysphere
= Copy_Skysphere((SKYSPHERE
*)Token
.Data
);
2834 Skysphere
= Create_Skysphere();
2840 CASE (PIGMENT_TOKEN
)
2842 Skysphere
->Pigments
= (PIGMENT
**)POV_REALLOC(Skysphere
->Pigments
, Skysphere
->Count
*sizeof(SKYSPHERE
*), "sky-sphere pigment");
2843 Skysphere
->Pigments
[Skysphere
->Count
-1] = Create_Pigment();
2845 Parse_Pigment(&(Skysphere
->Pigments
[Skysphere
->Count
-1]));
2849 CASE (TRANSLATE_TOKEN
)
2850 Parse_Vector (Local_Vector
);
2851 Translate_Skysphere(Skysphere
, Local_Vector
);
2855 Parse_Vector (Local_Vector
);
2856 Rotate_Skysphere(Skysphere
, Local_Vector
);
2860 Parse_Scale_Vector (Local_Vector
);
2861 Scale_Skysphere(Skysphere
, Local_Vector
);
2865 Parse_Matrix(Local_Matrix
);
2866 Compute_Matrix_Transform(&Local_Trans
, Local_Matrix
);
2867 Transform_Skysphere(Skysphere
, &Local_Trans
);
2870 CASE (TRANSFORM_TOKEN
)
2871 GET(TRANSFORM_ID_TOKEN
)
2872 Transform_Skysphere(Skysphere
, (TRANSFORM
*)Token
.Data
);
2883 if (Skysphere
->Count
==0)
2885 Error("Empty sky_sphere statement.");
2891 /*****************************************************************************
2893 * FUNCTION : Check_BH_Parameters
2895 * ARGUMENTS : bh - pointer to Black_Hole
2897 * AUTHOR : CJC [7/95]
2899 * DESCRIPTION : Applies sanity checks to the parameters of a black hole.
2903 ******************************************************************************/
2905 static void Check_BH_Parameters (BLACK_HOLE
*bh
)
2907 if (bh
->Repeat
== FALSE
) return ;
2909 if (bh
->Repeat_Vector
[X
] > 0.0)
2911 if (bh
->Center
[X
] < bh
->Radius
)
2912 bh
->Center
[X
] = bh
->Radius
;
2913 if (bh
->Repeat_Vector
[X
] < bh
->Center
[X
] + bh
->Radius
+ bh
->Uncertainty_Vector
[X
])
2915 bh
->Repeat_Vector
[X
] = bh
->Center
[X
] + bh
->Radius
+ bh
->Uncertainty_Vector
[X
] ;
2916 Warning (0.0, "Black Hole repeat vector X too small ; increased to %g\n", bh
->Repeat_Vector
[X
]) ;
2918 if (bh
->Repeat_Vector
[X
] < Small_Tolerance
)
2920 Warning (0.0,"Black Hole repeat vector X is less than %f ; ignored\n", (float) Small_Tolerance
) ;
2921 bh
->Repeat_Vector
[X
] = 0.0 ;
2925 if (bh
->Repeat_Vector
[Y
] > 0.0)
2927 if (bh
->Center
[Y
] < bh
->Radius
)
2928 bh
->Center
[Y
] = bh
->Radius
;
2929 if (bh
->Repeat_Vector
[Y
] < bh
->Center
[Y
] + bh
->Radius
+ bh
->Uncertainty_Vector
[Y
])
2931 bh
->Repeat_Vector
[Y
] = bh
->Center
[Y
] + bh
->Radius
+ bh
->Uncertainty_Vector
[Y
] ;
2932 Warning (0.0, "Black Hole repeat vector Y too small ; increased to %g\n", bh
->Repeat_Vector
[Y
]) ;
2934 if (bh
->Repeat_Vector
[Y
] < Small_Tolerance
)
2936 Warning (0.0, "Black Hole repeat vector Y is less than %f ; ignored\n", (float) Small_Tolerance
) ;
2937 bh
->Repeat_Vector
[Y
] = 0.0 ;
2941 if (bh
->Repeat_Vector
[Z
] > 0.0)
2943 if (bh
->Center
[Z
] < bh
->Radius
)
2944 bh
->Center
[Z
] = bh
->Radius
;
2945 if (bh
->Repeat_Vector
[Z
] < bh
->Center
[Z
] + bh
->Radius
+ bh
->Uncertainty_Vector
[Z
])
2947 bh
->Repeat_Vector
[Z
] = bh
->Center
[Z
] + bh
->Radius
+ bh
->Uncertainty_Vector
[Z
] ;
2948 Warning (0.0, "Black Hole repeat vector Z too small ; increased to %g\n", bh
->Repeat_Vector
[Z
]) ;
2950 if (bh
->Repeat_Vector
[Z
] < Small_Tolerance
)
2952 Warning (0.0, "Black Hole repeat vector Z is less than %f ; ignored\n", (float) Small_Tolerance
) ;
2953 bh
->Repeat_Vector
[Z
] = 0.0 ;
2958 /*****************************************************************************
2966 * Warps_Ptr : Address where the root warp of a warp list
2971 * Warps_Ptr : If *Warps_Ptr is NULL, a classic turb warp
2972 * is created and a pointer to it is stored
2976 * A pointer to the last warp in the chain which is guarenteed
2977 * to be a classic turb.
2983 * DESCRIPTION : This routine is called when a classic outside-the-warp
2984 * turbulence parameter is parsed. One and only one classic turb may exist
2985 * in a warp chain. If there is one, it must be the last. This routine
2986 * traverses the warp chain and looks at the last link. If it is not a
2987 * classic turb then it adds one to the end and returns a pointer to it.
2988 * If the chain is empty, it creates a single link chain consisting of a
2989 * classic turb link. Future warp links get added ahead of the chain so
2990 * that any classic turb link is always last.
2994 ******************************************************************************/
2996 static TURB
*Check_Turb (WARP
**Warps_Ptr
)
2998 WARP
*Temp
=*Warps_Ptr
;
3002 *Warps_Ptr
= Temp
= Create_Warp(CLASSIC_TURB_WARP
);
3006 while (Temp
->Next_Warp
!= NULL
)
3008 Temp
=Temp
->Next_Warp
;
3011 if (Temp
->Warp_Type
!= CLASSIC_TURB_WARP
)
3013 Temp
->Next_Warp
=Create_Warp(CLASSIC_TURB_WARP
);
3014 Temp
=Temp
->Next_Warp
;
3017 return((TURB
*)Temp
);
3022 /*****************************************************************************
3040 ******************************************************************************/
3042 static void Parse_Warp (WARP
**Warp_Ptr
)
3047 BLACK_HOLE
*Black_Hole
;
3048 VECTOR Local_Vector
;
3053 CASE(TURBULENCE_TOKEN
)
3054 New
=Create_Warp(EXTRA_TURB_WARP
);
3056 Parse_Vector(Turb
->Turbulence
);
3059 Turb
->Octaves
= (int)Parse_Float();
3060 if(Turb
->Octaves
< 1)
3062 if(Turb
->Octaves
> 10) /* Avoid DOMAIN errors */
3067 Turb
->Omega
= Parse_Float();
3071 Turb
->Lambda
= Parse_Float();
3083 New
=Create_Warp(REPEAT_WARP
);
3084 Repeat
=(REPEAT
*)New
;
3085 Parse_Vector(Local_Vector
);
3087 if (Local_Vector
[X
]!=0.0)
3089 if (Local_Vector
[Y
]!=0.0)
3091 if (Repeat
->Axis
< X
)
3094 Error("Can only repeat along 1 axis.");
3096 if (Local_Vector
[Z
]!=0.0)
3098 if (Repeat
->Axis
< X
)
3101 Error("Can only repeat along 1 axis.");
3103 if (Repeat
->Axis
< X
)
3104 Error("No axis specified in repeat.");
3105 Repeat
->Width
=Local_Vector
[Repeat
->Axis
];
3109 Parse_Vector(Repeat
->Offset
);
3113 Parse_Vector(Repeat
->Flip
);
3114 if (Repeat
->Flip
[X
]!=0.0) Repeat
->Flip
[X
]=-1.0; else Repeat
->Flip
[X
]=1.0;
3115 if (Repeat
->Flip
[Y
]!=0.0) Repeat
->Flip
[Y
]=-1.0; else Repeat
->Flip
[Y
]=1.0;
3116 if (Repeat
->Flip
[Z
]!=0.0) Repeat
->Flip
[Z
]=-1.0; else Repeat
->Flip
[Z
]=1.0;
3127 CASE(BLACK_HOLE_TOKEN
)
3128 New
= Create_Warp(BLACK_HOLE_WARP
) ;
3129 Black_Hole
= (BLACK_HOLE
*) New
;
3130 Parse_Vector (Local_Vector
) ;
3131 Assign_Vector (Black_Hole
->Center
, Local_Vector
) ;
3133 Black_Hole
->Radius
= Parse_Float () ;
3134 Black_Hole
->Radius_Squared
= Black_Hole
->Radius
* Black_Hole
->Radius
;
3135 Black_Hole
->Inverse_Radius
= 1.0 / Black_Hole
->Radius
;
3136 Black_Hole
->Strength
= 1.0 ;
3137 Black_Hole
->Power
= 2.0 ;
3138 Black_Hole
->Inverted
= FALSE
;
3139 Black_Hole
->Type
= 0 ;
3142 CASE(STRENGTH_TOKEN
)
3143 Black_Hole
->Strength
= Parse_Float () ;
3147 Black_Hole
->Power
= Parse_Float () ;
3151 Black_Hole
->Inverted
= TRUE
;
3155 Black_Hole
->Type
= (int) Parse_Float () ;
3159 Parse_Vector (Black_Hole
->Repeat_Vector
) ;
3160 Black_Hole
->Repeat
= TRUE
;
3161 Check_BH_Parameters (Black_Hole
) ;
3164 CASE(TURBULENCE_TOKEN
)
3165 Parse_Vector (Black_Hole
->Uncertainty_Vector
) ;
3166 Black_Hole
->Uncertain
= TRUE
;
3167 Check_BH_Parameters (Black_Hole
) ;
3179 Parse_Error_Str ("warp type");
3185 Error("Empty warp statement.");
3188 New
->Next_Warp
=*Warp_Ptr
;
3195 static void Warn_Interior(char *s
)
3198 Warning(0.0,"should be specified in 'interior{...}' statement.\n");
3202 void Parse_Material(MATERIAL
*Material
)
3206 VECTOR Local_Vector
;
3207 MATRIX Local_Matrix
;
3208 TRANSFORM Local_Trans
;
3213 CASE(MATERIAL_ID_TOKEN
)
3214 Temp
= (MATERIAL
*)Token
.Data
;
3215 Texture
= Copy_Textures(Temp
->Texture
);
3216 Link_Textures(&(Material
->Texture
),Texture
);
3217 Destroy_Interior(Material
->Interior
);
3218 Material
->Interior
= Copy_Interior(Temp
->Interior
);
3229 CASE (TEXTURE_TOKEN
)
3231 Texture
= Parse_Texture ();
3233 Link_Textures(&(Material
->Texture
),Texture
);
3236 CASE (INTERIOR_TOKEN
)
3237 Parse_Interior((INTERIOR
**)(&(Material
->Interior
)));
3240 CASE (TRANSLATE_TOKEN
)
3241 Parse_Vector (Local_Vector
);
3242 Compute_Translation_Transform(&Local_Trans
, Local_Vector
);
3243 Transform_Textures (Material
->Texture
, &Local_Trans
);
3244 Transform_Interior (Material
->Interior
,&Local_Trans
);
3248 Parse_Vector (Local_Vector
);
3249 Compute_Rotation_Transform(&Local_Trans
, Local_Vector
);
3250 Transform_Textures (Material
->Texture
, &Local_Trans
);
3251 Transform_Interior (Material
->Interior
,&Local_Trans
);
3255 Parse_Scale_Vector (Local_Vector
);
3256 Compute_Scaling_Transform(&Local_Trans
, Local_Vector
);
3257 Transform_Textures (Material
->Texture
, &Local_Trans
);
3258 Transform_Interior (Material
->Interior
,&Local_Trans
);
3262 Parse_Matrix(Local_Matrix
);
3263 Compute_Matrix_Transform(&Local_Trans
, Local_Matrix
);
3264 Transform_Textures (Material
->Texture
, &Local_Trans
);
3265 Transform_Interior (Material
->Interior
,&Local_Trans
);
3268 CASE (TRANSFORM_TOKEN
)
3269 GET(TRANSFORM_ID_TOKEN
)
3270 Transform_Textures (Material
->Texture
, (TRANSFORM
*)Token
.Data
);
3271 Transform_Interior (Material
->Interior
,(TRANSFORM
*)Token
.Data
);