diff options
-rw-r--r-- | release/scripts/ui/properties_data_bone.py | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_anim.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 161 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 9 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 28 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_action_types.h | 24 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_armature_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/makesrna.c | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_animviz.c | 350 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_pose.c | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 2 |
14 files changed, 578 insertions, 29 deletions
diff --git a/release/scripts/ui/properties_data_bone.py b/release/scripts/ui/properties_data_bone.py index e64b2e1a10d..d064b9a4897 100644 --- a/release/scripts/ui/properties_data_bone.py +++ b/release/scripts/ui/properties_data_bone.py @@ -227,7 +227,7 @@ class BONE_PT_display(BoneButtonsPanel): col.label(text="Custom Shape:") col.prop(pchan, "custom_shape", text="") if pchan.custom_shape: - col.prop_object(pchan, "custom_shape_transform", ob.pose, "bones", text="") + col.prop_object(pchan, "custom_shape_transform", ob.pose, "bones", text="At") class BONE_PT_inverse_kinematics(BoneButtonsPanel): diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index 5507a8b380e..4862f4e5c46 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -40,6 +40,7 @@ struct Scene; struct ListBase; struct bAnimVizSettings; struct bMotionPath; +struct bPoseChannel; #include "DNA_object_types.h" @@ -51,6 +52,9 @@ void animviz_settings_init(struct bAnimVizSettings *avs); void animviz_free_motionpath_cache(struct bMotionPath *mpath); void animviz_free_motionpath(struct bMotionPath *mpath); +struct bMotionPath *animviz_verify_motionpaths(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan); +void animviz_calc_motionpaths(struct Scene *scene, struct Object *ob); + /* ---------------------------------------------------- */ /* Curve Paths */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index a7d1ac10195..507fc520a85 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -44,6 +44,7 @@ #include "DNA_anim_types.h" #include "DNA_action_types.h" +#include "DNA_armature_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" #include "DNA_group_types.h" @@ -72,6 +73,7 @@ #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_particle.h" +#include "BKE_scene.h" #include "BKE_utildefines.h" #ifdef HAVE_CONFIG_H @@ -178,14 +180,21 @@ bMotionPath *animviz_verify_motionpaths(Scene *scene, Object *ob, bPoseChannel * dst= &ob->mpath; } - /* if there is already a motionpath, just return that... */ - // TODO: maybe we should validate the settings in this case - if (*dst != NULL) - return *dst; + /* if there is already a motionpath, just return that, + * but provided it's settings are ok + */ + if (*dst != NULL) { + mpath= *dst; - /* create a new motionpath, and assign it */ - mpath= MEM_callocN(sizeof(bMotionPath), "bMotionPath"); - *dst= mpath; + /* if range is not invalid, and/or length is set ok, just return */ + if ((mpath->start_frame != mpath->end_frame) && (mpath->length > 0)) + return mpath; + } + else { + /* create a new motionpath, and assign it */ + mpath= MEM_callocN(sizeof(bMotionPath), "bMotionPath"); + *dst= mpath; + } /* set settings from the viz settings */ mpath->start_frame= avs->path_sf; @@ -203,15 +212,151 @@ bMotionPath *animviz_verify_motionpaths(Scene *scene, Object *ob, bPoseChannel * return mpath; } +/* ------------------- */ + +/* Motion path needing to be baked (mpt) */ +typedef struct MPathTarget { + struct MPathTarget *next, *prev; + + bMotionPath *mpath; /* motion path in question */ + + Object *ob; /* source object */ + bPoseChannel *pchan; /* source posechannel (if applicable) */ +} MPathTarget; + +/* ........ */ + +/* get list of motion paths to be baked (assumes the list is ready to be used) */ +static void motionpaths_get_bake_targets(Object *ob, ListBase *targets) +{ + MPathTarget *mpt; + + /* object itself first */ + if ((ob->avs.recalc & ANIMVIZ_RECALC_PATHS) && (ob->mpath)) { + /* new target for object */ + mpt= MEM_callocN(sizeof(MPathTarget), "MPathTarget Ob"); + BLI_addtail(targets, mpt); + + mpt->mpath= ob->mpath; + mpt->ob= ob; + } + + /* bones */ + if ((ob->pose) && (ob->pose->avs.recalc & ANIMVIZ_RECALC_PATHS)) { + bArmature *arm= ob->data; + bPoseChannel *pchan; + + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if ((pchan->bone) && (arm->layer & pchan->bone->layer) && (pchan->mpath)) { + /* new target for bone */ + mpt= MEM_callocN(sizeof(MPathTarget), "MPathTarget PoseBone"); + BLI_addtail(targets, mpt); + + mpt->mpath= pchan->mpath; + mpt->ob= ob; + mpt->pchan= pchan; + } + } + } +} + +/* perform baking for the targets on the current frame */ +static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) +{ + MPathTarget *mpt; + + /* for each target, check if it can be baked on the current frame */ + for (mpt= targets->first; mpt; mpt= mpt->next) { + bMotionPath *mpath= mpt->mpath; + bMotionPathVert *mpv; + + /* current frame must be within the range the cache works for */ + if (IN_RANGE(CFRA, mpath->start_frame, mpath->end_frame) == 0) + continue; + + /* get the relevant cache vert to write to */ + mpv= mpath->points + (CFRA - mpath->start_frame); + + /* pose-channel or object path baking? */ + if (mpt->pchan) { + /* heads or tails */ + if (mpath->flag & MOTIONPATH_FLAG_BHEAD) { + VECCOPY(mpv->co, mpt->pchan->pose_head); + } + else { + VECCOPY(mpv->co, mpt->pchan->pose_tail); + } + + /* result must be in worldspace */ + mul_m4_v3(mpt->ob->obmat, mpv->co); + } + else { + /* worldspace object location */ + VECCOPY(mpv->co, mpt->ob->obmat[3]); + } + } +} + +/* ........ */ /* Perform baking of the given object's and/or its bones' transforms to motion paths * - scene: current scene * - ob: object whose flagged motionpaths should get calculated * - recalc: whether we need to */ +// TODO: include reports pointer? void animviz_calc_motionpaths(Scene *scene, Object *ob) { - + ListBase targets = {NULL, NULL}; + MPathTarget *mpt; + int sfra, efra; + int cfra; + + /* sanity checks */ + if (ob == NULL) + return; + + /* get motion paths to affect */ + motionpaths_get_bake_targets(ob, &targets); + + if (targets.first == NULL) + return; + + /* set frame values */ + cfra = CFRA; + sfra = efra = cfra; + + for (mpt= targets.first; mpt; mpt= mpt->next) { + /* try to increase area to do (only as much as needed) */ + sfra= MIN2(sfra, mpt->mpath->start_frame); + efra= MAX2(efra, mpt->mpath->end_frame); + } + if (efra <= sfra) return; + + /* calculate path over requested range */ + for (CFRA=sfra; CFRA<=efra; CFRA++) { + /* do all updates + * - if this is too slow, resort to using a more efficient way + * that doesn't force complete update, but for now, this is the + * most accurate way! + */ + scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive? + + /* perform baking for targets */ + motionpaths_calc_bake_targets(scene, &targets); + } + + /* reset original environment */ + CFRA= cfra; + scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive? + + // TODO: make an API call for this too? + ob->avs.recalc &= ~ANIMVIZ_RECALC_PATHS; + if (ob->pose) + ob->pose->avs.recalc &= ~ANIMVIZ_RECALC_PATHS; + + /* free temp data */ + BLI_freelistN(&targets); } /* ******************************************************************** */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index e86cfce6fd9..3ce77c8cb4f 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1734,9 +1734,16 @@ static float fcurve_eval_samples (FCurve *fcu, FPoint *fpts, float evaltime) cvalue= lastfpt->vec[1]; } else { + float t= (float)abs(evaltime - (int)evaltime); + /* find the one on the right frame (assume that these are spaced on 1-frame intervals) */ fpt= prevfpt + (int)(evaltime - prevfpt->vec[0]); - cvalue= fpt->vec[1]; + + /* if not exactly on the frame, perform linear interpolation with the next one */ + if (t != 0.0f) + cvalue= interpf(fpt->vec[1], (fpt+1)->vec[1], t); + else + cvalue= fpt->vec[1]; } /* return value */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6b4e0bef9bd..7b30ba603ac 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10339,33 +10339,37 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* initialise object defaults */ animviz_settings_init(&ob->avs); - /* if armature, copy settings for pose from armature data */ + /* if armature, copy settings for pose from armature data + * performing initialisation where appropriate + */ if (ob->pose && ob->data) { bArmature *arm= newlibadr(fd, lib, ob->data); if(arm) { /* XXX - why does this fail in some cases? */ bAnimVizSettings *avs= &ob->pose->avs; - + /* ghosting settings ---------------- */ /* ranges */ avs->ghost_bc= avs->ghost_ac= arm->ghostep; - + avs->ghost_sf= arm->ghostsf; avs->ghost_ef= arm->ghostef; - + /* type */ avs->ghost_type= arm->ghosttype; - + /* stepsize */ avs->ghost_step= arm->ghostsize; - + if (avs->ghost_step == 0) + avs->ghost_step= 1; + /* path settings --------------------- */ /* ranges */ avs->path_bc= arm->pathbc; avs->path_ac= arm->pathac; - + avs->path_sf= arm->pathsf; avs->path_ef= arm->pathef; - + /* flags */ if (arm->pathflag & ARM_PATH_FNUMS) avs->path_viewflag |= MOTIONPATH_VIEW_FNUMS; @@ -10373,17 +10377,19 @@ static void do_versions(FileData *fd, Library *lib, Main *main) avs->path_viewflag |= MOTIONPATH_VIEW_KFRAS; if (arm->pathflag & ARM_PATH_KFNOS) avs->path_viewflag |= MOTIONPATH_VIEW_KFNOS; - + /* bake flags */ if (arm->pathflag & ARM_PATH_HEADS) avs->path_bakeflag |= MOTIONPATH_BAKE_HEADS; - + /* type */ if (arm->pathflag & ARM_PATH_ACFRA) avs->path_type = MOTIONPATH_TYPE_ACFRA; - + /* stepsize */ avs->path_step= arm->pathsize; + if (avs->path_step == 0) + avs->path_step= 1; } } } diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index b6af91a9570..dbc715ba87f 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -90,10 +90,13 @@ typedef struct bAnimVizSettings { int ghost_sf, ghost_ef; /* start and end frames of ghost-drawing range (only used for GHOST_TYPE_RANGE) */ int ghost_bc, ghost_ac; /* number of frames before/after current frame to show */ - short ghost_type; /* eOnionSkinTypes */ + short ghost_type; /* eOnionSkin_Types */ short ghost_step; /* number of frames between each ghost shown (not for GHOST_TYPE_KEYS) */ - int pad; + short ghost_flag; /* eOnionSkin_Flag */ + + /* General Settings ------------------------ */ + short recalc; /* eAnimViz_RecalcFlags */ /* Motion Path Settings ------------------- */ short path_type; /* eMotionPath_Types */ @@ -107,16 +110,31 @@ typedef struct bAnimVizSettings { } bAnimVizSettings; +/* bAnimVizSettings->recalc */ +typedef enum eAnimViz_RecalcFlags { + /* motionpaths need recalculating */ + ANIMVIZ_RECALC_PATHS = (1<<0), +} eAnimViz_RecalcFlags; + + /* bAnimVizSettings->ghost_type */ typedef enum eOnionSkin_Types { + /* no ghosts at all */ + GHOST_TYPE_NONE = 0, /* around current frame */ - GHOST_TYPE_ACFRA = 0, + GHOST_TYPE_ACFRA, /* show ghosts within the specified frame range */ GHOST_TYPE_RANGE, /* show ghosts on keyframes within the specified range only */ GHOST_TYPE_KEYS, } eOnionSkin_Types; +/* bAnimVizSettings->ghost_flag */ +typedef enum eOnionSkin_Flag { + /* only show selected bones in ghosts */ + GHOST_FLAG_ONLYSEL = (1<<0), +} eOnionSkin_Flag; + /* bAnimVizSettings->path_type */ typedef enum eMotionPaths_Types { diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 1b0da09058a..010f210d5aa 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -117,7 +117,7 @@ typedef enum eArmature_Flag { ARM_AUTO_IK = (1<<9), ARM_NO_CUSTOM = (1<<10), /* made option negative, for backwards compat */ ARM_COL_CUSTOM = (1<<11), /* draw custom colours */ - ARM_GHOST_ONLYSEL = (1<<12), /* when ghosting, only show selected bones (this should belong to ghostflag instead) */ + ARM_GHOST_ONLYSEL = (1<<12), /* when ghosting, only show selected bones (this should belong to ghostflag instead) */ // XXX depreceated ARM_DS_EXPAND = (1<<13) } eArmature_Flag; diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 5697747fcab..efd42878087 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -52,6 +52,9 @@ extern StructRNA RNA_ActuatorSensor; extern StructRNA RNA_AlwaysSensor; extern StructRNA RNA_AndController; extern StructRNA RNA_AnimData; +extern StructRNA RNA_AnimViz; +extern StructRNA RNA_AnimVizOnionSkinning; +extern StructRNA RNA_AnimVizMotionPaths; extern StructRNA RNA_AnyType; extern StructRNA RNA_Area; extern StructRNA RNA_AreaLamp; @@ -305,6 +308,8 @@ extern StructRNA RNA_MirrorModifier; extern StructRNA RNA_Modifier; extern StructRNA RNA_MouseSensor; extern StructRNA RNA_MovieSequence; +extern StructRNA RNA_MotionPath; +extern StructRNA RNA_MotionPathVert; extern StructRNA RNA_MultiresModifier; extern StructRNA RNA_MusgraveTexture; extern StructRNA RNA_NandController; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 35515e76f48..aa7939c644f 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1996,6 +1996,7 @@ RNAProcessItem PROCESS_ITEMS[]= { {"rna_texture.c", NULL, RNA_def_texture}, {"rna_action.c", "rna_action_api.c", RNA_def_action}, {"rna_animation.c", "rna_animation_api.c", RNA_def_animation}, + {"rna_animviz.c", NULL, RNA_def_animviz}, {"rna_actuator.c", NULL, RNA_def_actuator}, {"rna_armature.c", "rna_armature_api.c", RNA_def_armature}, {"rna_boid.c", NULL, RNA_def_boid}, diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c new file mode 100644 index 00000000000..fda40f4436a --- /dev/null +++ b/source/blender/makesrna/intern/rna_animviz.c @@ -0,0 +1,350 @@ +/** + * $Id: rna_animation.c 25359 2009-12-14 12:09:20Z aligorith $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributor(s): Blender Foundation (2010), Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_types.h" +#include "RNA_enum_types.h" + +#include "rna_internal.h" + +#include "DNA_anim_types.h" +#include "DNA_action_types.h" +#include "DNA_scene_types.h" + +#include "MEM_guardedalloc.h" + +#include "WM_types.h" + +#ifdef RNA_RUNTIME + +static PointerRNA rna_AnimViz_onion_skinning_get(PointerRNA *ptr) +{ + return rna_pointer_inherit_refine(ptr, &RNA_AnimVizOnionSkinning, ptr->data); +} + +static PointerRNA rna_AnimViz_motion_paths_get(PointerRNA *ptr) +{ + return rna_pointer_inherit_refine(ptr, &RNA_AnimVizMotionPaths, ptr->data); +} + +static void rna_AnimViz_ghost_start_frame_set(PointerRNA *ptr, int value) +{ + bAnimVizSettings *data= (bAnimVizSettings*)ptr->data; + + CLAMP(value, 1, data->ghost_ef); + data->ghost_sf= value; +} + +static void rna_AnimViz_ghost_end_frame_set(PointerRNA *ptr, int value) +{ + bAnimVizSettings *data= (bAnimVizSettings*)ptr->data; + + CLAMP(value, data->ghost_sf, (int)(MAXFRAMEF/2)); + data->ghost_ef= value; +} + +static void rna_AnimViz_path_start_frame_set(PointerRNA *ptr, int value) +{ + bAnimVizSettings *data= (bAnimVizSettings*)ptr->data; + + CLAMP(value, 1, data->path_ef); + data->path_sf= value; +} + +static void rna_AnimViz_path_end_frame_set(PointerRNA *ptr, int value) +{ + bAnimVizSettings *data= (bAnimVizSettings*)ptr->data; + + CLAMP(value, data->path_sf, (int)(MAXFRAMEF/2)); + data->path_ef= value; +} + +#else + +void rna_def_motionpath_common(StructRNA *srna) +{ + PropertyRNA *prop; + + prop= RNA_def_property(srna, "motion_path", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "mpath"); + RNA_def_property_ui_text(prop, "Motion Path", "Motion Path for this element."); +} + +static void rna_def_animviz_motionpath_vert(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "MotionPathVert", NULL); + RNA_def_struct_sdna(srna, "bMotionPathVert"); + RNA_def_struct_ui_text(srna, "Motion Path Cache Point", "Cached location on path."); + + prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Coordinates", ""); + + prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOTIONPATH_VERT_SEL); + RNA_def_property_ui_text(prop, "Selected", "Path point is selected for editing."); +} + +static void rna_def_animviz_motion_path(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "MotionPath", NULL); + RNA_def_struct_sdna(srna, "bMotionPath"); + RNA_def_struct_ui_text(srna, "Motion Path", "Cache of the worldspace positions of an element over a frame range."); + + /* Collections */ + prop= RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "points", "length"); + RNA_def_property_struct_type(prop, "MotionPathVert"); + RNA_def_property_ui_text(prop, "Motion Path Points", "Cached positions per frame"); + + /* Playback Ranges */ + prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Start Frame", "Starting frame of the stored range."); + + prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_TIME); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "End Frame", "End frame of the stored range."); + + prop= RNA_def_property(srna, "length", PROP_INT, PROP_TIME); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Length", "Number of frames cached."); + + /* Settings */ + prop= RNA_def_property(srna, "use_bone_head", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOTIONPATH_FLAG_BHEAD); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); // xxx + RNA_def_property_ui_text(prop, "Use Bone Heads", "For PoseBone paths, use the bone head location when calculating this path."); + + prop= RNA_def_property(srna, "editing", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOTIONPATH_FLAG_EDIT); + RNA_def_property_ui_text(prop, "Edit Path", "Path is being edited."); +} + +/* --- */ + +static void rna_def_animviz_ghosts(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static const EnumPropertyItem prop_type_items[] = { + {GHOST_TYPE_NONE, "NONE", 0, "No Ghosts", "Don not show any ghosts"}, + {GHOST_TYPE_ACFRA, "CURRENT_FRAME", 0, "Around Current Frame", "Show ghosts from around the current frame"}, + {GHOST_TYPE_RANGE, "RANGE", 0, "In Range", "Show ghosts for the specified frame range"}, + {GHOST_TYPE_KEYS, "KEYS", 0, "On Keyframes", "Show ghosts on keyframes"}, + {0, NULL, 0, NULL, NULL}}; + + + srna= RNA_def_struct(brna, "AnimVizOnionSkinning", NULL); + RNA_def_struct_sdna(srna, "bAnimVizSettings"); + RNA_def_struct_nested(brna, srna, "AnimViz"); + RNA_def_struct_ui_text(srna, "Onion Skinning Settings", "Onion Skinning settings for animation visualisation."); + + /* Enums */ + prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "ghost_type"); + RNA_def_property_enum_items(prop, prop_type_items); + RNA_def_property_ui_text(prop, "Type", "Method used for determining what ghosts get drawn."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + /* Settings */ + prop= RNA_def_property(srna, "only_selected", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ghost_flag", GHOST_FLAG_ONLYSEL); + RNA_def_property_ui_text(prop, "On Selected Bones Only", "For Pose-Mode drawing, only draw ghosts for selected bones."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "frame_step", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "ghost_step"); + RNA_def_property_range(prop, 1, 20); + RNA_def_property_ui_text(prop, "Frame Step", "Number of frames between ghosts shown (not for 'On Keyframes' Onion-skining method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + /* Playback Ranges */ + prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME); + RNA_def_property_int_sdna(prop, NULL, "ghost_sf"); + RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_ghost_start_frame_set", NULL); + RNA_def_property_ui_text(prop, "Start Frame", "Starting frame of range of Ghosts to display (not for 'Around Current Frame' Onion-skinning method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_TIME); + RNA_def_property_int_sdna(prop, NULL, "ghost_ef"); + RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_ghost_end_frame_set", NULL); + RNA_def_property_ui_text(prop, "End Frame", "End frame of range of Ghosts to display (not for 'Around Current Frame' Onion-skinning method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + /* Around Current Ranges */ + prop= RNA_def_property(srna, "before_current", PROP_INT, PROP_TIME); + RNA_def_property_int_sdna(prop, NULL, "ghost_bc"); + RNA_def_property_range(prop, 0, 30); + RNA_def_property_ui_text(prop, "Before Current", "Number of frames to show before the current frame (only for 'Around Current Frame' Onion-skinning method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "after_current", PROP_INT, PROP_TIME); + RNA_def_property_int_sdna(prop, NULL, "ghost_ac"); + RNA_def_property_range(prop, 0, 30); + RNA_def_property_ui_text(prop, "After Current", "Number of frames to show after the current frame (only for 'Around Current Frame' Onion-skinning method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ +} + +static void rna_def_animviz_paths(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static const EnumPropertyItem prop_type_items[]= { + {MOTIONPATH_TYPE_RANGE, "RANGE", 0, "In Range", "Display Paths of poses within specified range."}, + {MOTIONPATH_TYPE_ACFRA, "CURRENT_FRAME", 0, "Around Frame", "Display Paths of poses within a fixed number of frames around the current frame."}, + {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem prop_location_items[]= { + {MOTIONPATH_BAKE_HEADS, "HEADS", 0, "Heads", "Calculate bone paths from heads"}, + {0, "TAILS", 0, "Tails", "Calculate bone paths from tails"}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "AnimVizMotionPaths", NULL); + RNA_def_struct_sdna(srna, "bAnimVizSettings"); + RNA_def_struct_nested(brna, srna, "AnimViz"); + RNA_def_struct_ui_text(srna, "Motion Path Settings", "Motion Path settings for animation visualisation."); + + /* Enums */ + prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "path_type"); + RNA_def_property_enum_items(prop, prop_type_items); + RNA_def_property_ui_text(prop, "Paths Type", "Type of range to show for Motion Paths"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "bake_location", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "path_bakeflag"); + RNA_def_property_enum_items(prop, prop_location_items); + RNA_def_property_ui_text(prop, "Bake Location", "When calculating Bone Paths, use Head or Tips"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + /* Settings */ + prop= RNA_def_property(srna, "show_frame_numbers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_FNUMS); + RNA_def_property_ui_text(prop, "Show Frame Numbers", "Show frame numbers on Motion Paths"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "highlight_keyframes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_KFRAS); + RNA_def_property_ui_text(prop, "Highlight Keyframes", "Emphasize position of keyframes on Motion Paths"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "show_keyframe_numbers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_KFNOS); + RNA_def_property_ui_text(prop, "Show Keyframe Numbers", "Show frame numbers of Keyframes on Motion Paths"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "frame_step", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "path_step"); + RNA_def_property_range(prop, 1, 100); + RNA_def_property_ui_text(prop, "Frame Step", "Number of frames between paths shown (not for 'On Keyframes' Onion-skining method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + + /* Playback Ranges */ + prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME); + RNA_def_property_int_sdna(prop, NULL, "path_sf"); + RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_path_start_frame_set", NULL); + RNA_def_property_ui_text(prop, "Start Frame", "Starting frame of range of paths to display/calculate (not for 'Around Current Frame' Onion-skinning method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_TIME); + RNA_def_property_int_sdna(prop, NULL, "path_ef"); + RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_path_end_frame_set", NULL); + RNA_def_property_ui_text(prop, "End Frame", "End frame of range of paths to display/calculate (not for 'Around Current Frame' Onion-skinning method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + /* Around Current Ranges */ + prop= RNA_def_property(srna, "before_current", PROP_INT, PROP_TIME); + RNA_def_property_int_sdna(prop, NULL, "path_bc"); + RNA_def_property_range(prop, 1, MAXFRAMEF/2); + RNA_def_property_ui_text(prop, "Before Current", "Number of frames to show before the current frame (only for 'Around Current Frame' Onion-skinning method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ + + prop= RNA_def_property(srna, "after_current", PROP_INT, PROP_TIME); + RNA_def_property_int_sdna(prop, NULL, "path_ac"); + RNA_def_property_range(prop, 1, MAXFRAMEF/2); + RNA_def_property_ui_text(prop, "After Current", "Number of frames to show after the current frame (only for 'Around Current Frame' Onion-skinning method)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */ +} + +/* --- */ + +void rna_def_animviz_common(StructRNA *srna) +{ + PropertyRNA *prop; + + prop= RNA_def_property(srna, "animation_visualisation", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "avs"); + RNA_def_property_ui_text(prop, "Animation Visualisation", "Animation data for this datablock."); +} + +static void rna_def_animviz(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "AnimViz", NULL); + RNA_def_struct_sdna(srna, "bAnimVizSettings"); + RNA_def_struct_ui_text(srna, "Animation Visualisation", "Settings for the visualisation of motion."); + + /* onion-skinning settings (nested struct) */ + prop= RNA_def_property(srna, "onion_skinning", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "AnimVizOnionSkinning"); + RNA_def_property_pointer_funcs(prop, "rna_AnimViz_onion_skinning_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Onion Skinning", "Onion Skinning (ghosting) settings for visualisation."); + + /* motion path settings (nested struct) */ + prop= RNA_def_property(srna, "motion_paths", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "AnimVizMotionPaths"); + RNA_def_property_pointer_funcs(prop, "rna_AnimViz_motion_paths_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Motion Paths", "Motion Path settings for visualisation."); +} + +/* --- */ + +void RNA_def_animviz(BlenderRNA *brna) +{ + rna_def_animviz(brna); + rna_def_animviz_ghosts(brna); + rna_def_animviz_paths(brna); + + rna_def_animviz_motion_path(brna); + rna_def_animviz_motionpath_vert(brna); +} + +#endif diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 22b8388f693..91443e8f9fa 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -118,6 +118,7 @@ extern BlenderRNA BLENDER_RNA; void RNA_def_ID(struct BlenderRNA *brna); void RNA_def_action(struct BlenderRNA *brna); void RNA_def_animation(struct BlenderRNA *brna); +void RNA_def_animviz(struct BlenderRNA *brna); void RNA_def_armature(struct BlenderRNA *brna); void RNA_def_actuator(struct BlenderRNA *brna); void RNA_def_boid(struct BlenderRNA *brna); @@ -175,6 +176,9 @@ void RNA_def_world(struct BlenderRNA *brna); void rna_def_animdata_common(struct StructRNA *srna); +void rna_def_animviz_common(struct StructRNA *srna); +void rna_def_motionpath_common(struct StructRNA *srna); + void rna_def_texmat_common(struct StructRNA *srna, const char *texspace_editable); void rna_def_mtex_common(struct StructRNA *srna, const char *begin, const char *activeget, const char *activeset, const char *structname, const char *update); void rna_def_render_layer_common(struct StructRNA *srna, int scene); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index e87edabbcdf..a1109e01d50 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1559,7 +1559,7 @@ static void rna_def_object(BlenderRNA *brna) * having a single one is better for Keyframing and other property-management situations... */ prop= RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE); - RNA_def_property_array(prop, 4); // TODO: maybe we'll need to define the 'default value' getter too... + RNA_def_property_array(prop, 4); RNA_def_property_float_funcs(prop, "rna_Object_rotation_axis_angle_get", "rna_Object_rotation_axis_angle_set", NULL); RNA_def_property_editable_array_func(prop, "rna_Object_rotation_4d_editable"); RNA_def_property_float_array_default(prop, default_axisAngle); @@ -1771,6 +1771,9 @@ static void rna_def_object(BlenderRNA *brna) /* anim */ rna_def_animdata_common(srna); + rna_def_animviz_common(srna); + rna_def_motionpath_common(srna); + /* duplicates */ prop= RNA_def_property(srna, "track_override_parent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_POWERTRACK); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index ff8f21028eb..b37442fab6a 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -693,6 +693,8 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Bone Paths Calculation End Frame", "End frame of range of frames to use for Bone Path calculations."); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); + rna_def_motionpath_common(srna); + /* Relationships to other bones */ prop= RNA_def_property(srna, "bone", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); @@ -1115,7 +1117,8 @@ static void rna_def_pose(BlenderRNA *brna) RNA_def_property_int_funcs(prop, "rna_Pose_active_bone_group_index_get", "rna_Pose_active_bone_group_index_set", "rna_Pose_active_bone_group_index_range"); RNA_def_property_ui_text(prop, "Active Bone Group Index", "Active index in bone groups array."); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); - + + /* ik solvers */ prop= RNA_def_property(srna, "ik_solver", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "iksolver"); RNA_def_property_enum_funcs(prop, NULL, "rna_Pose_ik_solver_set", NULL); @@ -1128,7 +1131,10 @@ static void rna_def_pose(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_Pose_ikparam_get", NULL, "rna_Pose_ikparam_typef"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "IK Param", "Parameters for IK solver."); - + + /* animviz */ + rna_def_animviz_common(srna); + /* RNA_api_pose(srna); */ } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 23a534562d0..35c8c7ac345 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1351,7 +1351,7 @@ static void rna_def_space_graph(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "mode"); RNA_def_property_enum_items(prop, mode_items); RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed."); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); // XXX need to be able to flush channel types /* display */ prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); |