View Full Version : prob with loop assigned controllers instancing
joconnell 07-06-2005, 02:53 PM Heya Folks,
I'm working on a script to assign an array of controllers to an object by assigning the first controller in the array, then assigning a list controller, then finally running through the entries from 2 on in the array and assigning each to the available slots of the list controller
My problem is that if I do the loop as described above the controllers become instanced and the objects pop to a new position unexpectedly. If however I skip assigning the first array controller and directly put on the list controller it doesn't cause this problem.
Has anyone seen this before or know of the syntax to make each controller unique?
Here's a script that will make three bones, store them in an array and apply the function to them - it's set to work properly at the moment by not assigning the first controller, you'll see the three lines commented that cause my problem.
-- Make an array for our bones to feed into the freezetrans function
Bonearray = #()
b1 = bonesys.createbone [0,0,0] [50,0,0] [0,0,1]
append BoneArray b1
b2 = bonesys.createbone [50,0,0] [100,0,0] [0,0,1]
append BoneArray b2
b3 = bonesys.createbone [100,0,0] [150,0,0] [0,0,1]
append BoneArray b3
b2.parent = b1
b3.parent = b2
-- function name, object to apple the fn to, array of position controllers, array of rotation controllers, position controller to set active, rotation controller to set active
fn FreezeTrans obj ThePosContArray TheRotContArray ActivePosCont ActiveRotCont =
(
-- Set Up position lists - This works fine by keeping the objects original pos controller
obj.position.controller = position_list()
obj.position.controller.setname 1 ThePosContArray[1][2] as string
-- However, if I assign the first controller of the PosArray it instances all
-- other controllers from then on and makes the bones pop. Comment the above two lines and uncomment the three under
-- Commented to stop bones popping to another position
/*
obj.position.controller = ThePosContArray[1][1] -- Sets the default controller as the first cont in the array
obj.position.controller = position_list() -- Then assigns our list controller
obj.position.controller.setname 1 ThePosContArray[1][2] as string -- Names the first entry in the list controller
*/
-- Loop through other positions and assign controllers based on posarray count
if ThePosContArray.count > 1 then
(
for p = 2 to ThePosContArray.count do
(
obj.position.controller.available.controller = ThePosContArray[p][1]
obj.position.controller.setname p ThePosContArray[p][2] as string
)
)
obj.position.controller.SetActive ActivePosCont
-- do the same job with the rotations - I havent included the problems above as they're the same with rotations too
obj.rotation.controller = Rotation_list()
obj.rotation.controller.setname 1 TheRotContArray[1][2] as string
if TheRotContArray.count > 1 then
(
for r = 2 to TheRotContArray.count do
(
obj.rotation.controller.available.controller = TheRotContArray[r][1]
obj.rotation.controller.setname r TheRotContArray[r][2] as string
)
)
obj.Rotation.controller.SetActive ActiveRotCont
)
-- make an array with controller types and names to assign
TempPosArray = #(#(position_xyz(),"Frozen_Position"),#(position_xyz(),"Zero_Position"))
TempRotArray = #(#(Euler_xyz(),"Frozen_Rotation"),#(Euler_xyz(),"Splay_Rotation"),#(Euler_xyz(),"Linked_rotation"),#(Euler_xyz(),"Zero_rotation"))
for i = 1 to bonearray.count do
(
FreezeTrans bonearray[i] TempPosArray TempRotArray 2 4
)
Any ideas how to solve this?
Thanks again,
John
|
|
joconnell
07-06-2005, 02:56 PM
Oh and another thing,
If I don't use the loop method it seems to work fine (effectively this becomes fred ruffs freeze transform macro) but I'd like to have a more flexible function that can deal with any number of controllers.
Cheers,
John
marktsang
07-06-2005, 03:06 PM
hey john,
i havent talked to you for a while :) im busy making my website i have only glanced at it - ill get back to you in a few mins when i can check the script , im rendering at the moment
i would say the best way to deal with looping throught the lists is with a recursive function
i used it on a script i wrote that turns off all keyable attributes on objects even if they contain multiple nested list controlers
mark
marktsang
07-06-2005, 03:19 PM
hi john,
had a better look at it now -
it seems you are setting the pos list to all bones at once
joconnell
07-06-2005, 03:23 PM
Yeah I'm wondering if there's any way to do this during the loop rather than having to do something with getsubanims afterwards. The curious thing is why does it work if I skip the first entry in the loop? If I assign then first controller, then the list I get the problems. If I assign the list, then the first controller I get the same problem? The only way it works is to not bother with the first controller, assign the list directly and loop through from controller two onwards.
The Freeze transform script from fred ruff assigns two controllers manually whereas mine assigns the first one manually and loops from the second on which causes the problem. I'm fairly confused as to why this may be...
Hows the animation coming on?
marktsang
07-06-2005, 03:31 PM
im kindof confused as to what you are trying to achieve here - maybe i just dont get it or its overcomplicated -
what exactly do you want the script to do?
mark
joconnell
07-06-2005, 03:43 PM
Effectively a more flexible freeze transforms that drives its loops based on the count of the controllers in an array, rather than typing out the controller assignments by hand. It's pretty much a mass assigner for list controllers.
marktsang
07-06-2005, 03:46 PM
after reading it again you are actually applying instances of controller
look at the array
TempPosArray = #(#(position_xyz(),"Frozen_Position"),#(position_xyz(),"Zero_Position"))
eveytime you assing the element tempposarray(ThePosContArray in the function) you are assinging an instance
what i dont get is why you keep assinging the same element from the array - i have the scirpt doing what i think is expected now
but im not sure what you expect it to do - explain further and i will fix it for you
mark
marktsang
07-06-2005, 03:47 PM
so you want to freeze all the inital controllers in nested list controllers?
mark
marktsang
07-06-2005, 03:53 PM
ahhh - wow im slow today - ok i get what you trying to do
so
you want to
1. add a list controller
2. freeze ititial transform
3. (not sure about this one) add another list controller
4. inside the second list controller add all the controllers from the array
am i close?
mark
joconnell
07-06-2005, 03:54 PM
well, I want to keep the initial position as a controller and then add more controllers on top.
I wanted to have the flexibility of being able to assign any type of controller to the available slots of the list via the array entry rather than writing code manually but it seems to be problematic.
What I reckon is happening is that maxscript is making a controller object and then assigning the same controller object to all of my objects rather than making a unique controller assignment each time...
marktsang
07-06-2005, 04:03 PM
gimme a list of the controllers you are supposed to get in the position controller from running the script - its not too clear in the code .
eg
position:
-position xyz ("frozen positon")
-position xyz ("ititial position")
-position_list
----position Xyz ("position layer")
----Position_noise ("noise layer")
ec..
mark
joconnell
07-06-2005, 04:03 PM
In the current script I'm using I only have euler_xyz() controllers on the rotation and position_xyz() controllers on the pos and manually chaning the line
obj.position.available.controller = posarray[i][1]
to
obj.position.available.controller = position_xyz()
works with no issues - admittedly is means I lose the flexibility of being able to use arrays to assign the controller which is a shame. I'm thinking more and more that when I have my array with multiple position_xyz() values such as:
TempPosArray = #(#(position_xyz(),"Frozen_Position"),#(position_xyz(),"Zero_Position"))
it's treating both of the position_xyz() entries as on object, almost like a global variable.
Perhaps I'll have to store the position_xyz() as a string and have another function convert them into controller types after.
How terribly annoying!
marktsang
07-06-2005, 04:04 PM
i already told you above that naming the position_xyz() in the array is an instance every time you call that element
mark
hello
the syntax to make each controller unique?
I think you need to copy the controllers from your array to the objects and use the copy keyword.
If you just assign the controllers from your array to the objects there are always instances and are influencing each other.
I had a similiar issue once with materials and copy helped me a lot.
I hope, I didn't miss the point completely.
Georg
marktsang
07-06-2005, 04:06 PM
instaed of ploping in the controlly name write a simple case statement inside the fucntion that will pick out the controllers so you can still use it like you want to
of course you could also use copy
eg.. $.pos.controller = copy (mypostionarray[1][2])
mark
joconnell
07-06-2005, 04:09 PM
Ah okay - if we take an array that uses the following array on the rotation:
TempRotArray = #(#(Euler_xyz(),"Frozen_Rotation"),#(Euler_xyz(),"Splay_Rotation"),#(Euler_xyz(),"Linked_rotation"),#(Euler_xyz(),"Zero_rotation"))
we should end up with a rotation_list controller with four euler_xyz entries: frozen_rotation, Splay_rotation, Linked_rotation and zero_rotation
I reckon there is a problem with saving the euler_xyz into an array directly - they seem to act as instances of each other (the little swines.)
Even if I go back into the track view and manually make each controller unique, because they've already gotten values from the first controller and won't pop back to where they're supposed to be - I'd have to write a function that makes each controller unique and sets each axis value to 0 to undo the problem.
joconnell
07-06-2005, 04:10 PM
Thanks for that george - I'll add that right away and hopefully it'll sort it :)
marktsang
07-06-2005, 04:11 PM
john
I reckon there is a problem with saving the euler_xyz into an array directly - they seem to act as instances of each other (the little swines.)
this is expected behaviour -and very useful i might add too....
just look at my above post to remedy using copy key work or case statments
mark
joconnell
07-06-2005, 04:44 PM
Thanks a million george and mark - the copy option has done quite a bit of good in stopping the instancing, whats happening now though which shouldn't be a problem is that if I assign a controller via maxscript it's automatically set to a value of 0,0,0 so if I have an object that's currently at 100,100,100, it will pop back to 0,0,0 which is a tad shite - thankfully since the bas position and rotation controller will be the frozen one this isn't really a problem anymore - I could probably also save the previous pos or rot values and reapply them afterwards. (actually just checked and this works)
Here's the final function - theres a random pos in there that I used to check whether the first assigned pos controller defaulted to 0,0,0
-- Make an array for our bones to feed into the freezetrans function
Bonearray = #()
b1 = bonesys.createbone [0,0,0] [50,0,0] [0,0,1]
append BoneArray b1
b2 = bonesys.createbone [50,0,0] [100,0,0] [0,0,1]
append BoneArray b2
b3 = bonesys.createbone [100,0,0] [150,0,0] [0,0,1]
append BoneArray b3
b2.parent = b1
b3.parent = b2
b1.pos = random [-100,-100,-100] [100,100,100]
-- function name, object to apple the fn to, array of position controllers, array of rotation controllers, position controller to set active, rotation controller to set active
fn FreezeTrans obj ThePosContArray TheRotContArray ActivePosCont ActiveRotCont =
(
-- Set Up position lists - This works fine by keeping the objects original pos controller
--obj.position.controller = position_list()
--obj.position.controller.setname 1 ThePosContArray[1][2] as string
-- However, if I assign the first controller of the PosArray it instances all
-- other controllers from then on and makes the bones pop. Comment the above two lines and uncomment the three under
-- Commented to stop bones popping to another position
Temppos=obj.position
obj.position.controller = copy(ThePosContArray[1][1]) -- Sets the default controller as the first cont in the array
obj.position = temppos
obj.position.controller = position_list() -- Then assigns our list controller
obj.position.controller.setname 1 ThePosContArray[1][2] as string -- Names the first entry in the list controller
-- Loop through other positions and assign controllers based on posarray countr
if ThePosContArray.count > 1 then
(
for p = 2 to ThePosContArray.count do
(
obj.position.controller.available.controller = copy(ThePosContArray[p][1])
obj.position.controller.setname p ThePosContArray[p][2] as string
)
)
obj.position.controller.SetActive ActivePosCont
-- do the same job with the rotations - I havent included the problems above as they're the same with rotations too
obj.rotation.controller = copy(TheRotContArray[1][1])
obj.rotation.controller = Rotation_list()
obj.rotation.controller.setname 1 TheRotContArray[1][2] as string
if TheRotContArray.count > 1 then
(
for r = 2 to TheRotContArray.count do
(
obj.rotation.controller.available.controller = copy(TheRotContArray[r][1])
obj.rotation.controller.setname r TheRotContArray[r][2] as string
)
)
obj.Rotation.controller.SetActive ActiveRotCont
)
-- make an array with controller types and names to assign
TempPosArray = #(#(position_xyz(),"Frozen_Position"),#(position_xyz(),"Zero_Position"))
TempRotArray = #(#(Euler_xyz(),"Frozen_Rotation"),#(Euler_xyz(),"Splay_Rotation"),#(Euler_xyz(),"Linked_rotation"),#(Euler_xyz(),"Zero_rotation"))
for i = 1 to bonearray.count do
(
FreezeTrans bonearray[i] TempPosArray TempRotArray 2 4
)
Thanks again for saving my hair and sanity :)
marktsang
07-06-2005, 05:00 PM
john
assigning a controller through maxscript should be no different than through the GUI
it should hold its current position and should not pop to 0 0 0
i would say the reason why it seems to do this is becase you are copying the controllers from an instance (will also copy the default position held in that controller) that is why i suggested using case statements instead
mark
joconnell
07-06-2005, 07:24 PM
Yeah I'll do that now, the correction I did to retain position should be much faster but who knows what problems it'll cause later on.
P.s. sped past one of your posts in a block of three so missed the part about assigning instances - d'oh :)
marktsang
07-06-2005, 07:39 PM
:D glad i could help out in some small way
hope your keeping busy ;P
mark
CGTalk Moderation
07-06-2005, 07:39 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.