[Closed] Getting a subanim from a value
I’ve got a script that’s returning something like this:
$teapot01.radius
What I want is to convert it and any other returning value expressions to their respective subanim forms. ie. $teapot01.baseobject[#radius]
How can I do that?
:¬/
No takers? OK…
Well, what I'm doing specifically is trying to extract the details of a script controller; trying to create the code that will create a target, object, constant or node variable in a script controller by extracting the information contained within it. The problem is however, that maxscript's commands for getting that info have a few holes in them.
For example, if I try to extract the info of a variable assigned to a controller on an object using .getobject, I get something like Controller:bezier_float. No detail on the object's name or where in the controller hierachy it is. So, I use the command .printDetails() which gives me a good array of stuff that I can sift through with string stream commands to get what I need.
But...
If that variable's target is the weight of a list controller, the result printed isn't correct.
For example, this is what's returned from .printDetails():
$Teapot01.pos.controller.X_Position.controller.weight.controller
When what it should be is:
$Teapot01.pos.controller.X_Position.controller.weight.weight__bezier_float.controller
How can I extract the specific controller that it is? Especially as in this example, both weights are called weight__bezier_float, how do you extract the index of the weights from the small amount of information given?
:¬/
Can you use some combination of
filterstring
exprForMAXObject
execute
?
Hmm, looks like a real head ache. Can you elaborate on what it is you are doing and why? Maybe there are other ways to go about it.
Dave: I just discovered exprForMAXObject for the .getObject stuff and that saves me a lot of stringstream searching through the .printDetails() result.
However, the same problem remains, how do I get the right weight controller/subanim?
Paul: What I’m doing is turning a rig into code. Rigging something by hand, then running the script to create a new script that when run, will rebuild the rig. I’ve got it to build objects, name them, link them, assign CAs, assign controllers and wire them. I can put script controllers on them but it fails when assigning variable targets and/or objects when they are list weights.
For example:
for i = 5 to obj.controller.numvariables() do
(
scriptVar = obj.controller.getName i
scriptTarget = exprForMAXObject (obj.controller.getTarget i)
format (objname + "_script.addTarget \"" + scriptVar + "\" " + scriptTarget + "
") to:ScriptFile
)
When it comes to list weights, the scriptTarget variable is returning:
blah.weight.controller
when it should return:
blah.weight.weight__bezier_float.controller
or better still:
blah.weights[1].controller
I could easily do some string replacing to turn “weight” into “weights[1]” but I can’t find the index number of the weight I should be using. It won’t always be 1.
Does that make sense?
What I would try is this:
[ol]
[li]Get your target controller as an object[/li][li]Create a recursive function that recurses through any object’s subanims[/li][li]Recurse through the object (as you have its name) building up the string as you go with name and index values, eg “$object.position.controller[2].controller”[/li][li]When your target == your iterator, you have your string![/li][/ol]Would that work? Probably not perfectly on instanced controllers, but you may be able to write checks for this.
Any good to ya?
Dave
Hi Chinwagon,
a way that’ i found to get the real string and avoid that bug is to use the string from the exprForMAXObject function, then loop in each of its controllers, and compare it to the controller gotten from the “getObject” function.
Here i made a try:
targetController=([b]scriptController[/b].getobject "[b]variable[/b]")
stringVal=exprForMAXObject targetController explicitNames:true
auxCtrl=execute stringVal
if auxCtrl==undefined then
(
--Here i copy the string without the ".controller" part
stringVal2=""
for i=1 to (stringval.count-11) do
(
append stringval2 stringval[i]
)
--get the number of weights and loop throught them
n=execute (stringval2+".count")
for i=1 to n do
(
--compare to the controller to find the right string
aux=(stringval2+"["+(i as string)+"].controller")
if (execute aux)==targetController then stringVal=aux
)
)
YIKES!, looked into that at one point and just ran away screaming. good on ya. That would be very handy to have.
OK, Here’s my take:
struct scriptExpr
(
expr = "",
function getSubAnims src trg path =
(
local sas = getSubAnimNames src
if sas != undefined do
(
for sa in sas do
(
local ctrl = src[sa].controller
local temp = path + "[#" + sa + "]"
if ctrl != undefined AND ctrl == trg then
(
-- success!
expr = temp + ".controller"
)
else(
-- failure
getSubAnims src[sa] trg temp
)
)
)
),
function get trg =
(
-- get the source object if unsupplied
local obj = exprformaxobject trg explicitNames:true
local src = execute (filterstring obj ".")[1]
-- recurse through src and attempt to find target controller
getSubAnims src trg ("$" + src.name)
-- return the final script path
expr
)
)
-- objects
trg = $.pos.controller[2].controller -- second controller in a position list
se = scriptExpr()
-- get the expression
expr = se.get trg
trg == (execute expr)
-- results
-- "$Teapot01[#transform][#position][#Pos_2].controller"
-- true
I was trying to make a standalone struct, but I was having a bit of trouble figuring out how to pass the final expression back up the recursion chain.
Still, this is an OK starting point. You may need to add checks to check for unique names, or use indices instead, but this proves the theory at least.
Hope that helps.
Dave