|
|
Right, here's the magic incantation:
// 'Encase' places objects over the surface of another object.
// Call this macro from inside union or merge for greater flexibility.
//
// baseobj - object identifier - the target object (must not be infinite).
// componentobj - object identifier - the object to be copied over the surface
of the target object.
// randy - yes/no - should componentobj be randomly rotated around the normal
when placed? (yes for grass etc)
// randxy - yes/no - should componentobj be randomly oriented before scaling and
placement? (yes for rocks etc)
// dx - float - grid size; probably similar to average object separation after
placement.
// scal1 - float - scale factor of componentobj in-plane (relative to dx)
// scal2 - float - scale factor of componentobj along normal (relative to dx)
// sd - seed - the random seed to be used.
//
#macro Encase(baseobj, componentobj, randy, randxy, dx, scal1, scal2, sd)
#local minext = min_extent(baseobj);
#local maxext = max_extent(baseobj);
#local xwid = maxext.x - minext.x;
#local ywid = maxext.y - minext.y;
#local zwid = maxext.z - minext.z;
#local norm = <0, 0, 0>;
#local dirs = array[6] { x, -x, y, -y, z, -z }
#local zp = minext.z + dx/2;
#while (zp < maxext.z)
#local yp = minext.y + dx/2;
#while (yp < maxext.y)
#local xp = minext.x + dx/2;
#while (xp < maxext.x)
#local startpos = <xp+dx*(rand(sd)-0.5), yp+dx*(rand(sd)-0.5),
zp+dx*(rand(sd)-0.5)>;
#local n = 0;
#local trans = transform { rotate x*rand(sd)*90 rotate y*rand(sd)*90 }
#while ((n < 6))
#local dir = vtransform(dirs[n], trans);
#local spoint = trace(baseobj, startpos, dir, norm);
#local sdist = vlength(spoint-startpos);
#if ((sdist < dx) & (vlength(norm) > 0))
object {
componentobj
#if (randy) rotate y*rand(sd) #end
#if (randxy) rotate x*rand(sd)*360 rotate y*rand(sd)*360 #end
scale <scal1*dx, scal2*dx, scal1*dx>
Point_At_Trans(norm) translate spoint }
#end
#local n = n + 1;
#end // direction loop
#local xp = xp + dx;
#end // x loop
#local yp = yp + dx;
#end // y loop
#local zp = zp + dx;
#end // z loop
#end
// usage example:
#declare TestTorus = torus { 2, 1 }
#declare TestBall = sphere { <0,0,0>, 1 }
#declare r1 = seed(0);
Encase(TestTorus, TestBall, no, no, 0.2, 0.5, 0.5, r1)
Hope it's useful!
Bill
Post a reply to this message
|
|