/* Hfwrap.inc - Wraps height fields around cylinders with a variety of options. Version 1.0 (Tmpov for Povray 3.02) This version requires Tmpov, a custom compile by Jamis Buck and Noel Bundy with patches created by several others. It is available (for Win95 systems only) at: http://twysted.net This include file approximates a (vertical or horizontal) cylindrical height field with a triangle or smooth_triangle mesh. Parse is quite slow, but it renders fast. Usage: #declare your options and variables and then #include "hfwrap.inc". You must declare your height field by saying, for example: #declare __Hftomap = height_field { tga "Myhf.tga" }. #declare Mymesh = #include "hfwrap.inc" object { Mymesh } All other options/variables have reasonable defaults. Options/Variables: __Hftomap - Name assigned to height field. Required. No default. __Hftex - Texture assigned to mesh. Default is a shiny red. __Ht - Height of cylinder. Default 1. __Rad - Radius of cylinder. Default 1 / (2 * pi). The defaults for __Rad and __Ht are chosen to wrap a square height field without distortion. Unfortunately the result is rather tall and narrow. __Horiz - Flag that tells whether to make cylinder horizontal. Default 0. 0 means vertical, 1 (or nonzero) means horizontal. __Begin - Where to start your cylinder slice. Default 0. Range usually 0 to 360. __Begin and __End allow you to render only a portion of a cylinder. The entire height field is placed on the portion of the cylinder that you render. __End - Where to end your cylinder slice. Default 360. Range usually 0 to 360. See __Begin for more information. __Exag - Exaggeration of height field. Default 1. Makes amplitude of height field larger or smaller in relation to cylinder radius. Negative Exag carves height field in to cylinder instead of sculpting it out from cylinder. __Offset - Offsets height field in relation to cylinder. Default 0. A positive value pushes height field out from cylinder on a sort of plateau. A negative value indents all or part of the height field. If, for example, the offset is -.4, height field values of 0 to .4 become 0 to -.4, values from .4 to .8 become -.4 to 0, and values from .8 to 1.0 become 0 to .2. __Offset -1 works like __Exag -1. Useful offsets are usually in the range of 1 to -1. Experiment will make this clearer. Offset never moves the 0 level (the surface of the base cylinder), but if __Ztrim is set, triangles that touch the 0 level are omitted, giving you just the positive and/or negative "bumps" of the height field. __Xfine - How many samples of the height field in the x direction. Default 128. If you have the memory, __Xfine = x resolution of height field image is good. Using a smaller number skips some pixels of the height field. Can work with __Zfine to distort the sampling to make up for altering __Rad and __Ht. __Zfine - How many samples of the height field in the z direction. Default 128. __Watlev - Water level. Default 0. Range 0 to 1. It is internally adjusted to take __Exag, __Offset, etc. in to account. The height values are clamped to a minimum value of __Watlev. Normally, the shape is flattened at that level. If __Wtrim is set, the triangles with corners at that level are omitted. This is more like the "water_level" setting in regular height fields. __Skylev - Sky level. Default 1. Range 0 to 1. It is internally adjusted to tak __Exag, __Offset, etc. in to account. The height values are clamped to a maximum value of __Skylev. Normally, the shape is flattened at that level. If __Strim is set, the triangles with corners at that level are omitted. This is a sort of opposite of __Watlev. __Smooth - Flag that tells whether to use smooth_triangles. Default 0. 0 means "use ordinary triangles", 1 (or nonzero) means "use smooth triangles." Smoothing is done by averaging the normals of the triangles incident at a vertex (even if they are not rendered because of __Watlev, etc.) Smooth triangles use more memory and parse more slowly, but they can look better, especially with a small height field covering a lot of screen space. __Wtrim - Flag that tells whether to omit triangles that touch __Watlev. Default 0. 0 means "do not omit", 1 (or nonzero) means "omit triangles that touch __Watlev". See __Watlev for more information. __Strim - Flag that tells whether to omit triangles that touch __Skylev. Default 0. 0 means "do not omit", 1 (or nonzero) means "omit triangles that touch __Skylev". See __Skylev for more information. __Ztrim - Flag that tells whether to omit triangles that touch 0 (base cylinder surface). Default 0. 0 means "do not omit", 1 (or nonzero) means "omit triangles that touch 0". This is most useful in conjunction with __Offset. See __Offset for more information. __Progress - Flag that tells whether to send progress reports to the #debug stream while parsing. Default 1. 0 means "no progress reports" and 1 (or nonzero) means "send progress reports to #debug". Free for commercial or noncommercial use. As is. No warranty of any kind. Reserve the right to change it at any time. Use it, abuse it, but don't blame me. Copyright 1998 by Jerry Anning. Permission granted to use, distribute, upload, download and copy. Questions to Jerry Anning, clem@dhol.com. */ #ifndef(__Hftomap) #warning "__Hftomap not defined for Hfwrap.inc\n" #end #ifndef(__Hftex) #declare __Hftex = texture { pigment { color rgb <1, 0, 0> } finish { specular 1 roughness .001 reflection .1 } } #end #ifndef (__Ht) #declare __Ht = 1 #end #ifndef (__Rad) #declare __Rad = -1 / (2 * pi) #end #declare __Rad = ((__Rad > 0) ? -__Rad : __Rad) #ifndef (__Horiz) #declare __Horiz = 0 #end #declare __Horiz = ((__Horiz != 0) ? 1 : 0) #ifndef (__Exag) #declare __Exag = 1 #end #ifndef (__Begin) #declare __Begin = 0 #end #declare __Begin = mod(__Begin, 360) #declare __Begin = ((__Begin < 0) ? __Begin + 360 : __Begin) #ifndef (__End) #declare __End = 360 #end #declare __End = mod(__End, 360) #declare __End = ((__End < 0) ? __End + 360 : __End) #declare __End = ((__End <= __Begin) ? __End + 360 : __End) #ifndef (__Offset) #declare __Offset = 0 #end #ifndef (__Xfine) #declare __Xfine = 128 #end #ifndef (__Zfine) #declare __Zfine = 128 #end #ifndef (__Watlev) #declare __Watlev = 0 #end #declare __Watlev = max(0, min(__Watlev, 1)) #ifndef (__Skylev) #declare __Skylev = 1 #end #declare __Skylev = max(0, min(__Skylev, 1)) #ifndef (__Smooth) #declare __Smooth = 0 #end #declare __Smooth = ((__Smooth != 0) ? 1 : 0) #ifndef(__Wtrim) #declare __Wtrim = 0 #end #declare __Wtrim = ((__Wtrim != 0) ? 1 : 0) #ifndef (__Strim) #declare __Strim = 0 #end #declare __Strim = ((__Strim != 0) ? 1 : 0) #ifndef (__Ztrim) #declare __Ztrim = 0 #end #declare __Ztrim = ((__Ztrim != 0) ? 1 : 0) #ifndef (__Progress) #declare __Progress = 1 #end #declare __Progress = ((__Progress != 0) ? 1 : 0) mesh { #declare __Xfine1 = __Xfine - 1 #declare __Xfine2 = __Xfine - 2 #declare __Zfine1 = __Zfine - 1 #declare __Zfine2 = __Zfine - 2 #declare __Ext = __End - __Begin #declare __Inc = -y * __Ext / __Xfine #declare __Wo = __Watlev + __Offset #declare __So = __Skylev + ((__Offset < 0) ? (2 * __Offset) : __Offset) #if (__Horiz = 1) #declare __Hftomap = height_field { __Hftomap rotate <0, -90, 0> } #end #declare __Ziter = 0 #while (__Ziter < __Zfine1) #declare __Xiter = 0 #declare __Zpos = __Ziter / __Zfine1 #declare __Zposp1 = (__Ziter + 1) / __Zfine1 #if (__Ziter < __Zfine2) #declare __Zposp2 = (__Ziter + 2) / __Zfine1 #end #if (__Ziter != 0) #declare __Zposm1 = (__Ziter -1) / __Zfine1 #end #while (__Xiter < __Xfine) #declare __Xpos = __Xiter / __Xfine1 #declare __Zpos = __Ziter / __Zfine1 #declare __Xposp1 = mod(__Xiter + 1, __Xfine1) / __Xfine1 #declare __Xposp2 = mod(__Xiter + 2, __Xfine1) / __Xfine1 #declare __Rot = __Inc * __Xiter #declare __Rotp1 = __Inc * mod(__Xiter + 1, __Xfine1) #declare __Rotp2 = __Inc * mod(__Xiter + 2, __Xfine1) #if (__Xiter != 0) #declare __Xposm1 = (__Xiter - 1) / __Xfine1 #declare __Rotm1 = __Inc * (__Xiter - 1) #else #declare __Xposm1 = 1 #declare __Rotm1 = __Inc * __Xfine1 #end #declare __Yposa = hf_height_at(__Xpos, __Zpos, __Hftomap) #declare __Yposa = ((__Yposa = 0) ? 0 : ((__Offset < 0) ? ((__Yposa <= abs(__Offset)) ? -__Yposa : (__Yposa + 2 * __Offset)) : (__Yposa + __Offset))) #declare __Yposa = min(max(__Yposa, __Wo), __So) #declare __Yposas = ((__Wtrim = 0) ? 1 : ((__Yposa = __Wo) ? 0 : 1)) #declare __Yposas = ((__Strim = 0) ? __Yposas : ((__Yposa = __So) ? 0 : __Yposas)) #declare __Yposas = ((__Ztrim = 0) ? __Yposas : ((__Yposa = 0) ? 0 : __Yposas)) #declare __Yposa = ((__Yposa * __Exag) + 1) * __Rad #declare __Yposb = hf_height_at(__Xposp1, __Zpos, __Hftomap) #declare __Yposb = ((__Yposb = 0) ? 0 : ((__Offset < 0) ? ((__Yposb <= abs(__Offset)) ? -__Yposb : (__Yposb + 2 * __Offset)) : (__Yposb + __Offset))) #declare __Yposb = min(max(__Yposb, __Wo), __So) #declare __Yposbs = ((__Wtrim = 0) ? 1 : ((__Yposb = __Wo) ? 0 : 1)) #declare __Yposbs = ((__Strim = 0) ? __Yposbs : ((__Yposb = __So) ? 0 : __Yposbs)) #declare __Yposbs = ((__Ztrim = 0) ? __Yposbs : ((__Yposb = 0) ? 0 : __Yposbs)) #declare __Yposb = ((__Yposb * __Exag) + 1) * __Rad #declare __Yposc = hf_height_at(__Xposp1, __Zposp1, __Hftomap) #declare __Yposc = ((__Yposc = 0) ? 0 : ((__Offset < 0) ? ((__Yposc <= abs(__Offset)) ? -__Yposc : (__Yposc + 2 * __Offset)) : (__Yposc + __Offset))) #declare __Yposc = min(max(__Yposc, __Wo), __So) #declare __Yposcs = ((__Wtrim = 0) ? 1 : ((__Yposc = __Wo) ? 0 : 1)) #declare __Yposcs = ((__Strim = 0) ? __Yposcs : ((__Yposc = __So) ? 0 : __Yposcs)) #declare __Yposcs = ((__Ztrim = 0) ? __Yposcs : ((__Yposc = 0) ? 0 : __Yposcs)) #declare __Yposc = ((__Yposc * __Exag) + 1) * __Rad #declare __Yposd = hf_height_at(__Xpos, __Zposp1, __Hftomap) #declare __Yposd = ((__Yposd = 0) ? 0 : ((__Offset < 0) ? ((__Yposd <= abs(__Offset)) ? -__Yposd : (__Yposd + 2 * __Offset)) : (__Yposd + __Offset))) #declare __Yposd = min(max(__Yposd, __Wo), __So) #declare __Yposds = ((__Wtrim = 0) ? 1 : ((__Yposd = __Wo) ? 0 : 1)) #declare __Yposds = ((__Strim = 0) ? __Yposds : ((__Yposd = __So) ? 0 : __Yposds)) #declare __Yposds = ((__Ztrim = 0) ? __Yposds : ((__Yposd = 0) ? 0 : __Yposds)) #declare __Yposd = ((__Yposd * __Exag) + 1) * __Rad #declare __Sadc = __Yposas * __Yposds * __Yposcs #declare __Sadc = ((__Xpos = 1) ? ((__Ext < 360) ? 0 : __Sadc) : __Sadc) #declare __Sacb = __Yposas * __Yposcs * __Yposbs #declare __Sacb = ((__Xpos = 1) ? ((__Ext < 360) ? 0 : __Sacb) : __Sacb) #if (__Smooth != 0) #declare __Ypose = hf_height_at(__Xposm1, __Zpos, __Hftomap) #declare __Ypose = ((__Ypose = 0) ? 0 : ((__Offset < 0) ? ((__Ypose <= abs(__Offset)) ? -__Ypose : (__Ypose + 2 * __Offset)) :(__Ypose + __Offset))) #declare __Ypose = min(max(__Ypose, __Wo), __So) #declare __Ypose = ((__Ypose * __Exag) + 1) * __Rad #declare __Yposn = hf_height_at(__Xposm1, __Zposp1, __Hftomap) #declare __Yposn = ((__Yposn = 0) ? 0 : ((__Offset < 0) ? ((__Yposn <= abs(__Offset)) ? -__Yposn : (__Yposn + 2 * __Offset)) : (__Yposn + __Offset))) #declare __Yposn = min(max(__Yposn, __Wo), __So) #declare __Yposn = ((__Yposn * __Exag) + 1) * __Rad #declare __Yposi = hf_height_at(__Xposp2, __Zpos, __Hftomap) #declare __Yposi = ((__Yposi = 0) ? 0 : ((__Offset < 0) ? ((__Yposi <= abs(__Offset)) ? -__Yposi : (__Yposi + 2 * __Offset)) : (__Yposi + __Offset))) #declare __Yposi = min(max(__Yposi, __Wo), __So) #declare __Yposi = ((__Yposi * __Exag) + 1) * __Rad #declare __Yposj = hf_height_at(__Xposp2, __Zposp1, __Hftomap) #declare __Yposj = ((__Yposj = 0) ? 0 : ((__Offset < 0) ? ((__Yposj <= abs(__Offset)) ? -__Yposj : (__Yposj + 2 * __Offset)) : (__Yposj + __Offset))) #declare __Yposj = min(max(__Yposj, __Wo), __So) #declare __Yposj = ((__Yposj * __Exag) + 1) * __Rad #if (__Ziter < __Zfine2) #declare __Yposk = hf_height_at(__Xposp2, __Zposp2, __Hftomap) #declare __Yposk = ((__Yposk = 0) ? 0 : ((__Offset < 0) ? ((__Yposk <= abs(__Offset)) ? -__Yposk : (__Yposk + 2 * __Offset)) : (__Yposk + __Offset))) #declare __Yposk = min(max(__Yposk, __Wo), __So) #declare __Yposk = ((__Yposk * __Exag) + 1) * __Rad #declare __Yposl = hf_height_at(__Xposp1, __Zposp2, __Hftomap) #declare __Yposl = ((__Yposl = 0) ? 0 : ((__Offset < 0) ? ((__Yposl <= abs(__Offset)) ? -__Yposl : (__Yposl + 2 * __Offset)) : (__Yposl + __Offset))) #declare __Yposl = min(max(__Yposl, __Wo), __So) #declare __Yposl = ((__Yposl * __Exag) + 1) * __Rad #declare __Yposm = hf_height_at(__Xpos, __Zposp2, __Hftomap) #declare __Yposm = ((__Yposm = 0) ? 0 : ((__Offset < 0) ? ((__Yposm <= abs(__Offset)) ? -__Yposm : (__Yposm + 2 * __Offset)) : (__Yposm + __Offset))) #declare __Yposm = min(max(__Yposm, __Wo), __So) #declare __Yposm = ((__Yposm * __Exag) + 1) * __Rad #end #if (__Ziter != 0) #declare __Yposf = hf_height_at(__Xposm1, __Zposm1, __Hftomap) #declare __Yposf = ((__Yposf = 0) ? 0 : ((__Offset < 0) ? ((__Yposf <= abs(__Offset)) ? -__Yposf : (__Yposf + 2 * __Offset)) : (__Yposf + __Offset))) #declare __Yposf = min(max(__Yposf, __Wo), __So) #declare __Yposf = ((__Yposf * __Exag) + 1) * __Rad #declare __Yposg = hf_height_at(__Xpos, __Zposm1, __Hftomap) #declare __Yposg = ((__Yposg = 0) ? 0 : ((__Offset < 0) ? ((__Yposg <= abs(__Offset)) ? -__Yposg : (__Yposg + 2 * __Offset)) : (__Yposg + __Offset))) #declare __Yposg = min(max(__Yposg, __Wo), __So) #declare __Yposg = ((__Yposg * __Exag) + 1) * __Rad #declare __Yposh = hf_height_at(__Xposp1, __Zposm1, __Hftomap) #declare __Yposh = ((__Yposh = 0) ? 0 : ((__Offset < 0) ? ((__Yposh <= abs(__Offset)) ? -__Yposh : (__Yposh + 2 * __Offset)) : (__Yposh + __Offset))) #declare __Yposh = min(max(__Yposh, __Wo), __So) #declare __Yposh = ((__Yposh * __Exag) + 1) * __Rad #end #end #declare __A = vrotate(<0, (__Zpos - .5) * __Ht, __Yposa>, __Rot) #declare __B = vrotate(<0, (__Zpos - .5) * __Ht, __Yposb>, __Rotp1) #declare __C = vrotate(<0, (__Zposp1 - .5) * __Ht, __Yposc>, __Rotp1) #declare __D = vrotate(<0, (__Zposp1 - .5) * __Ht, __Yposd>, __Rot) #if (__Smooth != 0) #declare __E = vrotate(<0, (__Zpos - .5) * __Ht, __Ypose>, __Rotm1) #declare __N = vrotate(<0, (__Zposp1 - .5) * __Ht, __Yposn>, __Rotm1) #declare __I = vrotate(<0, (__Zpos - .5) * __Ht, __Yposi>, __Rotp2) #declare __J = vrotate(<0, (__Zposp1 - .5) * __Ht, __Yposj>, __Rotp2) #declare __An = vcross((__E - __A), (__D - __A)) + vcross((__D - __A), (__C - __A)) + vcross((__C - __A), (__B - __A)) #declare __Bn = vcross((__A - __B), (__C - __B)) + vcross((__C - __B), (__J - __B)) + vcross((__J - __B), (__I - __B)) #declare __Cn = vcross((__J - __C), (__B - __C)) + vcross((__B - __C), (__A - __C)) + vcross((__A - __C), (__D - __C)) #declare __Dn = vcross((__C - __D), (__A - __D)) + vcross((__A - __D), (__E - __D)) + vcross((__E - __D), (__N - __D)) #if (__Ziter < __Zfine2) #declare __K = vrotate(<0, (__Zposp2 - .5) * __Ht, __Yposk>, __Rotp2) #declare __L = vrotate(<0, (__Zposp2 - .5) * __Ht, __Yposl>, __Rotp1) #declare __M = vrotate(<0, (__Zposp2 - .5) * __Ht, __Yposm>, __Rot) #declare __Cn = __Cn + vcross((__D - __C), (__L - __C)) + vcross((__L - __C), (__K - __C)) + vcross((__K - __C), (__J - __C)) #declare __Dn = __Dn + vcross((__N - __D), (__M - __D)) + vcross((__M - __D), (__L - __D)) + vcross((__L - __D), (__C - __D)) #end #if (__Ziter != 0) #declare __F = vrotate(<0, (__Zposm1 - .5) * __Ht, __Yposf>, __Rotm1) #declare __G = vrotate(<0, (__Zposm1 - .5) * __Ht, __Yposg>, __Rot) #declare __H = vrotate(<0, (__Zposm1 - .5) * __Ht, __Yposh>, __Rotp1) #declare __An = __An + vcross((__B - __A), (__G - __A)) + vcross((__G - __A), (__F - __A)) + vcross((__F - __A), (__E - __A)) #declare __Bn = __Bn + vcross((__I - __B), (__H - __B)) + vcross((__H - __B), (__G - __B)) + vcross((__G - __B), (__A - __B)) #end #declare __An = vnormalize(__An) #declare __Bn = vnormalize(__Bn) #declare __Cn = vnormalize(__Cn) #declare __Dn = vnormalize(__Dn) #declare __At = vdot(__An, vnormalize(<__A.x, 0, __A.z>)) #declare __An = ((abs(__At) = __At) ? __An : -__An) #declare __Bt = vdot(__Bn, vnormalize(<__B.x, 0, __B.z>)) #declare __Bn = ((abs(__Bt) = __Bt) ? __Bn : -__Bn) #declare __Ct = vdot(__Cn, vnormalize(<__C.x, 0, __C.z>)) #declare __Cn = ((abs(__Ct) = __Ct) ? __Cn : -__Cn) #declare __Dt = vdot(__Dn, vnormalize(<__D.x, 0, __D.z>)) #declare __Dn = ((abs(__Dt) = __Dt) ? __Dn : -__Dn) #if (__Sadc = 1) smooth_triangle { __A, __An, __D, __Dn, __C, __Cn } #end #if (__Sacb = 1) smooth_triangle { __A, __An, __C, __Cn, __B, __Bn } #end #else #if (__Sadc = 1) triangle { __A, __D, __C } #end #if (__Sacb = 1) triangle { __A, __C, __B } #end #end #declare __Xiter = __Xiter + 1 #end #if (__Progress = 1) #debug concat("Parsed HF Line ", str(__Ziter, 0, 0), " of ", str(__Zfine - 2, 0, 0), "\n") #end #declare __Ziter = __Ziter + 1 #end texture { __Hftex } #if (__Begin != 0) rotate <0, 180 - __Begin, 0> #end #if (__Horiz = 1) rotate <0, 0, -90> #end }