Help with logic of vector and matrix calculations in Poser

  • I'm working on a script which derives it's innermost logic from Ockham's Jiggles and FindAvDirs scripts, which perform analysis of a list of morphs to be used for simulating gravity effects, without going into the whole soft body dynamics regime. The scripts work quite effectively, determining the average displacement vector of each morph (the difference between the WorldVertex position of each vertex in the actor with, and without that morph applied at unit strength), returned as direction cosines and magnitude. The trouble is, both of those averaging calculations must be evaluated for every morph at every frame of an animation.

    It strikes me that the untransformed actor's geometry (averaged as a centroid or origin), and the averaged targetGeom deltas for that actor's morphs (as an averaged displacement vector from that origin) are pieces of static data which should only need to be evaluated once for the entire animation, if not for that figure, and thus could be stored in a preference file to save recalculation. The question that remains is: will it be sufficient to use those per-morph vectors (stored as direction cosines and magnitudes) and transform each once per animation frame via the actor's current WorldMatrix, to derive the transformed vector whose Y component is used to determine the strength with which that morph should be applied in that frame?

    At this point, I'm completely ignoring the effects of inertia and damping, as though the animation were a series of static poses. The script takes long enough to execute already (on the order of 18-20 minutes for 30 frames with 10 affected morphs), since it's current incarnation must take the precaution of removing all valueOperations from the morphs it uses, lest the calculations be corrupted by unexpected influences (like constraint morphs, whose valueOperations multiply the affected morph by zero), and then restore them afterwards, which takes time.

    It's my hope that precalculating the static direction cosines of the average morph vectors and then performing a single matrix transformation per morph, per frame will significantly speed up this process. Is there something I'm missing, like the WorldMatrix for an actor still needing to be pre-or-post-multiplied by the scale scalar of the figure (which can also be invisibly influenced by scaled constraint objects)?

  • [Thwack!@#*&^$] We distract your attention, dear reader, from the background rumblings and hurley-burley of self-castigation, to remind ourselves AGAIN, that some things are done for a reason. Just because the reason has been forgotten does not invalidate the process.

    [When facepalms go wrong!]

    Hmph! It seems that I have been labouring under a misapprehension. It is impossible to calculate the average displacement of a targetGeom which has no deltas, but instead controls a deformer via valueOperations! Thus, its effect cannot be predetermined, but must be evaluated by actually applying the deformer's influence to the vertices and seeing how much they move, on average, from their undeformed position at every frame. Even more so, since the deformers (in this particular case) get applied AFTER all the other morphs, so vertices may then be in a different position relative to the deformer falloff zone (no fixed, predefined weight maps in this case), and hence be displaced by a different amount for the same value of the deformer. D-X

    [Expletives deleted]

  • Well, another revelation, through necessary debugging.

    Has anyone noticed that in the animation palette, with a figure expanded to show it's actors, you can sometimes delete a block of keyframes, to the point where it appears the figure has no keys in a particular range, yet when you collapse the figure, it still shows there to be keys on those frames! Open the figure up and there's still nothing to see. Mysterious!

    Well, mystified no more. I have discovered, through dint of Python debugging while trying to find out why just such a figure was reporting that it's last frame was at the end of the scene's animation, despite not showing any keyframes for any of the visible actors. I had a loop which iterated over all of the figure's actors, like:

    for actor in figure.Actors():

    then cycling through frames until each actor reported no more keyframes beyond that frame (actor.NextKeyFrame() is None)
    As soon as I threw in a print statement to display the actor's name, up sprang the culprit FocusDistanceControl actor. This actor is normally hidden, and would not ordinarily be considered to be part of any specific figure, normally belonging to a camera. Yet in this scene, I actually have cameras parented to the figure's eyes, so I can render stereo images for 3D viewing. The FocusDistanceControl prop had keyframes on every frame, but was never visible in the animation palette.

    Now knowing that, I can at least test for, and ignore any actor whose IsControlProp() method returns True.