Author Topic: Useful scripts for 3ds Max  (Read 43657 times)

0 Members and 1 Guest are viewing this topic.

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Useful scripts for 3ds Max
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: [Select]
-- 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
)
)
)
)

setup-turret-vecs.ms
Code: [Select]
-- 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

scale_orbs_for_export.ms
Code: [Select]
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]
)

old_turrets_to_spicious_style.ms
Code: [Select]
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"
)
)
)
« Last Edit: July 15, 2011, 04:52:13 pm by zookeeper »

 
Re: Useful scripts for 3ds Max
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
That's cool and ....disturbing at the same time o_o  - Vasudan Admiral

"Don't play games with me. You just killed someone I like, that is not a safe place to stand. I'm the Doctor. And you're in the biggest library in the universe. Look me up."

"Quick everyone out of the universe now!"

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: Useful scripts for 3ds Max
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
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.
« Last Edit: January 09, 2011, 06:15:27 am by zookeeper »

 

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Useful scripts for 3ds Max
Stickied due to usefulness
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: Useful scripts for 3ds Max
yeah, these are pretty much awesome! Good work!  :yes:
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline Kusanagi

  • A man, a van, a plan, Vanama!
  • 27
  • Enemy vessel captured
Re: Useful scripts for 3ds Max
Will these keep the orientation for firingpoints?
Cum historia
mutat valde Razgriz
revelat ipsum
primum daemon scelestus est.

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: Useful scripts for 3ds Max
Will these keep the orientation for firingpoints?

No, but it's worth noting that you don't need to set the firepoint normals in pcs2 if the turret has fvecs and uvecs set.

 

Offline Spicious

  • Master Chief John-158
  • 210
Re: Useful scripts for 3ds Max
The importer looks for a helper called vec* now. Try exporting something with uvec and fvec.

 

Offline Kusanagi

  • A man, a van, a plan, Vanama!
  • 27
  • Enemy vessel captured
Re: Useful scripts for 3ds Max
So let me see if I have this straight.

I have a few turrets that I need to add to a ship both blob and multiparts which are in their own separate MAX scenes so I can merge them into the existing scene.

For a blob turret, I would just import it, group it (with its three helpers) and move them to where they need to go with the angles. Ungroup, run the fvec/uvec script, and then run the reset xform script?

For multiparts, the process is the same?
Cum historia
mutat valde Razgriz
revelat ipsum
primum daemon scelestus est.

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: Useful scripts for 3ds Max
The importer looks for a helper called vec* now. Try exporting something with uvec and fvec.

So if a turret has a helper called vec* attached to it (does there need to be another helper in between?), the importer automatically creates fvecs and uvecs for the turret based on the rotation of the vec helper? That's a great feature.

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: Useful scripts for 3ds Max
So let me see if I have this straight.

I have a few turrets that I need to add to a ship both blob and multiparts which are in their own separate MAX scenes so I can merge them into the existing scene.

For a blob turret, I would just import it, group it (with its three helpers) and move them to where they need to go with the angles. Ungroup, run the fvec/uvec script, and then run the reset xform script?

For multiparts, the process is the same?

Well, yes, that's how it works for multiparts. I'm not sure how it is for blob turrets, but I think at some point a change was made which makes blob turrets use the uvec (if provided) as the firepoint normal instead of the one you can set in pcs2. If that's the case then yeah, you the same process works for blob turrets as well, although the fvec doesn't need to point in the right direction (since there isn't a right direction).

 
Re: Useful scripts for 3ds Max
You should also collapse the stack BEFORE doing a reset Xform.  If the stack isn't collapsed some odd things can happen that's irreversible.
That's cool and ....disturbing at the same time o_o  - Vasudan Admiral

"Don't play games with me. You just killed someone I like, that is not a safe place to stand. I'm the Doctor. And you're in the biggest library in the universe. Look me up."

"Quick everyone out of the universe now!"

 

Offline Kusanagi

  • A man, a van, a plan, Vanama!
  • 27
  • Enemy vessel captured
Re: Useful scripts for 3ds Max
There never was any stack on it, heh.

I think this goes back to you giving me a hand with the assault frigate and what a wonderful time we had with that, Scooby :P
Cum historia
mutat valde Razgriz
revelat ipsum
primum daemon scelestus est.

 
Re: Useful scripts for 3ds Max
Trust me... if the objects modifier stack isn't collapsed, you can get some nasty results when you least expect it (like when you forgot to save before hand LOL)

Edit: This i think is all you need to change
Code: [Select]
--print ("Reseting XForm on " + node.name)
collapseStack obj
ResetXForm obj
collapseStack obj
« Last Edit: January 10, 2011, 11:08:49 pm by Scooby_Doo »
That's cool and ....disturbing at the same time o_o  - Vasudan Admiral

"Don't play games with me. You just killed someone I like, that is not a safe place to stand. I'm the Doctor. And you're in the biggest library in the universe. Look me up."

"Quick everyone out of the universe now!"

 

Offline Spicious

  • Master Chief John-158
  • 210
Re: Useful scripts for 3ds Max
So if a turret has a helper called vec* attached to it (does there need to be another helper in between?), the importer automatically creates fvecs and uvecs for the turret based on the rotation of the vec helper? That's a great feature.
All helpers should be a child of the "helper" node.

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: Useful scripts for 3ds Max
Fixed two bugs in setup-turret-vecs.

EDIT: Sigh. The fvec bug wasn't a bug at all, I just thought so because the ship I was converting was facing backwards.
« Last Edit: January 11, 2011, 08:38:05 am by zookeeper »

 
Re: Useful scripts for 3ds Max
Lincks are deleted, can you repost them please?
$Formula: ( every-time
   ( has-time-elapsed "0" )
   ( Do-Nothing
   )
   ( send-message
      "#Dalek"
      "High"
      "Pro-crasti-nate"
   )
   )
)
+Name: Procratination
+Repeat Count: 99999999999
+Interval: 1

 
Re: Useful scripts for 3ds Max
Lincks are deleted, can you repost them please?

Agreed. I'm looking for the vector one
That's cool and ....disturbing at the same time o_o  - Vasudan Admiral

"Don't play games with me. You just killed someone I like, that is not a safe place to stand. I'm the Doctor. And you're in the biggest library in the universe. Look me up."

"Quick everyone out of the universe now!"

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: Useful scripts for 3ds Max
Oops, sorry. :ick: They're back now. Feel free to host them permanently somewhere and post a link here.

 
Re: Useful scripts for 3ds Max
How about this:

setup_turret_vecs.txt
Code: [Select]
-- 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

That's cool and ....disturbing at the same time o_o  - Vasudan Admiral

"Don't play games with me. You just killed someone I like, that is not a safe place to stand. I'm the Doctor. And you're in the biggest library in the universe. Look me up."

"Quick everyone out of the universe now!"