Modding, Mission Design, and Coding > The Modding Workshop

Useful scripts for 3ds Max

(1/6) > >>

zookeeper:
I've written a few scripts to help myself perform some of the most tedious routines involved in setting up and converting models in Max. No reason to not share them, so here you go:

1. reset_Xform_on_selected.ms - this is for reseting xform on everything right before exporting the ship. Because reseting xform on an object messes up the transforms of its children, you'd usually have to either unlink everything, reset xform and then re-link everything, which can get really tedious. This script does that for you, so all you have to do is select everything and run the script.

2. setup_turret_vecs.ms - this is for setting up fvecs/uvecs. It has a notable limitation of not being able to handle angled turrets for which xform has already been reseted, but that doesn't bother me since I always take care to not do that in a working file.

3. scale_orbs_for_export.ms - this is for allowing you to easily setup subsystem/thruster orbs in Max. Instead of placing those points as dummies, place them as spheres with a size of your choosing. Then, before exporting run the script and it should scale each point so that they'll end up being the right size in PCS2. Note: reseting XForms must be done before running this script, not after.

4. old_turrets_to_spicious_style.ms - do you have turrets setup the old way and they won't work when imported in new PCS2 builds? Running this script should convert the old-style turret hierarchy to the one expected by Spicious's newer builds.

All are written on Max 2009; I think they'll work on somewhat earlier versions too, but I don't know for sure. I'm sure there's bugs and some things I've missed, so feel free to point those out, although I won't promise to fix any issues I don't myself find important. Don't forget to read the comments inside the script for more details of use.

Note: all of the scripts tend to act based on object names: for example, setup_turret_vecs assumes that all objects whose name matches *turret* (except those which match *turret*-arm* or *turret*-destroyed*) are indeed turret bases, and strange things are bound to happen if any other objects have names which match that.

Finally, if you've written or know of any other maxscripts which are useful for modders, post/link them here!

EDIT: reset_Xform_on_selected had a bug which caused the objects to not get linked back together - fixed.
EDIT2: reset_Xform_on_selected now resets only objects which are selected, whereas the previous version(s) reseted selected objects + all their children. It also now automatically collapses the stack of every reseted object.
EDIT3: setup-turret-vecs wasn't correctly inverting the third fvec component, leading to turrets firing in reverse, and it also didn't overwrite already existing properties as advertised. Both fixed.
EDIT4: reverted the bogus fvec fix mentioned above.

reset_Xform_on_selected.ms

--- Code: ----- This script resets xform on all selected nodes. The built-in reset xform
-- function is inadequate because it cannot handle linked objects correctly.
-- This script unlinks each object from its children first before reseting
-- its xform and then linking the children back.
--
-- NOTE: this script seems to sometimes not work on objects which have
-- an active subobject selection.

undo "Reset XForm on selected" on (
for obj in selection do (
children = #()

for child in obj.children do (
append children child
)

for child in children do (
child.parent = undefined
)

collapseStack obj
ResetXForm obj
collapseStack obj

if children.count >= 1 then (
for child in children do (
child.parent = obj
)
)
)
)

--- End code ---

setup-turret-vecs.ms

--- Code: ----- This script helps in setting up fvec/uvec values for turrets.
-- However, for angled turrets it'll only work as long as the turret
-- retains its rotation; if you've reseted xform on an angled turret
-- already, then its own rotation information has been lost and the
-- script no longer works right.
--
-- Instructions: select the turrets you wish to setup, run the script
-- and adjust the sliders until the fvec (green) points along the
-- direction of the barrels and uvec (blue) points directly upwards,
-- then hit "Apply".
--
-- IMPORTANT NOTE:
--
-- It's unlikely that you can setup all turrets at once; most likely
-- you'll have to do them in groups. The script uses the turret's
-- existing rotation as a starting point, and if the selection contains
-- turrets which have been rotated in different ways then the script
-- will "suggest" different kinds of fvecs/uvecs for them, in which
-- case you will simply have to setup them separately.

turrets = for turret in selection where ((matchPattern turret.name pattern:"*turret*") and (not matchPattern turret.name pattern:"*turret*-arm*") and (not matchPattern turret.name pattern:"*turret*-destroyed*")) collect turret

