Help with smooth change of animation blend control effect changing

I’ve been working on my own animation interface in my fps project primarily so that I can use blending to better represent where a player is walking/aiming. To this end, I’ve created the following code:

def set_look(self, p: float):
    if p > 0:
        scale = p/85
        self.change_blend("idle", "torso", 1 - scale)
        self.change_blend("LookUp", "torso", scale)
    else:
        self.change_blend("idle", "torso", 1)
        self.change_blend("LookUp", "torso", 0)

where self.change_blend is:

def change_blend(self, name:str, part:str = 'modelroot', blend:float = 1):
    control = self.controls[part].find_anim(name)
    if blend != self.bundle.get_control_effect(control):
        self.bundle.set_control_effect(control, blend)

and then I call set_look whenever the player changes their view pitch. however, it seems that the end result does not smoothly interpolate between animations, as seen in this video. (Ignore the improperly placed models; I’m testing with a model from another project.)

Is there something I’m doing wrong that’s causing this laggy change in blend effect? Or is this an inherent limitation with panda3d?
I’ve considered using CLerpAnimEffectInterval, but since this is a online multiplayer project and animation blending will frequently need to be set at a specific ratio, I don’t really think it fits my exact needs…

Hmm… Could we perhaps see the code that generates new values of “p”, please? I’m wondering whether there isn’t perhaps an issue there–maybe a delta-time issue…

I’ll warn you now that this isn’t my actual code: I’ve moved the actual bits and pieces into one block for easier comprehensibility, but p is controlled more or less by this:

pointer = base.win.get_pointer(0)
if pointer.get_in_window():#Get mouse movement
    scSize = base.win.getProperties()
    xSize, ySize = scSize.get_x_size() // 2, scSize.get_y_size() // 2
    self._hRot, self._pRot = -((pointer.get_x() - xSize) // 3) * 0.7, -((pointer.get_y() - ySize) // 3) * 0.7
    base.win.movePointer(0, xSize, ySize)
if (self._pRot != 0) and (abs(self._rig.get_p() + self._pRot) <= 85):
    self._rig.set_p(self._rig, self._pRot)
self.model.set_look(self._rig.get_p())

I wouldn’t imagine that the problem is the value-setting code for p, considering that I’ve parented jack.egg to self._rig and that moves quite smoothly when looking up or down…

edit: Since this is a networked game, I should mention that I do have to implement this in such a way where the value of p can be set to an exact amount, rather than being interpolated.

Wait, this appears to be using integer division–could that not be the cause of the jerkiness? What happens if you use non-integer division? (i.e. Just " / 3", rather than " // 3".)

Well, I don’t remember why I started doing integer division and changing it didn’t crash the game, but somehow it feels like its even jerkier than before.

Aaaaand as I was writing this I actually remembered why I was doing integer division. It was based on a technique I read online for making fps camera movement feel smoother; it divides the screen into imaginary “cells”, and for each complete cell unit the mouse is away from the center of the window each frame, the camera is moved by that total times a mouse sensitivity scalar.

Oh Dear! I really should have considered more testing before…
Upon testing the animation blending on the client instance of the game, the animation blending is perfectly smooth! Something about my clientNetworkedPlayer class is causing set_look to be called inconsistently, thus causing the jagged movement. Thanks @Thaumaturge for trying to help regardless!

1 Like

Aaah, I’m glad that you managed to find the problem! :slight_smile:

Sometimes it really is something unexpected that causes an issue!

I think that I can sort of see how that might work: it would cause very small movements to be ignored, smoothing out some of the jitter of the input device and the person using it.

Fair enough!