Remove/Disable setControlEffect on a animation?

Hey, it has been a while, my first post of 2020, anyway I have a simple issue with blending, that is if a animation uses setControlEffect() when I attempt to unloadAnims() on it, the actor freaks out and stops animating to the point where to reverts back to the default blender3d pose.

I want to know what is happening and is it possible to unsetControlEffect on it? I guess this also brings up additional concerns for cleanup like what is being added or flagged to those animations that panda some how knows they were effected by setControlEffect. any help is appreciated, thanks.

Have you tried disabling blending when unloading animations?

1 Like

hmm, how do you do that? is it just disableBlend()?

Iā€™m honestly not sure. The manual seems to indicate as much, however.

it is saying one name, so I,m currently trying that right now.
EDIT: so it didnā€™t work, the name method gave.

TypeError: Arguments must match:
set_blend_type(const PartBundle self, int bt)

And when I left it blank, nothing happened, I,m still going to run some tests.

That error appears to relate to ā€œsetBlendTypeā€, not ā€œdisableBlendā€ā€“does it appear when you call the latter?

Sorry fell asleep, I donā€™t know what the error means, but I donā€™t get it when I leave the parentheses blank, so I assume it means you cannot enable/disable blend on a single animation (setting a string name to it), maybe enable/disable blend was designed purely for the actor as a whole and not itā€™s individual animations?

I mean, I have a poorer method that works, of recording animations loaded then not touching them until it is time to remove the entire node, but I have my concerns about this method such as what is the limit on the total animations a actor can have in Panda3d, and does removeNode() also remove seemingly this extra information caused by setControlEffect. (have to imagine it is some kind of weight data)

Could you show what code you called to trigger that error? It is hard for us to understand what is happening otherwise. I am curious whether there is a bug or whether you are simply passing in an incorrect parameter somewhere.

The correct way to remove the effects of setControlEffect is to call setControlEffect again, but pass in an effect value of 0.

What you might be seeing is that Panda3D automatically restores the actor to its default, unanimated pose when setting all control effects back to 0. If you do not want this behaviour, set this Config.prc variable:

restore-initial-pose false

If you set that to false, then Panda will instead keep the current pose when the last control-effect is removed.

what happened is I tried to enableBlend() and disableBlend() on a string or a single animation by name, basically it would be

actor.enableBlend("animation name")
actor.disableBlend("animation name")

I donā€™t think there is anything wrong with panda3d, me and Thaumaturge were testing to see what works, or how the disable and enable blend works.

EDIT: I did a setControlEffect of 0, even on animation that had no setControlEffect, and it give me the issue

EDIT2: is there way to set ā€œrestore-initial-poseā€ by python code instead of Config.prc?

Probably the right thing to do:

setControlEffect(0)

so pure zero? let me try that out, hold on.

EDIT: it gave a error stating it needed a effect,

proplst[pridx].setControlEffect(0) TypeError: setControlEffect() missing 1 required positional argument: 'effect'
from direct.showbase.ShowBase import ShowBase
from direct.actor.Actor import Actor

class RoamingRalphDemo(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.ralph = Actor("models/ralph", {"run": "models/ralph-run"})
        self.ralph.setScale(.2)
        self.ralph.loop('run')
        self.ralph.reparentTo(render)
        self.ralph.setControlEffect('run', 0)

demo = RoamingRalphDemo()
demo.run()
1 Like

yes, that was the original code I tried the first time.

prevAnim[pridx] = "Animation Name"
proplst[pridx].setControlEffect(prevAnim[pridx], 0)
proplst[pridx].disableBlend()
proplst[pridx].unloadAnims({prevAnim[pridx]})

For the record, unloadAnims() calls .clearControlEffects() on the underlying PartBundle, which is equivalent to calling setControlEffect(anim, 0) on every bound animation. So this is not the problem.

Did you try restore-initial-pose? What you can do to set it in Python code is this:

loadPrcFileData("", "restore-initial-pose false")

EDIT: I originally stated that disableBlend() calls clearControlEffects(), but I meant to say that unloadAnims() does so.

Is it possible to call a clearControlEffect() on a single animation? maybe Iā€™ll try that.

Yes, it is possible to disable control effects for a single animation. Itā€™s called setControlEffect(anim, 0). As I pointed out, however, unloadAnims() clears the control effects for all animations. So any other calls to setControlEffect are completely redundant.

Rather than continuing to try different methods that have slightly different semantics but do the same thing, maybe you could try the restore-initial-pose solution I suggested?

loadPrcFileData("", "restore-initial-pose false")

prevAnim[pridx] = "Animation Name"
proplst[pridx].unloadAnims([prevAnim[pridx]])

itā€™s just I,m a little touchy about the prc file since it might not translate well to the runtime releases, but Iā€™ll give it a go right now.

EDIT: gave me a error.

loadPrcFileData("", "restore-initial-pose false") NameError: name 'loadPrcFileData' is not defined

should I have put render in front of it? like render.loadPrcFileData

You should import it first:

from panda3d.core import loadPrcFileData

so I got it working, but the character stopped moving.

EDIT: hold on, Iā€™m going to try a trick.

EDIT2: the trick did not work, I attempted to call loadPrcFileData("", ā€œrestore-initial-pose trueā€) after the animation was unloaded but it restored the issue I had previous.

I wonder if this behaviour is working against you here? That calling unloadAnims() with a single animation is clearing the control effects for other animations?

Maybe, instead of unloadAnims, you could give this code a try, which does the same thing as unloadAnims but without clearing all the control effects:

prevAnim[pridx] = "Animation Name"
proplst[pridx].setControlEffect(prevAnim[pridx], 0.0)

cdict = proplst[pridx].getAnimControlDict()
lodNames = cdict.keys()
partNames = cdict[next(iter(lodNames))].keys()
for lodName in lodNames:
    for partName in partNames:
        animDef = cdict[lodName][partName].get(prevAnim[pridx])
        if animDef:
            animDef.animControl = None

EDIT: oops, corrected

2 Likes