[Bf-committers] 'Why armatures are so slow' Report

Nathan Vegdahl bf-committers@blender.org
Sat, 5 Jul 2003 14:45:04 -0700 (PDT)

Yay!  I got a chance to get online again!

   Anyway, one problem that I noticed is that if the target for an IKA chain is
beyond the range of that chain (i.e. further away from the chain's origin than
the sum of the lengths of the bones) it still calculates all the itterations
even though it's impossible for it to get within the thresh-hold distance. 
Calculating all of the itterations obviously results in a severe slow-down.
   This could be solved by making sure that the target is within the range of
the chain (internally while solving, at least; it could be invisible to the

--Nathan "Cessen" Vegdahl

--- Chris Want <cwant@ualberta.ca> wrote:
> This is a just a little bit of a brain dump(tm) to share my findings
> on the causes for slowness in the armature system.
> The main finding is that there is too much recalculation of poses
> and deformation/displist's at unnecessary times. It appears that
> the NaN programmers started working on a pose/constraint caching
> feature to alleiviate this, but it was not finished. Finishing this
> work and expanding on it will lead to a vast increase in the response
> time while animating characters.
> Anyways, here are some important parts of the code that influence the
> interactive speed:
> *** source/blender/blenkernel/intern/armature.c ********************
> - void where_is_bone1_time (Object *ob, Bone *bone, float ctime)
>    This function figures out where a bone is based on a pose
>    and constraints. The important speed up to note is that it
>    does very little work if (chan->flag & PCHAN_DONE) in which
>    case it just uses a cached matrix, which generally would be
>    the way to go if the armature isn't being modified (either
>    explicitely or implicitely via a constraint).
> *** source/blender/src/drawview.c **********************************
> - void drawview3d(void)
>    This function draws the scene you see in the 3D window
>    during every redraw. The big bottle neck here is this
>    little gem:
> 	/* Clear the constraint "done" flags */
> 	for (base = G.scene->base.first; base; base=base->next){
> 		clear_object_constraint_status(base->object);
> 	}
>    Remember the pose caching I talked about earlier? This function
>    makes it recalculate the matrix in the cache. Since this is
>    done every redraw things get sloooooooowhoa!
> *** source/blender/src/editarmature.c *****************************
> - void draw_armature(Object *ob)
>    This function draws the armature. The source of slowness
>    here is this stuff:
> #if 1   /* Activate if there are problems with action lag */
>                  apply_pose_armature(arm, ob->pose, 0);
>                  where_is_armature (ob);
> #endif
>    Remember where_is_bone1_time, which would recalculate poses if
>    they weren't cached? Well, that gets called for each bone through
>    the where_is_armature function.
> *** source/blender/src/drawobject.c ********************************
> - void draw_object(Base *base)
>    OK enough about armatures ... what about those objects that are
>    deformed by armatures? Well, they get recalculated every redraw
>    too!
> #if 1
> #ifdef __NLA
>                          /* Force a refresh of the display list if the 
> parent is an armature */
>                          if (ob->parent && ob->parent->type==OB_ARMATURE 
> && ob->partype==PARSKEL){
> #if 0                   /* Turn this on if there are problems with 
> deformation lag */
>                                  where_is_armature (ob->parent);
> #endif
>                                  if (ob != G.obedit)
>                                          makeDispList (ob);
>                          }
> #endif
> #endif
>    (man I hate comments/indenting that spans beyond 80 characters ... but
>    that's another story).
> ************************************************************************
> So what to do?
> Unfortunately, it turns out that the naive disabling of any of the bits
> of code above leads to a character that does not update/pose correctly.
> The 2 most important things to do to improve the system to prevent
> armature slowness are thus:
> 1) figure out when is the best time to recalculate a pose. This would
> include:
> - Frame changed
> - Enter pose mode
> - Exit pose mode
> - In the while loop in transform, i.e., 'g', 's', 'r' in pose mode... 
> and also
>    after you press esc in there.
> - The target of a constraint on the armature has changed
> - any others? (I noticed intrr added some code to clear constraints on
>    'set scenes' so some care will be needed).
> 2) figure out when the best time to recalculate the deformation of a
> child mesh of an armature. This would basically include all of the
> events listed above in 1), but with the added consideration that it
> must be in very good sync with the pose calculation to avoid lags.
> Anyways, through experimentation I have on my local source tree a system
> which has most of this stuff sorted out, with excellent interaction
> times, but occasionally gets a little out of sync between pose
> calculation, deformation calculation, and redraws. The interaction time
> while transform()-ing in posemode isn't great because I have it
> recalculating the whole armature as it goes through each cycle of the
> event loop, but that can be improved by making it only recalculate the
> bones that need it, and also by only recalculating when the mouse
> position changes.
> I will continue to experiment ...
> Chris
> P.S. On an only partially related note, it might be good to replace
> some code in drawview3d that is flagged as /* SILLY CODE!!!! */
> with a non-silly alternative... if the code is silly it means it's
> broken or poorly understood and it should be re-evaluated.
> _______________________________________________
> Bf-committers mailing list
> Bf-committers@blender.org
> http://www.blender.org/mailman/listinfo/bf-committers

Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!