PDA

View Full Version : My animation envelope issue



clintonman
08-31-2012, 06:20 PM
I just finished writing a couple of scripts to enhance/fix Collada file imports. I found that when setting animation for camera fov that the properties panel had to be open to make it work. So I added some code to open the panel. Is there a better way to do this? See the sample code below with envfov as the fov/zoom envelope for the camera:


env_func = lwsdk.LWEnvelopeFuncs()
item_info = lwsdk.LWItemInfo()
cameraItem = item_info.first(lwsdk.LWI_CAMERA, None)
while cameraItem:
cameraName = item_info.name(cameraItem)
if cameraName == colladaName:
ga.evaluate(ga.data, "SelectItem %s" % lwsdk.itemid_to_str(cameraItem))
group = item_info.chanGroup( cameraItem )
envfov = self.findEnv( group, "ZoomFactor" )
if not envfov:
ga.evaluate(ga.data, "SelectItem %s" % lwsdk.itemid_to_str(cameraItem))
ga.evaluate(ga.data, "AddEnvelope ZoomFactor")
envfov = self.findEnv( group, "ZoomFactor" )
if not envfov:
#assume item properties was not open
# the AddEnvelope and findEnv need the properties panel to be open
ga.evaluate(ga.data, "ItemProperties")
ga.evaluate(ga.data, "AddEnvelope ZoomFactor")
envfov = self.findEnv( group, "ZoomFactor" )


def findEnv( self, group, name ):
chan_info = lwsdk.LWChannelInfo()
chan = chan_info.nextChannel( group, None )
while chan:
if chan_info.channelName(chan) == name:
return chan_info.channelEnvelope( chan )
chan = chan_info.nextChannel( group, chan )

return None

The scripts are available here:
http://www.clintons3d.com/plugins/lightwave/index.html

The first script adds core extra tags to a collada file so Lightwave can see and read the spot lights. The second script reads the camera fov in x or y and light color and spotlight cone angle animations. There is also a preexisting script for adding Lightwave animations to exported Collada files.

