/* pvars.inc * * store, manipulate, and use up to four related (typically) variables * packed in a single 4-vector; the values can be integers, booleans, * and or floats, no strings or vectors. elements ("components") are * addressed via an index, zero-based like arrays. * nb. packed variables have no "state", are simply regular 4-vectors. * * Persistence of Vision Raytracer version 3.8 or later. * * pvPack(opt a, opt b, opt c, opt d) * takes four arguments, all optional and zero where omitted, and * returns a 4-vector value "packed" in argument order; eg if N = 4, * then '#declare pv = pvPack(,5,N,);' equals '<0,5,4,0>'. * * pvSet(pv, i, n) * sets the 'i'th element of 'pv' to the new value 'n'. * eg continuing from the example above, 'pvSet(pv,0,6)' will set * 'pv' to '<6,5,4,0>'. * * pvClear(pv, i) * zeroises the 'i'th element of 'pv'. * * pvGet(pv, i) * retrieves/returns the 'i'th element from 'pv'. * eg reusing 'pv' from above, '#declare foo = 2 + pvGet(pv,2);' * will set 'foo' to '6'. * * pvFormat(pv, fmt) * returns the contents of 'pv' as a formatted string, where * the precision for each component is read from the (4-vector) * 'fmt'; eg reusing 'pv' from above and format '<2,0,2,0>', * will expand to "{6.00 : 5 : 4.00 : 0}". * * pvIncr(pv, i, opt n) * increments the 'i'th element of 'pv' by 'n', '1' when omitted. * * pvToggle(pv, i) * treating the 'i'th element of 'pv' as a boolen value, the call * negates its value, eg reusing 'pv' from above, 'pvToggle(pv,3)' * will set 'pv' to '<6,5,4,1>'. * * pvUnpack(pv) * expands the packed variable to its elements and returns these * for "tuple assignment", eg. '#declare (a,b,c,d) = pvUnpack(pv);'. * * version 202203.1 */ #ifndef (pv_include_temp) #declare pv_include_temp = version; #version 3.8; #ifdef (View_POV_Include_Stack) #debug "including packed.inc\n" #end #macro pvPack(optional a_,optional b_,optional c_,optional d_) #local (v0_,v1_,v2_,v3_) = (0,0,0,0); #if (defined(local.d_)) #local v3_ = d_; #end #if (defined(local.c_)) #local v2_ = c_; #end #if (defined(local.b_)) #local v1_ = b_; #end #if (defined(local.a_)) #local v0_ = a_; #end #end #macro pvSet(pv_,i_,n_) #switch (i_) #case (0) #local v_ = ; #break #case (1) #local v_ = ; #break #case (2) #local v_ = ; #break #case (3) #local v_ = ; #break #else #error "oops, bad 'pv' index." #end #local pv_ = v_; #end #macro pvClear(pv_,i_) pvSet(pv_,i_,0) #end #macro pvGet(pv_,i_) #switch (i_) #case (0) #local v_ = pv_.x; #break #case (1) #local v_ = pv_.y; #break #case (2) #local v_ = pv_.z; #break #case (3) #local v_ = pv_.t; #break #else #error "oops, bad 'pv' index." #end v_ #end #macro pvFormat(pv_,fmt_) #local s_ = "{"; #for (i_,0,3) #if (i_) #local s_ = concat(s_," : "); #end #local s_ = concat(s_,str(pvGet(pv_,i_),0,pvGet(fmt_,i_))); #end concat(s_,"}") #end #macro pvIncr(pv_,i_,optional n_) #if (!defined(local.n_)) #local n_ = 1; #end #switch (i_) #case (0) #local v_ = <(pv_.x + n_), pv_.y, pv_.z, pv_.t>; #break #case (1) #local v_ = ; #break #case (2) #local v_ = ; #break #case (3) #local v_ = ; #break #else #error "oops, bad 'pv' index." #end #local pv_ = v_; #end #macro pvToggle(pv_,i_) #switch (i_) #case (0) #local v_ = ; #break #case (1) #local v_ = ; #break #case (2) #local v_ = ; #break #case (3) #local v_ = ; #break #else #error "oops, bad 'pv' index." #end #local pv_ = v_; #end #macro pvUnpack(pv_) (pv_.x, pv_.y, pv_.z, pv_.t) #end #version pv_include_temp; #end /* -------------------------------------------------------------------- * * the content above is covered by the GNU General Public License v3+ * * copyright (c) 2022 jr . * * all rights reserved. * * -------------------------------------------------------------------- */