Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2009 by the Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): Joshua Leung 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <stdlib.h> 00034 #include <string.h> 00035 #include <math.h> 00036 00037 #include "BLO_sys_types.h" 00038 00039 #include "DNA_anim_types.h" 00040 #include "DNA_armature_types.h" 00041 #include "DNA_scene_types.h" 00042 #include "DNA_screen_types.h" 00043 #include "DNA_view3d_types.h" 00044 #include "DNA_object_types.h" 00045 00046 #include "BLI_blenlib.h" 00047 #include "BLI_math.h" 00048 #include "BLI_dlrbTree.h" 00049 00050 #include "BKE_animsys.h" 00051 #include "BKE_action.h" 00052 00053 #include "BIF_gl.h" 00054 00055 #include "ED_armature.h" 00056 #include "ED_keyframes_draw.h" 00057 00058 #include "BLF_api.h" 00059 00060 #include "UI_resources.h" 00061 00062 #include "view3d_intern.h" 00063 00064 /* ************************************ Motion Paths ************************************* */ 00065 00066 // TODO: 00067 // - options to draw paths with lines 00068 // - include support for editing the path verts 00069 00070 /* Set up drawing environment for drawing motion paths */ 00071 void draw_motion_paths_init(View3D *v3d, ARegion *ar) 00072 { 00073 RegionView3D *rv3d= ar->regiondata; 00074 00075 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); 00076 00077 glPushMatrix(); 00078 glLoadMatrixf(rv3d->viewmat); 00079 } 00080 00081 /* Draw the given motion path for an Object or a Bone 00082 * - assumes that the viewport has already been initialised properly 00083 * i.e. draw_motion_paths_init() has been called 00084 */ 00085 void draw_motion_path_instance(Scene *scene, 00086 Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath) 00087 { 00088 //RegionView3D *rv3d= ar->regiondata; 00089 bMotionPathVert *mpv, *mpv_start; 00090 int i, stepsize= avs->path_step; 00091 int sfra, efra, len; 00092 00093 00094 /* get frame ranges */ 00095 if (avs->path_type == MOTIONPATH_TYPE_ACFRA) { 00096 int sind; 00097 00098 /* With "Around Current", we only choose frames from around 00099 * the current frame to draw. However, this range is still 00100 * restricted by the limits of the original path. 00101 */ 00102 sfra= CFRA - avs->path_bc; 00103 efra= CFRA + avs->path_ac; 00104 if (sfra < mpath->start_frame) sfra= mpath->start_frame; 00105 if (efra > mpath->end_frame) efra= mpath->end_frame; 00106 00107 len= efra - sfra; 00108 00109 sind= sfra - mpath->start_frame; 00110 mpv_start= (mpath->points + sind); 00111 } 00112 else { 00113 sfra= mpath->start_frame; 00114 efra = sfra + mpath->length; 00115 len = mpath->length; 00116 mpv_start= mpath->points; 00117 } 00118 00119 if(len <= 0) { 00120 return; 00121 } 00122 00123 /* draw curve-line of path */ 00124 glShadeModel(GL_SMOOTH); 00125 00126 glBegin(GL_LINE_STRIP); 00127 for (i=0, mpv=mpv_start; i < len; i++, mpv++) { 00128 short sel= (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT); 00129 float intensity; /* how faint */ 00130 00131 /* set color 00132 * - more intense for active/selected bones, less intense for unselected bones 00133 * - black for before current frame, green for current frame, blue for after current frame 00134 * - intensity decreases as distance from current frame increases 00135 */ 00136 #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min) 00137 if ((sfra+i) < CFRA) { 00138 /* black - before cfra */ 00139 if (sel) { 00140 // intensity= 0.5f; 00141 intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f); 00142 } 00143 else { 00144 //intensity= 0.8f; 00145 intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f); 00146 } 00147 UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity); 00148 } 00149 else if ((sfra+i) > CFRA) { 00150 /* blue - after cfra */ 00151 if (sel) { 00152 //intensity = 0.5f; 00153 intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f); 00154 } 00155 else { 00156 //intensity = 0.8f; 00157 intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f); 00158 } 00159 UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity); 00160 } 00161 else { 00162 /* green - on cfra */ 00163 if (sel) { 00164 intensity= 0.5f; 00165 } 00166 else { 00167 intensity= 0.99f; 00168 } 00169 UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10); 00170 } 00171 00172 /* draw a vertex with this color */ 00173 glVertex3fv(mpv->co); 00174 } 00175 00176 glEnd(); 00177 glShadeModel(GL_FLAT); 00178 00179 glPointSize(1.0); 00180 00181 /* draw little black point at each frame 00182 * NOTE: this is not really visible/noticable 00183 */ 00184 glBegin(GL_POINTS); 00185 for (i=0, mpv=mpv_start; i < len; i++, mpv++) 00186 glVertex3fv(mpv->co); 00187 glEnd(); 00188 00189 /* Draw little white dots at each framestep value */ 00190 UI_ThemeColor(TH_TEXT_HI); 00191 glBegin(GL_POINTS); 00192 for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize) 00193 glVertex3fv(mpv->co); 00194 glEnd(); 00195 00196 /* Draw big green dot where the current frame is */ 00197 // NOTE: only do this when drawing keyframes for now... 00198 if (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) { 00199 UI_ThemeColor(TH_CFRAME); 00200 glPointSize(6.0f); 00201 00202 glBegin(GL_POINTS); 00203 mpv = mpv_start + (CFRA - sfra); 00204 glVertex3fv(mpv->co); 00205 glEnd(); 00206 00207 glPointSize(1.0f); 00208 UI_ThemeColor(TH_TEXT_HI); 00209 } 00210 00211 // XXX, this isnt up to date but probably should be kept so. 00212 invert_m4_m4(ob->imat, ob->obmat); 00213 00214 /* Draw frame numbers at each framestep value */ 00215 if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) { 00216 unsigned char col[4]; 00217 UI_GetThemeColor3ubv(TH_TEXT_HI, col); 00218 col[3]= 255; 00219 00220 for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize) { 00221 char numstr[32]; 00222 float co[3]; 00223 00224 /* only draw framenum if several consecutive highlighted points don't occur on same point */ 00225 if (i == 0) { 00226 sprintf(numstr, "%d", (i+sfra)); 00227 mul_v3_m4v3(co, ob->imat, mpv->co); 00228 view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); 00229 } 00230 else if ((i > stepsize) && (i < len-stepsize)) { 00231 bMotionPathVert *mpvP = (mpv - stepsize); 00232 bMotionPathVert *mpvN = (mpv + stepsize); 00233 00234 if ((equals_v3v3(mpv->co, mpvP->co)==0) || (equals_v3v3(mpv->co, mpvN->co)==0)) { 00235 sprintf(numstr, "%d", (sfra+i)); 00236 mul_v3_m4v3(co, ob->imat, mpv->co); 00237 view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); 00238 } 00239 } 00240 } 00241 } 00242 00243 /* Keyframes - dots and numbers */ 00244 if (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) { 00245 unsigned char col[4]; 00246 00247 AnimData *adt= BKE_animdata_from_id(&ob->id); 00248 DLRBT_Tree keys; 00249 00250 /* build list of all keyframes in active action for object or pchan */ 00251 BLI_dlrbTree_init(&keys); 00252 00253 if (adt) { 00254 /* it is assumed that keyframes for bones are all grouped in a single group 00255 * unless an option is set to always use the whole action 00256 */ 00257 if ((pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT)==0) { 00258 bActionGroup *agrp= action_groups_find_named(adt->action, pchan->name); 00259 00260 if (agrp) { 00261 agroup_to_keylist(adt, agrp, &keys, NULL); 00262 BLI_dlrbTree_linkedlist_sync(&keys); 00263 } 00264 } 00265 else { 00266 action_to_keylist(adt, adt->action, &keys, NULL); 00267 BLI_dlrbTree_linkedlist_sync(&keys); 00268 } 00269 } 00270 00271 /* Draw slightly-larger yellow dots at each keyframe */ 00272 UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col); 00273 col[3]= 255; 00274 00275 glPointSize(4.0f); // XXX perhaps a bit too big 00276 glColor3ubv(col); 00277 00278 glBegin(GL_POINTS); 00279 for (i=0, mpv=mpv_start; i < len; i++, mpv++) { 00280 float mframe= (float)(sfra + i); 00281 00282 if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) 00283 glVertex3fv(mpv->co); 00284 } 00285 glEnd(); 00286 00287 glPointSize(1.0f); 00288 00289 /* Draw frame numbers of keyframes */ 00290 if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) { 00291 float co[3]; 00292 for (i=0, mpv=mpv_start; i < len; i++, mpv++) { 00293 float mframe= (float)(sfra + i); 00294 00295 if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) { 00296 char numstr[32]; 00297 00298 sprintf(numstr, "%d", (sfra+i)); 00299 mul_v3_m4v3(co, ob->imat, mpv->co); 00300 view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, col); 00301 } 00302 } 00303 } 00304 00305 BLI_dlrbTree_free(&keys); 00306 } 00307 } 00308 00309 /* Clean up drawing environment after drawing motion paths */ 00310 void draw_motion_paths_cleanup(View3D *v3d) 00311 { 00312 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); 00313 glPopMatrix(); 00314 }