armature ghost stepsize was not initialized, Aligorith: can you check this is correct?
[blender.git] / source / blender / editors / space_view3d / drawanimviz.c
1 /**
2  * $Id: drawanim.c 24637 2009-11-18 11:40:55Z campbellbarton $
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2009 by the Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Joshua Leung
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_anim_types.h"
41 #include "DNA_action_types.h"
42 #include "DNA_armature_types.h"
43 #include "DNA_constraint_types.h"
44 #include "DNA_ID.h"
45 #include "DNA_object_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_space_types.h"
49 #include "DNA_view3d_types.h"
50 #include "DNA_userdef_types.h"
51
52 #include "BLI_blenlib.h"
53 #include "BLI_math.h"
54 #include "BLI_dlrbTree.h"
55
56 #include "BKE_anim.h"
57 #include "BKE_animsys.h"
58 #include "BKE_action.h"
59 #include "BKE_armature.h"
60 #include "BKE_constraint.h"
61 #include "BKE_context.h"
62 #include "BKE_depsgraph.h"
63 #include "BKE_DerivedMesh.h"
64 #include "BKE_global.h"
65 #include "BKE_main.h"
66 #include "BKE_modifier.h"
67 #include "BKE_nla.h"
68 #include "BKE_object.h"
69 #include "BKE_utildefines.h"
70
71 #include "BIF_gl.h"
72 #include "BIF_glutil.h"
73
74 #include "ED_armature.h"
75 #include "ED_anim_api.h"
76 #include "ED_keyframes_draw.h"
77
78 #include "WM_api.h"
79 #include "WM_types.h"
80 #include "BLF_api.h"
81
82 #include "UI_resources.h"
83
84 #include "view3d_intern.h"
85
86 /* ************************************ Motion Paths ************************************* */
87
88 // TODO: 
89 //      - options to draw paths with lines
90 //      - include support for editing the path verts
91
92 /* Set up drawing environment for drawing motion paths */
93 void draw_motion_paths_init(Scene *scene, View3D *v3d, ARegion *ar) 
94 {
95         RegionView3D *rv3d= ar->regiondata;
96         
97         if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
98         
99         glPushMatrix();
100         glLoadMatrixf(rv3d->viewmat);
101 }
102
103 /* Draw the given motion path for an Object or a Bone 
104  *      - assumes that the viewport has already been initialised properly
105  *              i.e. draw_motion_paths_init() has been called
106  */
107 void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, 
108                         Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath)
109 {
110         //RegionView3D *rv3d= ar->regiondata;
111         bMotionPathVert *mpv, *mpv_start;
112         int sfra, efra, len;
113         int i, stepsize= avs->ghost_step;
114         
115         /* get frame ranges */
116         if (avs->path_type == MOTIONPATH_TYPE_ACFRA) {
117                 int sind;
118                 
119                 /* With "Around Current", we only choose frames from around 
120                  * the current frame to draw. However, this range is still 
121                  * restricted by the limits of the original path.
122                  */
123                 sfra= CFRA - avs->path_bc;
124                 efra= CFRA + avs->path_ac;
125                 if (sfra < mpath->start_frame) sfra= mpath->start_frame;
126                 if (efra > mpath->end_frame) efra= mpath->end_frame;
127                 
128                 len= efra - sfra;
129                 
130                 sind= sfra - mpath->start_frame;
131                 mpv_start= (mpath->points + sind);
132         }
133         else {
134                 sfra= mpath->start_frame;
135                 efra = sfra + mpath->length;
136                 len = mpath->length;
137                 mpv_start= mpath->points;
138         }
139         
140         /* draw curve-line of path */
141         glShadeModel(GL_SMOOTH);
142         
143         glBegin(GL_LINE_STRIP);                                 
144         for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
145                 short sel= (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
146                 float intensity; /* how faint */
147                 
148                 /* set color
149                  *      - more intense for active/selected bones, less intense for unselected bones
150                  *      - black for before current frame, green for current frame, blue for after current frame
151                  *      - intensity decreases as distance from current frame increases
152                  */
153                 #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min) 
154                 if ((sfra+i) < CFRA) {
155                         /* black - before cfra */
156                         if (sel) {
157                                 // intensity= 0.5f;
158                                 intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f);
159                         }
160                         else {
161                                 //intensity= 0.8f;
162                                 intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
163                         }
164                         UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
165                 }
166                 else if ((sfra+i) > CFRA) {
167                         /* blue - after cfra */
168                         if (sel) {
169                                 //intensity = 0.5f;
170                                 intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f);
171                         }
172                         else {
173                                 //intensity = 0.8f;
174                                 intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
175                         }
176                         UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
177                 }
178                 else {
179                         /* green - on cfra */
180                         if (sel) {
181                                 intensity= 0.5f;
182                         }
183                         else {
184                                 intensity= 0.99f;
185                         }
186                         UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
187                 }       
188                 
189                 /* draw a vertex with this color */ 
190                 glVertex3fv(mpv->co);
191         }
192         
193         glEnd();
194         glShadeModel(GL_FLAT);
195         
196         glPointSize(1.0);
197         
198         /* draw little black point at each frame
199          * NOTE: this is not really visible/noticable
200          */
201         glBegin(GL_POINTS);
202         for (i=0, mpv=mpv_start; i < len; i++, mpv++) 
203                 glVertex3fv(mpv->co);
204         glEnd();
205         
206         /* Draw little white dots at each framestep value */
207         UI_ThemeColor(TH_TEXT_HI);
208         glBegin(GL_POINTS);
209         for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize) 
210                 glVertex3fv(mpv->co);
211         glEnd();
212         
213         /* Draw frame numbers at each framestep value */
214         if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) {
215                 for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize) {
216                         char str[32];
217                         
218                         /* only draw framenum if several consecutive highlighted points don't occur on same point */
219                         if (i == 0) {
220                                 sprintf(str, "%d", (i+sfra));
221                                 view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
222                         }
223                         else if ((i > stepsize) && (i < len-stepsize)) { 
224                                 bMotionPathVert *mpvP = (mpv - stepsize);
225                                 bMotionPathVert *mpvN = (mpv + stepsize);
226                                 
227                                 if ((equals_v3v3(mpv->co, mpvP->co)==0) || (equals_v3v3(mpv->co, mpvN->co)==0)) {
228                                         sprintf(str, "%d", (sfra+i));
229                                         view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
230                                 }
231                         }
232                 }
233         }
234
235         /* Keyframes - dots and numbers */
236         if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) {
237                 AnimData *adt= BKE_animdata_from_id(&ob->id);
238                 DLRBT_Tree keys;
239                 
240                 /* build list of all keyframes in active action for object or pchan */
241                 BLI_dlrbTree_init(&keys);
242                 
243                 if (adt) {
244                         /* for now, it is assumed that keyframes for bones are all grouped in a single group */
245                         if (pchan) {
246                                 bActionGroup *agrp= action_groups_find_named(adt->action, pchan->name);
247                                 
248                                 if (agrp) {
249                                         agroup_to_keylist(adt, agrp, &keys, NULL);
250                                         BLI_dlrbTree_linkedlist_sync(&keys);
251                                 }
252                         }
253                         else {
254                                 action_to_keylist(adt, adt->action, &keys, NULL);
255                                 BLI_dlrbTree_linkedlist_sync(&keys);
256                         }
257                 }
258                 
259                 /* Draw slightly-larger yellow dots at each keyframe */
260                 UI_ThemeColor(TH_VERTEX_SELECT);
261                 glPointSize(4.0f); // XXX perhaps a bit too big
262                 
263                 glBegin(GL_POINTS);
264                 for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
265                         float mframe= (float)(sfra + i);
266                         
267                         if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
268                                 glVertex3fv(mpv->co);
269                 }
270                 glEnd();
271                 
272                 glPointSize(1.0f);
273                 
274                 /* Draw frame numbers of keyframes  */
275                 if (avs->path_viewflag & (MOTIONPATH_VIEW_FNUMS|MOTIONPATH_VIEW_KFNOS)) {
276                         for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
277                                 float mframe= (float)(sfra + i);
278                                 
279                                 if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
280                                         char str[32];
281                                         
282                                         sprintf(str, "%d", (sfra+i));
283                                         view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
284                                 }
285                         }
286                 }
287                 
288                 BLI_dlrbTree_free(&keys);
289         }
290 }
291
292 /* Clean up drawing environment after drawing motion paths */
293 void draw_motion_paths_cleanup(Scene *scene, View3D *v3d, ARegion *ar)
294 {
295         if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
296         glPopMatrix();
297 }
298
299 #if 0 // XXX temp file guards 
300
301 /* ***************************** Onion Skinning (Ghosts) ******************************** */
302
303 #if 0 // XXX only for bones
304 /* helper function for ghost drawing - sets/removes flags for temporarily 
305  * hiding unselected bones while drawing ghosts
306  */
307 static void ghost_poses_tag_unselected(Object *ob, short unset)
308 {
309         bArmature *arm= ob->data;
310         bPose *pose= ob->pose;
311         bPoseChannel *pchan;
312         
313         /* don't do anything if no hiding any bones */
314         if ((arm->flag & ARM_GHOST_ONLYSEL)==0)
315                 return;
316                 
317         /* loop over all pchans, adding/removing tags as appropriate */
318         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
319                 if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
320                         if (unset) {
321                                 /* remove tags from all pchans if cleaning up */
322                                 pchan->bone->flag &= ~BONE_HIDDEN_PG;
323                         }
324                         else {
325                                 /* set tags on unselected pchans only */
326                                 if ((pchan->bone->flag & BONE_SELECTED)==0)
327                                         pchan->bone->flag |= BONE_HIDDEN_PG;
328                         }
329                 }
330         }
331 }
332 #endif // XXX only for bones
333
334 /* draw ghosts that occur within a frame range 
335  *      note: object should be in posemode 
336  */
337 static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
338 {
339         Object *ob= base->object;
340         AnimData *adt= BKE_animdata_from_id(&ob->id);
341         bArmature *arm= ob->data;
342         bPose *posen, *poseo;
343         float start, end, stepsize, range, colfac;
344         int cfrao, flago, ipoflago;
345         
346         start = (float)arm->ghostsf;
347         end = (float)arm->ghostef;
348         if (end <= start)
349                 return;
350         
351         stepsize= (float)(arm->ghostsize);
352         range= (float)(end - start);
353         
354         /* store values */
355         ob->mode &= ~OB_MODE_POSE;
356         cfrao= CFRA;
357         flago= arm->flag;
358         arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
359         ipoflago= ob->ipoflag; 
360         ob->ipoflag |= OB_DISABLE_PATH;
361         
362         /* copy the pose */
363         poseo= ob->pose;
364         copy_pose(&posen, ob->pose, 1);
365         ob->pose= posen;
366         armature_rebuild_pose(ob, ob->data);    /* child pointers for IK */
367         ghost_poses_tag_unselected(ob, 0);              /* hide unselected bones if need be */
368         
369         glEnable(GL_BLEND);
370         if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
371         
372         /* draw from first frame of range to last */
373         for (CFRA= (int)start; CFRA < end; CFRA += (int)stepsize) {
374                 colfac = (end - (float)CFRA) / range;
375                 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
376                 
377                 BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
378                 where_is_pose(scene, ob);
379                 draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
380         }
381         glDisable(GL_BLEND);
382         if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
383
384         ghost_poses_tag_unselected(ob, 1);              /* unhide unselected bones if need be */
385         free_pose(posen);
386         
387         /* restore */
388         CFRA= cfrao;
389         ob->pose= poseo;
390         arm->flag= flago;
391         armature_rebuild_pose(ob, ob->data);
392         ob->mode |= OB_MODE_POSE;
393         ob->ipoflag= ipoflago; 
394 }
395
396 /* draw ghosts on keyframes in action within range 
397  *      - object should be in posemode 
398  */
399 static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
400 {
401         Object *ob= base->object;
402         AnimData *adt= BKE_animdata_from_id(&ob->id);
403         bAction *act= (adt) ? adt->action : NULL;
404         bArmature *arm= ob->data;
405         bPose *posen, *poseo;
406         DLRBT_Tree keys;
407         ActKeyColumn *ak, *akn;
408         float start, end, range, colfac, i;
409         int cfrao, flago;
410         
411         start = (float)arm->ghostsf;
412         end = (float)arm->ghostef;
413         if (end <= start)
414                 return;
415         
416         /* get keyframes - then clip to only within range */
417         BLI_dlrbTree_init(&keys);
418         action_to_keylist(adt, act, &keys, NULL);
419         BLI_dlrbTree_linkedlist_sync(&keys);
420         
421         range= 0;
422         for (ak= keys.first; ak; ak= akn) {
423                 akn= ak->next;
424                 
425                 if ((ak->cfra < start) || (ak->cfra > end))
426                         BLI_freelinkN((ListBase *)&keys, ak);
427                 else
428                         range++;
429         }
430         if (range == 0) return;
431         
432         /* store values */
433         ob->mode &= ~OB_MODE_POSE;
434         cfrao= CFRA;
435         flago= arm->flag;
436         arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
437         ob->ipoflag |= OB_DISABLE_PATH;
438         
439         /* copy the pose */
440         poseo= ob->pose;
441         copy_pose(&posen, ob->pose, 1);
442         ob->pose= posen;
443         armature_rebuild_pose(ob, ob->data);    /* child pointers for IK */
444         ghost_poses_tag_unselected(ob, 0);              /* hide unselected bones if need be */
445         
446         glEnable(GL_BLEND);
447         if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
448         
449         /* draw from first frame of range to last */
450         for (ak=keys.first, i=0; ak; ak=ak->next, i++) {
451                 colfac = i/range;
452                 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
453                 
454                 CFRA= (int)ak->cfra;
455                 
456                 BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
457                 where_is_pose(scene, ob);
458                 draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
459         }
460         glDisable(GL_BLEND);
461         if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
462
463         ghost_poses_tag_unselected(ob, 1);              /* unhide unselected bones if need be */
464         BLI_dlrbTree_free(&keys);
465         free_pose(posen);
466         
467         /* restore */
468         CFRA= cfrao;
469         ob->pose= poseo;
470         arm->flag= flago;
471         armature_rebuild_pose(ob, ob->data);
472         ob->mode |= OB_MODE_POSE;
473 }
474
475 /* draw ghosts around current frame
476  *      - object is supposed to be armature in posemode 
477  */
478 static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
479 {
480         Object *ob= base->object;
481         AnimData *adt= BKE_animdata_from_id(&ob->id);
482         bArmature *arm= ob->data;
483         bPose *posen, *poseo;
484         float cur, start, end, stepsize, range, colfac, actframe, ctime;
485         int cfrao, flago;
486         
487         /* pre conditions, get an action with sufficient frames */
488         if ELEM(NULL, adt, adt->action)
489                 return;
490
491         calc_action_range(adt->action, &start, &end, 0);
492         if (start == end)
493                 return;
494
495         stepsize= (float)(arm->ghostsize);
496         range= (float)(arm->ghostep)*stepsize + 0.5f;   /* plus half to make the for loop end correct */
497         
498         /* store values */
499         ob->mode &= ~OB_MODE_POSE;
500         cfrao= CFRA;
501         actframe= BKE_nla_tweakedit_remap(adt, (float)CFRA, 0);
502         flago= arm->flag;
503         arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
504         
505         /* copy the pose */
506         poseo= ob->pose;
507         copy_pose(&posen, ob->pose, 1);
508         ob->pose= posen;
509         armature_rebuild_pose(ob, ob->data);    /* child pointers for IK */
510         ghost_poses_tag_unselected(ob, 0);              /* hide unselected bones if need be */
511         
512         glEnable(GL_BLEND);
513         if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
514         
515         /* draw from darkest blend to lowest */
516         for(cur= stepsize; cur<range; cur+=stepsize) {
517                 ctime= cur - (float)fmod(cfrao, stepsize);      /* ensures consistant stepping */
518                 colfac= ctime/range;
519                 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
520                 
521                 /* only within action range */
522                 if (actframe+ctime >= start && actframe+ctime <= end) {
523                         CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe+ctime, NLATIME_CONVERT_MAP);
524                         
525                         if (CFRA != cfrao) {
526                                 BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
527                                 where_is_pose(scene, ob);
528                                 draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
529                         }
530                 }
531                 
532                 ctime= cur + (float)fmod((float)cfrao, stepsize) - stepsize+1.0f;       /* ensures consistant stepping */
533                 colfac= ctime/range;
534                 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
535                 
536                 /* only within action range */
537                 if ((actframe-ctime >= start) && (actframe-ctime <= end)) {
538                         CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe-ctime, NLATIME_CONVERT_MAP);
539                         
540                         if (CFRA != cfrao) {
541                                 BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
542                                 where_is_pose(scene, ob);
543                                 draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
544                         }
545                 }
546         }
547         glDisable(GL_BLEND);
548         if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
549
550         ghost_poses_tag_unselected(ob, 1);              /* unhide unselected bones if need be */
551         free_pose(posen);
552         
553         /* restore */
554         CFRA= cfrao;
555         ob->pose= poseo;
556         arm->flag= flago;
557         armature_rebuild_pose(ob, ob->data);
558         ob->mode |= OB_MODE_POSE;
559 }
560
561
562
563 #endif // XXX temp file guards