skarloc
09-01-2012, 10:50 PM
I've not played around with camera animation, but I did have an issue with an object's animation. I'm note sure whether it applies - when you say it doesn't work, what doesn't work exactly? Is it the creation of the channel that doesn't work or is it creating the keys (judging by your code, I'd say the former).

My issue was with creating keys - I had a loop that was basically working out the movement of an object every X frames so it loops with a null, using a emporary null, setting it to 0,0,0 coordinates, unchecking ParentInPlace, setting temp_null's parent as the object, checking ParentInPlace, unparentling the temp_null, reading the X,Y,Z position of temp_null, then setting the first null's position to that (this was used to fire projectiles - the projectile must keep the moment of the firing object but not change with the firing object after firing when it moves). My problem was that ONE of the positional setting bit didn't work in the loop.

My work-around is to no longer store functions un variables, like in your first line of your code :


env_func = lwsdk.LWEnvelopeFuncs()

(Ironically, I don't see it being used, but it may be used elsewhere)

I'd replace all such uses - your function is a prime example :


def findEnv( self, group, name ):
chan_info = lwsdk.LWChannelInfo()
chan = chan_info.nextChannel( group, None )
while chan:
if chan_info.channelName(chan) == name:
return chan_info.channelEnvelope( chan )
chan = chan_info.nextChannel( group, chan )

return None

I'd replace by :


def findEnv( self, group, name ):
#~ chan_info = lwsdk.LWChannelInfo()
chan = lwsdk.LWChannelInfo().nextChannel( group, None )
while chan:
if lwsdk.LWChannelInfo().channelName(chan) == name:
return lwsdk.LWChannelInfo().channelEnvelope( chan )
chan = lwsdk.LWChannelInfo().nextChannel( group, chan )

return None

Now I have no idea why, when I did this to my problem, it worked (I can't see why it wouldn't work if you store the function in a variable - it's not as though the fnction changes!). You could try it out and see...

clintonman
09-02-2012, 09:45 AM
I've not played around with camera animation, but I did have an issue with an object's animation. I'm note sure whether it applies - when you say it doesn't work, what doesn't work exactly? Is it the creation of the channel that doesn't work or is it creating the keys (judging by your code, I'd say the former).

My issue was with creating keys - I had a loop that was basically working out the movement of an object every X frames so it loops with a null, using a emporary null, setting it to 0,0,0 coordinates, unchecking ParentInPlace, setting temp_null's parent as the object, checking ParentInPlace, unparentling the temp_null, reading the X,Y,Z position of temp_null, then setting the first null's position to that (this was used to fire projectiles - the projectile must keep the moment of the firing object but not change with the firing object after firing when it moves). My problem was that ONE of the positional setting bit didn't work in the loop.

My work-around is to no longer store functions un variables, like in your first line of your code :

Now I have no idea why, when I did this to my problem, it worked (I can't see why it wouldn't work if you store the function in a variable - it's not as though the fnction changes!). You could try it out and see...
I thought the problem was no channels, but it was no keys like you said. I made the changes you suggested, but it made no difference. I did find a slightly cleaner way to get good results. I thought that the properties panel had to be open for the envelope to be created and available for writing keys. It seems that the panel just has to be toggled. It's like some unseen thing gets updated and the envelope that was created becomes available to the script. I moved the ItemProperties command after the AddEnvelope command and that helps to clean up the code.




item_info = lwsdk.LWItemInfo()
cameraItem = item_info.first(lwsdk.LWI_CAMERA, None)
while cameraItem:
cameraName = item_info.name(cameraItem)
if cameraName == colladaName:
ga.evaluate(ga.data, "SelectItem %s" % lwsdk.itemid_to_str(cameraItem))
group = item_info.chanGroup( cameraItem )
envfov = self.findEnv( group, "ZoomFactor" )
if not envfov:
ga.evaluate(ga.data, "SelectItem %s" % lwsdk.itemid_to_str(cameraItem))
ga.evaluate(ga.data, "AddEnvelope ZoomFactor")
ga.evaluate(ga.data, "ItemProperties")
envfov = self.findEnv( group, "ZoomFactor" )

Parent in place sometimes needs the UpdateMotion command. Maybe you already know this, but it gave me some trouble in a previous script.

# /LightWave11.0/sdk/lwsdk11.0/html/commands/layout.html - UpdateMotion needed for parent in place
ga.evaluate(ga.data, 'UpdateMotion')
ga.evaluate(ga.data, "ParentItem %s" % lwsdk.itemid_to_str(joints[parentIndex].itemID))


UpdateMotion
Forces any deferred motion calculations to occur. When changing motion parameters such as position, any effects on the item or other items in the scene may be deferred until there is some spare time. This is done for improved interactivity. However, sometimes a script needs to have the motion fully updated before executing some other commands (for example, parenting in place after changing the position of an item). This command forces the motion to be updated before returning.

skarloc
09-02-2012, 10:32 AM
I'm sorry it didn't work for you. Have you tried creating a key througth the keySet function within the Envelope functions ? Note there's a but with keySet when you want to define the shape. But maybe creating a key this way then "allows" you to create other keys "normally" (I can't guarantee this - it's pure speculation).

I note you use ga.evaluate in your code. I, personally, use :


lwsdk.command("Position %f %f %f" % (x, y, z))

I find this provides neater code than ga.evaluate. IMHO.

clintonman
09-02-2012, 02:03 PM
I'm sorry it didn't work for you. Have you tried creating a key througth the keySet function within the Envelope functions ? Note there's a but with keySet when you want to define the shape. But maybe creating a key this way then "allows" you to create other keys "normally" (I can't guarantee this - it's pure speculation).

I note you use ga.evaluate in your code. I, personally, use :


lwsdk.command("Position %f %f %f" % (x, y, z))

I find this provides neater code than ga.evaluate. IMHO.

Actually, that is how I'm setting the keys. I just couldn't read the channel that was created to use in the create key and set key functions. It's all good now. I just had to add the one command before reading the channel.

lwsdk.command - it does look better and I'll be using it in the future now that I know it exists. Thanks for the tip.