A Simple Button Macro
If your animations include a lot of science fiction work, or other instances where a push button is part of the scene, this short macro will do a bit of the work for you.
#macro RoundButton(pB, pT, rB, rE, dD, fM) #local hB = vlength(pT - pB); #local vY = vnormalize(pT - pB); #local vX = vnormalize(vcross(vY, <vY.y,vY.z,-vY.x>)); #local vZ = vnormalize(vcross(vX, vY)); #if (fM) merge #else union #end { #if (dD < 0) #local rD = (2 * rB * rE - rB * rB - rE * rE - dD * dD) / 2 / dD - rE; difference { lathe { 5, <0,0>, <rB,0>, <rB, hB - rE>, <rB - rE, hB - rE>, <0, hB + rD + dD> } sphere { y * (hB + rD + dD), rD } bounded_by { cylinder { 0, y * hB, rB } } } #elseif (dD > 0) #local hB = hB - dD; #local rD = (rB * rB + rE * rE + dD * dD - 2 * rB * rE) / 2 / dD + rE; intersection { lathe { 6, <0,0>, <rB,0>, <rB, hB - rE>, <rB - rE, hB - rE>, <rB - rE, hB - rE> + 2 * <rB - rE, rD - rE - dD> * rE / (rD - rE), <0, rD + rE> } sphere { y * (hB + dD - rD), rD } bounded_by { cylinder { 0, y * (hB + dD), rB } } } #else cylinder { 0, y * (hB - rE), rB } cylinder { y * (hB - 2 * rE), y * hB, (rB - rE) } #end torus { rB - rE, rE translate y * (hB - rE) } matrix <vX.x,vX.y,vX.z, vY.x,vY.y,vY.z, vZ.x,vZ.y,vZ.z, pB.x,pB.y,pB.z> } #end
The button it creates is round, with a rounded edge, and you can make the face flat, dimpled, or protruding. The parameters have the following meaning:
merge
object or a union
object. Set this to 1
(or some other non-zero value) if the button's texture will have some transparency, otherwise set it to 0
.The resulting button will fit entirely in the cylinder running from
pB
to pT
with a radius of rB
.To use the macro, place the call to the macro in an
object
and apply any desired texturing and transformations in that:object { RoundButton(<0, 0, 0>, <0, .25, 0>, .75, .03, -.02, 0) texture { pigment { red 1 } finish { ambient .1 diffuse .9 } } translate { ButtonTransform } }
This will produce a red button that is 1.5 units across, .25 units tall, with a slightly-rounded edge and a shallow dimple on the face.
ButtonTransform
will need to be defined in the preceding scripting so that the button can be placed however you need it.The chief value of this macro comes from the edge radius and bulge/dimple parameters, because they provide fire-and-forget support for the small but important details. We could use a simple
cylinder
object to model the button, but real-life push buttons don't have the infinitely-sharp edges that idealized cylinders do, and they often don't have perfectly flat faces, either. Modeling the most common details, and getting everything right so that there are no visible seams between the parts that make up the whole, takes a bit of math that can be easily automated in code.
Comments
Post a Comment