afxZodiac.cpp

Engine/source/afx/ce/afxZodiac.cpp

More...

Public Variables

Public Functions

ConsoleDocClass(afxZodiacData , "@brief A datablock that specifies <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> decal-like Zodiac <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effect.\n\n</a>" "Zodiacs are special-purpose decal textures, often circular, that are always projected vertically onto the ground. Parameters " "<a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> dynamic rotation and scale as well as texture, color , and blending style." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Zodiacs <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> on objects of type TerrainBlock, InteriorInstance , <a href="/coding/class/classgroundplane/">GroundPlane</a> , <a href="/coding/class/classmeshroad/">MeshRoad</a> , and TSStatic. They are very " "effective as spellcasting lighting rings, explosion shockwaves, scorched earth decals, and selection indicators." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffects\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
ImplementEnumType(afxZodiac_BlendType , "Possible zodiac blend <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxZodiac\n\n</a>" )

Detailed Description

Public Variables

 EndImplementEnumType 

Public Functions

ConsoleDocClass(afxZodiacData , "@brief A datablock that specifies <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> decal-like Zodiac <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effect.\n\n</a>" "Zodiacs are special-purpose decal textures, often circular, that are always projected vertically onto the ground. Parameters " "<a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> dynamic rotation and scale as well as texture, color , and blending style." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Zodiacs <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> on objects of type TerrainBlock, InteriorInstance , <a href="/coding/class/classgroundplane/">GroundPlane</a> , <a href="/coding/class/classmeshroad/">MeshRoad</a> , and TSStatic. They are very " "effective as spellcasting lighting rings, explosion shockwaves, scorched earth decals, and selection indicators." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffects\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )

GFX_ImplementTextureProfile(AFX_GFXZodiacTextureProfile , GFXTextureProfile::DiffuseMap , GFXTextureProfile::Static</a>|<a href="/coding/class/classgfxtextureprofile/#classgfxtextureprofile_1a09105f0bf717a1f2ae49ceda21b8e82daf55b13e32bd1a1746406b68ead73ba05">GFXTextureProfile::NoMipmap</a>|<a href="/coding/class/classgfxtextureprofile/#classgfxtextureprofile_1a09105f0bf717a1f2ae49ceda21b8e82dac429cfe8dbe343378e106bc721fc96c8">GFXTextureProfile::PreserveSize , GFXTextureProfile::NONE )

IMPLEMENT_CO_DATABLOCK_V1(afxZodiacData )

ImplementEnumType(afxZodiac_BlendType , "Possible zodiac blend <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxZodiac\n\n</a>" )

  1
  2
  3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
  5// Copyright (C) 2015 Faust Logic, Inc.
  6//
  7// Permission is hereby granted, free of charge, to any person obtaining a copy
  8// of this software and associated documentation files (the "Software"), to
  9// deal in the Software without restriction, including without limitation the
 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 11// sell copies of the Software, and to permit persons to whom the Software is
 12// furnished to do so, subject to the following conditions:
 13//
 14// The above copyright notice and this permission notice shall be included in
 15// all copies or substantial portions of the Software.
 16//
 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 23// IN THE SOFTWARE.
 24//
 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 26
 27#include "afx/arcaneFX.h"
 28
 29#include "console/consoleTypes.h"
 30#include "core/stream/bitStream.h"
 31#include "core/frameAllocator.h"
 32#include "terrain/terrRender.h"
 33#include "gfx/primBuilder.h"
 34
 35#include "afx/ce/afxZodiac.h"
 36
 37GFX_ImplementTextureProfile(AFX_GFXZodiacTextureProfile, 
 38                            GFXTextureProfile::DiffuseMap, 
 39                            GFXTextureProfile::Static | GFXTextureProfile::NoMipmap | GFXTextureProfile::PreserveSize,  
 40                            GFXTextureProfile::NONE);
 41
 42//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 43
 44void afxZodiacData::convertGradientRangeFromDegrees(Point2F& gradrange, const Point2F& gradrange_deg)
 45{
 46  F32 x = mCos(mDegToRad(gradrange_deg.x));
 47  F32 y = mCos(mDegToRad(gradrange_deg.y));
 48  if (y > x)
 49    gradrange.set(x, y);
 50  else
 51    gradrange.set(y, x);
 52}
 53
 54
 55//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 56//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 57// afxZodiacData
 58
 59IMPLEMENT_CO_DATABLOCK_V1(afxZodiacData);
 60
 61ConsoleDocClass( afxZodiacData,
 62   "@brief A datablock that specifies a decal-like Zodiac effect.\n\n"
 63
 64   "Zodiacs are special-purpose decal textures, often circular, that are always projected vertically onto the ground. Parameters "
 65   "control dynamic rotation and scale as well as texture, color, and blending style."
 66   "\n\n"
 67
 68   "Zodiacs render on objects of type TerrainBlock, InteriorInstance, GroundPlane, MeshRoad, and TSStatic. They are very "
 69   "effective as spellcasting lighting rings, explosion shockwaves, scorched earth decals, and selection indicators."
 70   "\n\n"
 71
 72   "@ingroup afxEffects\n"
 73   "@ingroup AFX\n"
 74   "@ingroup Datablocks\n"
 75);
 76
 77StringTableEntry afxZodiacData::GradientRangeSlot;
 78bool afxZodiacData::sPreferDestinationGradients = false;
 79
 80afxZodiacData::afxZodiacData()
 81{
 82  txr_name = ST_NULLSTRING;
 83  radius_xy = 1;
 84  vert_range.set(0.0f, 0.0f);
 85  start_ang = 0;
 86  ang_per_sec = 0;
 87  color.set(1,1,1,1);
 88  grow_in_time = 0.0f; 
 89  shrink_out_time = 0.0f;
 90  growth_rate = 0.0f;
 91  blend_flags = BLEND_NORMAL;
 92  terrain_ok = true;
 93  interiors_ok = true;
 94  reflected_ok = false;
 95  non_reflected_ok = true;
 96  respect_ori_cons = false;
 97  scale_vert_range = true;
 98
 99  interior_h_only = false;
100  interior_v_ignore = false;
101  interior_back_ignore = false;
102  interior_opaque_ignore = false;
103  interior_transp_ignore = true;
104
105  altitude_max = 0.0f;
106  altitude_falloff = 0.0f;
107  altitude_shrinks = false;
108  altitude_fades = false;
109
110  distance_max = 75.0f;
111  distance_falloff = 30.0f;
112
113  use_grade_range = false;
114  prefer_dest_grade = sPreferDestinationGradients;
115  grade_range_user.set(0.0f, 45.0f);
116  afxZodiacData::convertGradientRangeFromDegrees(grade_range, grade_range_user);
117  inv_grade_range = false;
118  zflags = 0;
119}
120
121afxZodiacData::afxZodiacData(const afxZodiacData& other, bool temp_clone) : GameBaseData(other, temp_clone)
122{
123  txr_name = other.txr_name;
124  txr = other.txr;
125  radius_xy = other.radius_xy;
126  vert_range = other.vert_range;
127  start_ang = other.start_ang;
128  ang_per_sec = other.ang_per_sec;
129  grow_in_time = other.grow_in_time;
130  shrink_out_time = other.shrink_out_time;
131  growth_rate = other.growth_rate;
132  color = other.color;
133
134  altitude_max = other.altitude_max;
135  altitude_falloff = other.altitude_falloff;
136  altitude_shrinks = other.altitude_shrinks;
137  altitude_fades = other.altitude_fades;
138
139  distance_max = other.distance_max;
140  distance_falloff = other.distance_falloff;
141
142  use_grade_range = other.use_grade_range;
143  prefer_dest_grade = other.prefer_dest_grade;
144  grade_range = other.grade_range;
145  inv_grade_range = other.inv_grade_range;
146
147  zflags = other.zflags;
148  expand_zflags();
149}
150
151ImplementEnumType( afxZodiac_BlendType, "Possible zodiac blend types.\n" "@ingroup afxZodiac\n\n" )
152   { afxZodiacData::BLEND_NORMAL,      "normal",         "..." },
153   { afxZodiacData::BLEND_ADDITIVE,    "additive",       "..." },
154   { afxZodiacData::BLEND_SUBTRACTIVE, "subtractive",    "..." },
155EndImplementEnumType;
156
157void afxZodiacData::initPersistFields()
158{
159  addField("texture",               TypeFilename,   Offset(txr_name,          afxZodiacData),
160    "An image to use as the zodiac's texture.");
161  addField("radius",                TypeF32,        Offset(radius_xy,         afxZodiacData),
162    "The zodiac's radius in scene units.");
163  addField("verticalRange",         TypePoint2F,    Offset(vert_range,        afxZodiacData),
164    "For interior zodiacs only, verticalRange specifies distances above and below the "
165    "zodiac's position. If both values are 0.0, the radius is used.");
166  addField("scaleVerticalRange",    TypeBool,       Offset(scale_vert_range,  afxZodiacData),
167    "Specifies if the zodiac's verticalRange should scale according to changes in the "
168    "radius. When a zodiacs is used as an expanding shockwave, this value should be set "
169    "to false, otherwise the zodiac can expand to cover an entire interior.");
170  addField("startAngle",            TypeF32,        Offset(start_ang,         afxZodiacData),
171    "The starting angle in degrees of the zodiac's rotation.");
172  addField("rotationRate",          TypeF32,        Offset(ang_per_sec,       afxZodiacData),
173    "The rate of rotation in degrees-per-second. Zodiacs with a positive rotationRate "
174    "rotate clockwise, while those with negative values turn counter-clockwise.");
175  addField("growInTime",            TypeF32,        Offset(grow_in_time,      afxZodiacData),
176    "A duration of time in seconds over which the zodiac grows from a zero size to its "
177    "full size as specified by the radius.");
178  addField("shrinkOutTime",         TypeF32,        Offset(shrink_out_time,   afxZodiacData),
179    "A duration of time in seconds over which the zodiac shrinks from full size to "
180    "invisible.");
181  addField("growthRate",            TypeF32,        Offset(growth_rate,       afxZodiacData),
182    "A rate in meters-per-second at which the zodiac grows in size. A negative value will "
183    "shrink the zodiac.");
184  addField("color",                 TypeColorF,     Offset(color,             afxZodiacData),
185    "A color value for the zodiac.");
186
187  addField("blend", TYPEID<BlendType>(), Offset(blend_flags, afxZodiacData),
188    "A blending style for the zodiac. Possible values: normal, additive, or subtractive.");
189
190  addField("showOnTerrain",         TypeBool,       Offset(terrain_ok,        afxZodiacData),
191    "Specifies if the zodiac should be rendered on terrain or terrain-like surfaces.");
192  addField("showOnInteriors",       TypeBool,       Offset(interiors_ok,      afxZodiacData),
193    "Specifies if the zodiac should be rendered on interior or interior-like surfaces.");
194  addField("showInReflections",     TypeBool,       Offset(reflected_ok,      afxZodiacData),
195    "Specifies if the zodiac should be rendered on the reflection rendering pass of the "
196    "object it will be projected onto.");
197  addField("showInNonReflections",  TypeBool,       Offset(non_reflected_ok,  afxZodiacData),
198    "Specifies if the zodiac should be rendered on the non-reflection rendering pass of "
199    "the object it will be projected onto.");
200  addField("trackOrientConstraint", TypeBool,       Offset(respect_ori_cons,  afxZodiacData),
201    "Specifies if the zodiac's rotation should be defined by its constrained "
202    "transformation.");
203
204  addField("interiorHorizontalOnly",    TypeBool,   Offset(interior_h_only,        afxZodiacData),
205    "Specifies if interior zodiacs should be rendered exclusively on perfectly horizontal "
206    "interior surfaces.");
207  addField("interiorIgnoreVertical",    TypeBool,   Offset(interior_v_ignore,      afxZodiacData),
208    "Specifies if interior zodiacs should not be rendered on perfectly vertical interior "
209    "surfaces.");
210  addField("interiorIgnoreBackfaces",   TypeBool,   Offset(interior_back_ignore,   afxZodiacData),
211    "Specifies if interior zodiacs should not be rendered on interior surface which are "
212    "backfacing to the zodiac's center.");
213  addField("interiorIgnoreOpaque",      TypeBool,   Offset(interior_opaque_ignore, afxZodiacData),
214    "");
215  addField("interiorIgnoreTransparent", TypeBool,   Offset(interior_transp_ignore, afxZodiacData),
216    "");
217
218  addField("altitudeMax",           TypeF32,      Offset(altitude_max, afxZodiacData),
219    "The altitude at which zodiac becomes invisible as the result of fading out or "
220    "becoming too small.");
221  addField("altitudeFalloff",       TypeF32,      Offset(altitude_falloff, afxZodiacData),
222    "The altitude at which zodiac begins to fade and/or shrink.");
223  addField("altitudeShrinks",       TypeBool,     Offset(altitude_shrinks, afxZodiacData),
224    "When true, zodiac becomes smaller as altitude increases.");
225  addField("altitudeFades",         TypeBool,     Offset(altitude_fades, afxZodiacData),
226    "When true, zodiac fades out as altitude increases.");
227
228  addField("distanceMax",           TypeF32,      Offset(distance_max, afxZodiacData),
229    "The distance from camera at which the zodiac becomes invisible as the result of "
230    "fading out.");
231  addField("distanceFalloff",       TypeF32,      Offset(distance_falloff, afxZodiacData),
232    "The distance from camera at which the zodiac begins to fade out.");
233
234  addField("useGradientRange",      TypeBool,     Offset(use_grade_range, afxZodiacData),
235    "When true, gradientRange will be used to determine on which polygons the zodiac will "
236    "render.");
237  addField("preferDestinationGradients", TypeBool,  Offset(prefer_dest_grade, afxZodiacData),
238    "When true, a gradientRange specified on an InteriorInstance or TSStatic will be used "
239    "instead of the zodiac's gradientRange.");
240  addField("gradientRange",              TypePoint2F,  Offset(grade_range_user, afxZodiacData),
241    "Zodiac will render on polygons with gradients within the range specified by "
242    "gradientRange. 0 for floor polys, 90 for wall polys, 180 for ceiling polys.");
243  addField("invertGradientRange",        TypeBool,     Offset(inv_grade_range,   afxZodiacData),
244    "When true, the zodiac will render on polygons with gradients outside of the range "
245    "specified by gradientRange.");
246
247  Parent::initPersistFields();
248
249  GradientRangeSlot = StringTable->lookup("gradientRange");
250  Con::addVariable("pref::afxZodiac::preferDestinationGradients", TypeBool, &sPreferDestinationGradients);
251}
252
253bool afxZodiacData::onAdd()
254{
255  if (Parent::onAdd() == false)
256    return false;
257
258  if (altitude_falloff > altitude_max)
259    altitude_falloff = altitude_max;
260
261  if (distance_falloff > distance_max)
262    distance_falloff = distance_max;
263
264  return true;
265}
266
267void afxZodiacData::packData(BitStream* stream)
268{
269   Parent::packData(stream);
270
271  merge_zflags();
272
273  stream->writeString(txr_name);
274  stream->write(radius_xy);
275  stream->write(vert_range.x);
276  stream->write(vert_range.y);
277  stream->write(grade_range.x);
278  stream->write(grade_range.y);
279  stream->write(start_ang);
280  stream->write(ang_per_sec);
281  stream->write(grow_in_time);
282  stream->write(shrink_out_time);
283  stream->write(growth_rate);
284  stream->write(color);
285  stream->write(zflags);
286  stream->write(altitude_max);
287  stream->write(altitude_falloff);
288  stream->writeFlag(altitude_shrinks);
289  stream->writeFlag(altitude_fades);
290  stream->write(distance_max);
291  stream->write(distance_falloff);
292}
293
294void afxZodiacData::unpackData(BitStream* stream)
295{
296  Parent::unpackData(stream);
297
298  txr_name = stream->readSTString();
299  txr = GFXTexHandle();
300  stream->read(&radius_xy);
301  stream->read(&vert_range.x);
302  stream->read(&vert_range.y);
303  stream->read(&grade_range.x);
304  stream->read(&grade_range.y);
305  stream->read(&start_ang);
306  stream->read(&ang_per_sec);
307  stream->read(&grow_in_time);
308  stream->read(&shrink_out_time);
309  stream->read(&growth_rate);
310  stream->read(&color);
311  stream->read(&zflags);
312  stream->read(&altitude_max);
313  stream->read(&altitude_falloff);
314  altitude_shrinks = stream->readFlag();
315  altitude_fades = stream->readFlag();
316  stream->read(&distance_max);
317  stream->read(&distance_falloff);
318
319  expand_zflags();
320}
321
322bool afxZodiacData::preload(bool server, String &errorStr)
323{
324  if (!Parent::preload(server, errorStr))
325    return false;
326
327  if (!server)
328  {
329    if (txr_name && txr_name[0] != '\0')
330    {
331      txr.set(txr_name, &AFX_GFXZodiacTextureProfile, "Zodiac Texture");
332    }
333  }
334
335  if (vert_range.x == 0.0f && vert_range.y == 0.0f)
336    vert_range.x = vert_range.y = radius_xy;
337
338  return true;
339}
340
341void afxZodiacData::onStaticModified(const char* slot, const char* newValue)
342{
343  Parent::onStaticModified(slot, newValue);
344  if (slot == GradientRangeSlot)
345  {
346    convertGradientRangeFromDegrees(grade_range, grade_range_user);
347    return;
348  }
349  merge_zflags();
350}
351
352void afxZodiacData::onPerformSubstitutions() 
353{ 
354    if (txr_name && txr_name[0] != '\0')
355    {
356      txr.set(txr_name, &AFX_GFXZodiacTextureProfile, "Zodiac Texture");
357    }
358}
359
360F32 afxZodiacData::calcRotationAngle(F32 elapsed, F32 rate_factor)
361{
362  F32 angle = start_ang + elapsed*ang_per_sec*rate_factor;
363  angle = mFmod(angle, 360.0f);
364
365  return angle;
366}
367
368void afxZodiacData::expand_zflags()
369{
370  blend_flags = (zflags & BLEND_MASK);
371  terrain_ok = ((zflags & SHOW_ON_TERRAIN) != 0);
372  interiors_ok = ((zflags & SHOW_ON_INTERIORS) != 0);
373  reflected_ok = ((zflags & SHOW_IN_REFLECTIONS) != 0);
374  non_reflected_ok = ((zflags & SHOW_IN_NON_REFLECTIONS) != 0);
375  respect_ori_cons = ((zflags & RESPECT_ORIENTATION) != 0);
376  scale_vert_range = ((zflags & SCALE_VERT_RANGE) != 0);
377  interior_h_only = ((zflags & INTERIOR_HORIZ_ONLY) != 0);
378  interior_v_ignore = ((zflags & INTERIOR_VERT_IGNORE) != 0);
379  interior_back_ignore = ((zflags & INTERIOR_BACK_IGNORE) != 0);
380  interior_opaque_ignore = ((zflags & INTERIOR_OPAQUE_IGNORE) != 0);
381  interior_transp_ignore = ((zflags & INTERIOR_TRANSP_IGNORE) != 0);
382  use_grade_range = ((zflags & USE_GRADE_RANGE) != 0);
383  prefer_dest_grade = ((zflags & PREFER_DEST_GRADE) != 0);
384  inv_grade_range = ((zflags & INVERT_GRADE_RANGE) != 0);
385}
386
387void afxZodiacData::merge_zflags()
388{
389  zflags = (blend_flags & BLEND_MASK);
390  if (terrain_ok)
391    zflags |= SHOW_ON_TERRAIN;
392  if (interiors_ok)
393    zflags |= SHOW_ON_INTERIORS;
394  if (reflected_ok)
395    zflags |= SHOW_IN_REFLECTIONS;
396  if (non_reflected_ok)
397    zflags |= SHOW_IN_NON_REFLECTIONS;
398  if (respect_ori_cons)
399    zflags |= RESPECT_ORIENTATION;
400  if (scale_vert_range)
401    zflags |= SCALE_VERT_RANGE;
402  if (interior_h_only)
403    zflags |= INTERIOR_HORIZ_ONLY;
404  if (interior_v_ignore)
405    zflags |= INTERIOR_VERT_IGNORE;
406  if (interior_back_ignore)
407    zflags |= INTERIOR_BACK_IGNORE;
408  if (interior_opaque_ignore)
409    zflags |= INTERIOR_OPAQUE_IGNORE;
410  if (interior_transp_ignore)
411    zflags |= INTERIOR_TRANSP_IGNORE;
412  if (use_grade_range)
413    zflags |= USE_GRADE_RANGE;
414  if (prefer_dest_grade)
415    zflags |= PREFER_DEST_GRADE;
416  if (inv_grade_range)
417    zflags |= INVERT_GRADE_RANGE;
418}
419
420//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
421