rollout turretVecSetup "FS2O Turret fvec/uvec setup" (
slider scale_helpers "Scale helpers" orient:#vertical type:#float range:[0,5,1] height:100

slider rot_x "Rotate X" orient:#horizontal type:#integer ticks:2 range:[0,3,0] width:100
slider rot_y "Rotate Y" orient:#horizontal type:#integer ticks:2 range:[0,3,0] width:100
slider rot_z "Rotate Z" orient:#horizontal type:#integer ticks:2 range:[0,3,0] width:100

button apply_btn "Apply"
button exit_btn "Exit"

fn update_helpers = (
for turret in turrets do (
fvec_helper = getnodebyname(turret.name + "_fvec_helper")
uvec_helper = getnodebyname(turret.name + "_uvec_helper")

uvec_helper.rotation = turret.rotation

in coordsys turret (
rotate uvec_helper (eulerangles (rot_x.value * 90) (rot_y.value * 90) (rot_z.value * 90))
)

uvec_helper.pos = turret.pos

in coordsys uvec_helper (
fvec_helper.rotation = uvec_helper.rotation
rotate fvec_helper (eulerangles 0 -90 0)
)
)
)

fn clean_up = (
for turret in turrets do (
fvec_helper = getnodebyname(turret.name + "_fvec_helper")
uvec_helper = getnodebyname(turret.name + "_uvec_helper")

if fvec_helper != undefined then delete fvec_helper
if uvec_helper != undefined then delete uvec_helper
)
)

on turretVecSetup open do (
for turret in turrets do (
fvec_helper = cylinder name:(turret.name + "_fvec_helper") radius:1 height:20 wirecolor:(color 0 255 0)
uvec_helper = cone name:(turret.name + "_uvec_helper") radius1:3 radius2:0 height:10 wirecolor:(color 0  0 255)
uvec_helper.rotation = turret.rotation

in coordsys turret (
fvec_helper.pos = [0,0,0]
uvec_helper.pos = [0,0,0]
)
)

update_helpers()
)

on turretVecSetup close do (
clean_up()
)

on scale_helpers changed val do (
for turret in turrets do (
fvec_helper = getnodebyname(turret.name + "_fvec_helper")
uvec_helper = getnodebyname(turret.name + "_uvec_helper")

in coordsys local (
ResetScale fvec_helper
ResetScale uvec_helper
fvec_helper.objectoffsetscale = [scale_helpers.value,scale_helpers.value,scale_helpers.value]
uvec_helper.objectoffsetscale = [scale_helpers.value,scale_helpers.value,scale_helpers.value]
)
)
)

on rot_x changed val do (
update_helpers()
)
on rot_y changed val do (
update_helpers()
)
on rot_z changed val do (
update_helpers()
)

on apply_btn pressed do (
overwrote_props = false

for turret in turrets do (
props = getUserPropBuffer turret

fvec_helper = getnodebyname(turret.name + "_fvec_helper")
uvec_helper = getnodebyname(turret.name + "_uvec_helper")

in coordsys uvec_helper (
fvec_helper.pos = [-10,0,0]
uvec_helper.pos = [0,0,10]
)

fvec = normalize -(turret.pos - fvec_helper.pos)
uvec = normalize -(turret.pos - uvec_helper.pos)

fvec.x = (formattedPrint fvec.x format:"2.3f") as float
fvec.y = (formattedPrint fvec.y format:"2.3f") as float
fvec.z = (formattedPrint fvec.z format:"2.3f") as float
uvec.x = (formattedPrint uvec.x format:"2.3f") as float
uvec.y = (formattedPrint uvec.y format:"2.3f") as float
uvec.z = (formattedPrint uvec.z format:"2.3f") as float

fvec_prop = "$fvec: " + fvec.x as string + "," + fvec.z as string + "," + fvec.y as string
uvec_prop = "$uvec: " + uvec.x as string + "," + uvec.z as string + "," + uvec.y as string

if (matchPattern props pattern:"*?vec*") then (
props = ""
overwrote_props = true

print (turret.name + " already had an fvec, uvec or both set, all old subobject properties overwritten!")
)

props += "\r\n" + fvec_prop + "\r\n" + uvec_prop + "\r\n"

setUserPropBuffer turret props

delete fvec_helper
delete uvec_helper
)

if overwrote_props then (
rollout props_overwritten_note "Subobject properties overwritten" (
label note1_lbl "All previous subobject properties of turrets which already had fvec/uvec set were overwritten."
label note2_lbl "Look in the maxscript listener to see a list of those turrets."
label note3_lbl "Undo is available."
button ok_btn "Ok"

on ok_btn pressed do (
destroyDialog props_overwritten_note
)
)

createDialog props_overwritten_note width:600 height:100
)
)

on exit_btn pressed do (
clean_up()

destroyDialog turretVecSetup
)
)

createDialog turretVecSetup

--- End code ---

scale_orbs_for_export.ms

--- Code: ---orbs= #()

for b in $bay* where (matchpattern b.name pattern:"*-*") do (
append orbs b
)

for p in $path* where (matchpattern p.name pattern:"*-*") do (
append orbs p
)

for s in $subsystem* do (
append orbs s
)

for t in $thruster* where not (matchpattern t.name pattern:"thrusters*") do (
append orbs t
)

for o in orbs do (
upscale = (o.max.x - o.min.x) / 2
downscale = 1 / (o.max.x - o.min.x)

scale o [downscale,downscale,downscale]

ResetScale o

scale o [upscale,upscale,upscale]
)

--- End code ---

old_turrets_to_spicious_style.ms

--- Code: ---for t in $turret* where not (matchpattern t.name pattern:"*-destroyed") and not (matchpattern t.name pattern:"*-arm") do (
for h in t.children where (matchpattern h.name pattern:"*helper*") do (
for a in t.children where (matchpattern a.name pattern:"*-arm") do (
h.parent = a
)

for f in h.children where (matchpattern f.name pattern:"*firepoints*") do (
f.name = substituteString f.name "firepoints" "multifirepoints"
)
)
)

--- End code ---

Scooby_Doo:
How far down the hierarchy does the reset xform script go? 

For turrets you need the parent (turret), it's child (helper), that childs child (firepoints) and that childs children (firepoint).  Same depth with the thrusters

zookeeper:

--- Quote from: Scooby_Doo on January 09, 2011, 04:50:07 am ---How far down the hierarchy does the reset xform script go? 

For turrets you need the parent (turret), it's child (helper), that childs child (firepoints) and that childs children (firepoint).  Same depth with the thrusters

--- End quote ---
It goes all the way: it applies to the selected objects and recursively to all their children, even to ones which aren't selected. Arguably it could be smarter than that and only reset the objects which are actually selected, but it's a bit more complicated to handle that way so I didn't do that (yet), as the intended use is a mass-reset of everything right before exporting the model.

EDIT: Looks like I was mistaken; it wasn't really any more complicated to do, so I've updated the first post with a version which only resets the selected objects and also collapses the stack so you don't have to do it manually.

The E:
Stickied due to usefulness

mjn.mixael:
yeah, these are pretty much awesome! Good work!  :yes:

Navigation

[0] Message Index

[#] Next page

Go to full version