Notifications
Clear all

[Closed] How to make your own Timeline (NOT ENCRYPTED)

quick question… do you know what the trackviewnodes is and how to cook it?

3 Replies
(@denist)
Joined: 11 months ago

Posts: 0

do you not know? and you are not interested. that’s OK. we will follow what all other master classes say.

 MZ1
(@mz1)
Joined: 11 months ago

Posts: 0

i can see documentation here;
http://docs.autodesk.com/3DSMAX/15/ENU/MAXScript-Help/index.html?url=files/GUID-FA932DB0-738F-4A58-B49E-9A184064676C.htm,topicNumber=d30e592425
and i think trackviewnodes is root of nodes in trackview. what you mean by how to cook it?
i guess you want to:

  • create newTrackViewNode #hidden
  • addTrackViewController

and add data to this controller.yes?

(@denist)
Joined: 11 months ago

Posts: 0

we don’t need controller. we can add CA to the trackviewnode. also i am not sure that we have to make the node #hidden.

 MZ1

what is difference between trackViewNodes and globalTracks?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

they are both the system defined top-level nodes (MAXTVNode) but for different groups of Track View Nodes.

 MZ1

I’m not sure, but i think you want to use data storage like this:

if trackViewNodes.TimelineTV == undefined do
(
	newTrackViewNode "TimelineTV"

	CA = attributes TimelineData
	(
		rollout paramsRollout ""
		(
		)
		parameters main rollout:paramsRollout
		(
		)
	)
	custAttributes.add trackViewNodes.TimelineTV CA
) 
 MZ1

Denis, what is next?

i don’t have time to continue the project but till i have some we can think about the logic of our control work.
we know that:

global start can’t be bigger than anim range start

anim range has to be at least one frame less than anim end

global end can’t be less than anim end

so
what have we to do if the user sets values against these rules?
we have two choices:

limit the values and doesn’t allow to set anything out of the rules

push the other values to make them fit the rules (that’s how the Maya does do)

i want to hear your opinion and the reasons

Personally I would go with option 2 and push the other values.

I’ve had various instances where people would know how many frames their particular anim needs to be, but with a little bit of bad mental arithmetic they make their timelines a frame or two too short.

If they can simply set their start frame and then say ‘i need a 257 frame sequence’ then allowing the tool to figure out their end frame would be better than relying on them doing mental arithmetic would be better!

i like the variant #2… the reason? many years the Maya uses this logic and never had an idea to change it. Is it not a good reason?

so we will do the Undo/Redo system based on the logic #2. (confidentially, the logic #1 will be also used but later)

I removed everything that makes the debugging of the idea more complicated and we have a code:


try(destroydialog trackbarNavigatorLight) catch()

if isproperty rootnode #TrackbarNavigatorLightAttrib do custattributes.delete rootnode TrackbarNavigatorLightAttrib
gc()

if not isproperty rootnode #TrackbarNavigatorLightAttrib do
(
	TrackbarNavigatorLightAttrib = attributes "TrackbarNavigatorLightAttrib" attribID:#(0x1145de09, 0x1145de09)
	(
		local dialog
		parameters main
		(
			trackbarRange type:#point4 default:[0,0,100,1000] animatable:off
			on trackbarRange set val do if dialog != undefined do dialog.updateUI()
		)
	)
	custattributes.add rootnode TrackbarNavigatorLightAttrib
)

rollout trackbarNavigatorLight "Trackbar Navigator" width:327 height:24
(
	spinner sa_sp fieldwidth:50 range:[-1e9,1e9,0] type:#integer pos:[0,4]
	spinner sr_sp fieldwidth:50 range:[-1e9,1e9,0] type:#integer pos:[61,4]
	
	spinner er_sp fieldwidth:50 range:[-1e9,1e9,100] type:#integer pos:[200,4]
	spinner ea_sp fieldwidth:50 range:[-1e9,1e9,1000] type:#integer pos:[261,4]

	fn updateUI event:#custom = undo off
	(
		if (param = if isproperty rootnode #TrackbarNavigatorLightAttrib do rootnode) != undefined do
		(
			sr_sp.value = param.trackbarRange[2]
			er_sp.value = param.trackbarRange[3]
			sa_sp.value = param.trackbarRange[1]
			ea_sp.value = param.trackbarRange[4]
		)
	)
	fn setRange value: = undo on 
	(
		if value == unsupplied do value = [sa_sp.value, sr_sp.value, er_sp.value, ea_sp.value]
			
		if (param = if isproperty rootnode #TrackbarNavigatorLightAttrib do rootnode) != undefined do param.trackbarRange = value
	)
	
	on sr_sp entered arg can do if not can do 
	(
		sr = sr_sp.value
		sa = amin sa_sp.value sr
		er = amax er_sp.value (sr+1)
		ea = amax ea_sp.value sr
		
		setRange value:[sa, sr, er, ea]
	)
	on er_sp entered arg can do if not can do 
	(
		er = er_sp.value
		sr = amin sr_sp.value (er-1)
		sa = amin sa_sp.value sr
		ea = amax ea_sp.value sr
		
		setRange value:[sa, sr, er, ea]
	)
	on sa_sp entered arg can do if not can do 
	(
		sa = sa_sp.value
		sr = amax sr_sp.value sa
		er = amax er_sp.value (sr+1)
		ea = amax ea_sp.value sr
		
		setRange value:[sa, sr, er, ea]
	)
	on ea_sp entered arg can do if not can do 
	(
		ea = ea_sp.value
		er = amin er_sp.value ea
		sr = amin sr_sp.value (er-1)
		sa = amin sa_sp.value sr
		
		setRange value:[sa, sr, er, ea]
	)
	
	on trackbarNavigatorLight close do 
	(
	)
	on trackbarNavigatorLight open do 
	(
		updateUI()
	)
)
createdialog trackbarNavigatorLight style:#(#style_titlebar, #style_sysmenu)

rootnode.TrackbarNavigatorLightAttrib.dialog = trackbarNavigatorLight

I’m using here the CA added to rootnode. Why? Because most of resources show this solution. And it works. In my real code I do it safer way, but I will not share. I want to keep anything for myself that makes my code different than other.

did i miss anything?

do I have to explain why I use only the spinner entered event and not use the changed value event?

1 Reply
 MZ1
(@mz1)
Joined: 11 months ago

Posts: 0

changed Event, makes a lot of unneeded undo stack, but we need one stack.

i think spinner and scene undo stack are matched.

we can make an structure for all timeline data and update them in one stack.

also there is another trick as you see. In the parameter block of the CA I use only one parameter but the type of Point4. Why? that’s because in general case any value (global start, current start, current end, and global end) might touch another. So it’s better to have only one parameter change event than four.

what is the next? hmm…
are you really sure that we have to mix our timeline changes with any scene changing in the same undo/redo stack? do you have any idea how to organize the separate stack of timeline changes?

Page 7 / 8