--MESH TRACE 0.3 BETA for MAX 3.x
-----------------------------------
--*Pick A Light Source
--*Pick a Floor Object
--*Select any number of Objects
--*To capture the Shadow on the current frame only, uncheck "Animation in Active Segment" 
--Use this for non-animated objects to reduce ASE file size if exporting.
--*Leave the "Animation..." button checked to capture the whole animation
--*Press the "MESHTRACE SELECTED" button
--*A mesh representation of the shadow for the current animation segment will be created.

--HINTS:
--*Use high res meshes for better results
--*Make sure the ray from the light source through every vertex of every object 
--intersects the Floor object....
------------------------------------

utility  MeshTracer "MeshTrace"
(


group "About..."
(
label mts_label01 "MeshTrace"
label mts_label02 "Version 0.3 Beta - 2/7/00"
label mts_label03 "(c) by Bobo's Rendert**ls"
label mts_label04 "http://gfxcentral.com/bobo"
)

fn check_for_light obj =
(
return_value = false
if superclassof obj == Light then return_value = true
return_value 
)

group "Light and Floor"
(
pickbutton pick_light "Pick Light Source" width:140 filter:check_for_light align:#center
pickbutton pick_floor "Pick Floor Mesh" width:140 enabled:false align:#center
)

button go_do "MESHTRACE SELECTED" width:140 height:30 enabled:false

on pick_light picked obj do
(
pick_light.text = obj.name
light_node = obj
pick_floor.enabled = true
)

on pick_floor picked obj do
(
pick_floor.text = obj.name
floor_node = obj
go_do.enabled = true

)


group "Animation Options"
(
checkbutton use_anim "Animation in Active Segment" width:144 checked:true align:#center
)

group"Shadow Options"
(
colorpicker shadow_color "Shadow Color" color:[0,0,0] align:#right
spinner opacity_value "Opacity %" range:[0,100,90] fieldwidth:40 
spinner shadow_offset "Shadow Offset" range:[-10,10,0.1] fieldwidth:40
checkbox d_sided "2-Sided Shadow Mesh" checked:true align:#right
)

on go_do pressed do
(
disableSceneRedraw()
cancel_yes = false

black_mat = standardmaterial diffuse:shadow_color.color opacitytype:1 twosided:d_sided.state shininess:0 shinestrength:0
black_mat.ambient=shadow_color.color 
black_mat.specular=shadow_color.color 

black_mat.opacity=opacity_value.value 

black_mat.name = "MT_ShadowMaterial"

obj_array = selection as array

m_s = edit_mesh ()
addmodifier floor_node m_s



for j = 1 to obj_array.count do
(
a = obj_array[j]
b = copy a
if superclassof b == geometryclass and classof b != targetobject then
( 

converttomesh b
animatevertex b #all
b.name = "MTS_" + obj_array[j].name
b.material = black_mat
animateVertex b #all

tn = targetobject ()
tp = targetcamera ()
tp.target = tn

if use_anim.checked then
(
anim_s = animationrange.start 
anim_e = animationrange.end 
)
else
(
anim_s = SliderTime
anim_e = SliderTime
)

for t = anim_s to anim_e do
(
sliderTime = t
c = copy a
converttomesh c
tp.pos = light_node.pos

for i = 1 to c.numverts do
(
vert1 = getvert c i

tn.pos = vert1
tp_ray = tp as ray

i_ray = intersectRay floor_node tp_ray
if i_ray != undefined then
(
new_vert_pos = i_ray.pos - (shadow_offset.value * tp_ray.dir)
addnewkey b[4][1][i].controller t
animate on 
(
last_key_index = numkeys b[4][1][i].controller
b[4][1][i].keys[last_key_index].value = (new_vert_pos - b.pos)
)
)
)--end i loop
delete c
gc ()

)--end t loop


delete tp

)--end if class
)--end j loop
deletemodifier floor_node m_s
enableSceneRedraw()
)--end on

)--end util
