[Closed] Sort camera's keys selection range on timeline
Hi Guys,
I am new in maxscript and last couple of days I tried to write this script. It should select all cameras in scene and sort their “animationkeys” selection range on timeline. It does not work properly, the result should move the first key of the camera (including cam.target’s keys) animation range right behind the previous camera last key and continue this way with next cameras. Sometimes I get small overlaps or holes between selection ranges of neighboring cameras.
here is the code:
–array of cameras
select $cam*
deselect $*target
cams = selection as array
Cnames = for i in selection collect i.name
sort Cnames
cams = for i in Cnames collect getNodeByName i–array of camera.targets
select $*target
deselect lights
targs = selection as array
Tnames = for i in selection collect i.name
sort Tnames
targs = for i in Tnames collect getNodeByName i–move camera’s to zero
for i = 1 to cams.count do
(
for j = i to i do
(
C = (getkeytime cams[i].pos.controller 1)
T = (getkeytime targs[j].pos.controller 1)
if C <= T then movekeys cams[i] -C else movekeys cams[i] -T
if C <= T then movekeys targs[i] -C else movekeys targs[i] -T
)
)–sort cameras in time
values = #()
for i = 1 to cams.count do
(
for j = i to i do
(
C = (getkeytime cams[i].pos.controller (numkeys cams[i].pos.controller))
T = (getkeytime targs[j].pos.controller (numkeys targs[j].pos.controller))
if C >= T then append values C else append values T
sum = 0
(
for i=1 to values.count do
(
sum = sum + values[i]
)
)
sum
movekeys cams[i] sum
movekeys targs[j] sum
)
)
movekeys cameras -values[1]
deselect cameras
could anybody help me please?
Thanks
Filip
Hi Filip,
Sorry – I don’t understand your question! Could you post a screenshot or something?
Thanks,
Dave
Here’s a script that (I think) does what you want. There’s no error checking whatsoever, it assumes the position controllers of both the camera and its target contain keys.
(
-- function to sort cameras by name
fn sortByName a b = stricmp a.name b.name
-- collect target cameras
local cams = for obj in cameras where classOf obj == Targetcamera collect obj
-- sort camera array by name
qSort cams sortByName
-- initial time
local curtime = 0f
with undo "Sort cams" on
(
-- iterate through cameras
for i = 1 to cams.count do
(
-- get camera+target position controllers
camctrl = cams[i].position.controller
trgctrl = cams[i].target.position.controller
-- get camera animation range
camtime_first = amin camctrl.keys[1].time trgctrl.keys[1].time
camtime_last = amax camctrl.keys[camctrl.keys.count].time trgctrl.keys[trgctrl.keys.count].time
camtime_length = camtime_last - camtime_first
-- number of frames to shift
movetime = -camtime_first + curtime
-- move keys for both the camera and its target
moveKeys camctrl movetime
moveKeys trgctrl movetime
-- first key time for next camera
curtime += camtime_length + 1
)
)
)
Hope this helps, if you have any questions regarding this script don’t hesitate to ask.
Martijn
Martijn,
It works great, exactly what I wanted;)
I’ve spent hard time with my own and it does not work well,
have to learn from your code!
I really appreciate it
Filip
I was tidying up an old camera script the other day, and it occurred to me halfway through that the thing to remember with cameras is that it’s only really the target property (on target cameras only) that makes them so different from normal objects.
With this in mind, for anything that will affect a camera, it’s worth putting any code that will affect the target in a conditional statement, and that way you build yourself a tool that isn’t exclusive to cameras.
Therefore you could have a rather nice (and general) “butt up all animation” tool at your disposal, that you could run on any objects.
Also, movekeys works on any child tracks as well, so you could affect the whole transform (rotations, etc).
Just a thought or two
Martijn,
I like your script, its elegant way (at least for me – beginner;)).
Could you explain me please this part of your code?
with undo “Sort cams” on
what does this exactly do?
Many Thanks
Filip
This line tells max to create an undo entry for the following codeblock.
If you run the following line:
with undo off box()
you’ll notice that there’s no undo entry added to the history.
with undo on
(
b = box()
addModifier b (uvwmap())
)
This creates a single undo entry for both actions. If you look up ‘undo’ in the reference, you’ll see that you can also specify a label for the undo entry that is being created. This does not work in all situations though (it will appear as “MAXScript” instead of the specified label), I’m not sure when or why this happens.
Martijn