Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2010-01-01 15:24:16 +0300
committerJoshua Leung <aligorith@gmail.com>2010-01-01 15:24:16 +0300
commite6f26957ea56c7cfdaecd26e192a2ccbd1f6c97a (patch)
treebfe8aee1f6b75a64fe070feecda9ee5cc2f4eb62 /source
parent0b673d45e535fc59546631d2ffe602bd68aaba56 (diff)
Cleanup of MotionPaths+Ghosts (AnimViz) - Part 1
This commit sets up some of the groundwork necessary to extend the animation visualisation capabilities, previously only available for bones in PoseMode, to Objects as well. Also, some of the other goals of this refactor is to make future visualisation goodies (i.e. editable paths) more feasible... (There's really nothing to see here yet. The following log notes are really just for my own reference to keep track of things.) Currently, the following things have been done: * New datastructures + settings have been tidied up, ready for usage * Added these new types into the Object and PoseBone code as necessary, with freeing/adding/copying accounted for * File IO code for the new data, including version patching to convert the old system to the new one. * Set up the drawing system for motionpaths based on the old armature path drawing code. Armatures still draw using the old system, since the two systems use different storage systems. * Started setting up the motionpath 'baking' code, but the core of this still needs to be coded... Next Steps (after some semi-urgent Durian Driver changes): * Port the ghosting/onionskinning code over too * Finish motionpath baking code * RNA wrapping for the new types * Hooking up all the new code into the operators, etc.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_anim.h16
-rw-r--r--source/blender/blenkernel/intern/action.c37
-rw-r--r--source/blender/blenkernel/intern/anim.c184
-rw-r--r--source/blender/blenkernel/intern/object.c16
-rw-r--r--source/blender/blenloader/intern/readfile.c75
-rw-r--r--source/blender/blenloader/intern/writefile.c16
-rw-r--r--source/blender/editors/armature/poseobject.c1
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c563
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h12
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c4
-rw-r--r--source/blender/makesdna/DNA_action_types.h112
-rw-r--r--source/blender/makesdna/DNA_armature_types.h5
-rw-r--r--source/blender/makesdna/DNA_object_types.h7
13 files changed, 983 insertions, 65 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 32c5ff81740..5507a8b380e 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -38,14 +38,30 @@ struct Object;
struct PartEff;
struct Scene;
struct ListBase;
+struct bAnimVizSettings;
+struct bMotionPath;
#include "DNA_object_types.h"
+/* ---------------------------------------------------- */
+/* Animation Visualisation */
+
+void animviz_settings_init(struct bAnimVizSettings *avs);
+
+void animviz_free_motionpath_cache(struct bMotionPath *mpath);
+void animviz_free_motionpath(struct bMotionPath *mpath);
+
+/* ---------------------------------------------------- */
+/* Curve Paths */
+
void free_path(struct Path *path);
void calc_curvepath(struct Object *ob);
int interval_test(int min, int max, int p1, int cycl);
int where_on_path(struct Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius);
+/* ---------------------------------------------------- */
+/* Dupli-Geometry */
+
struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob);
void free_object_duplilist(struct ListBase *lb);
int count_duplilist(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 9e89ae77caa..a95cc7d1816 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -382,12 +382,12 @@ bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
if (ELEM(NULL, pose, name) || (name[0] == 0))
return NULL;
- return BLI_findstring(&pose->chanbase, name, offsetof(bPoseChannel, name));
+ return BLI_findstring(&((bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name));
}
/* Use with care, not on Armature poses but for temporal ones */
/* (currently used for action constraints and in rebuild_pose) */
-bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
+bPoseChannel *verify_pose_channel(bPose *pose, const char *name)
{
bPoseChannel *chan;
@@ -455,10 +455,10 @@ const char *get_ikparam_name(bPose *pose)
void copy_pose (bPose **dst, bPose *src, int copycon)
{
bPose *outPose;
- bPoseChannel *pchan;
+ bPoseChannel *pchan;
ListBase listb;
- if (!src){
+ if (!src) {
*dst=NULL;
return;
}
@@ -482,7 +482,8 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
if (copycon) {
copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb
pchan->constraints= listb;
- pchan->path= NULL;
+ pchan->path= NULL; // XXX remove this line when the new motionpaths are ready... (depreceated code)
+ pchan->mpath= NULL; /* motion paths should not get copied yet... */
}
if(pchan->prop) {
@@ -491,7 +492,7 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
}
/* for now, duplicate Bone Groups too when doing this */
- if(copycon)
+ if (copycon)
BLI_duplicatelist(&outPose->agroups, &src->agroups);
*dst=outPose;
@@ -532,12 +533,20 @@ void init_pose_ikparam(bPose *pose)
void free_pose_channel(bPoseChannel *pchan)
{
- if (pchan->path)
+ // XXX this case here will need to be removed when the new motionpaths are ready
+ if (pchan->path) {
MEM_freeN(pchan->path);
-
+ pchan->path= NULL;
+ }
+
+ if (pchan->mpath) {
+ animviz_free_motionpath(pchan->mpath);
+ pchan->mpath= NULL;
+ }
+
free_constraints(&pchan->constraints);
-
- if(pchan->prop) {
+
+ if (pchan->prop) {
IDP_FreeProperty(pchan->prop);
MEM_freeN(pchan->prop);
}
@@ -550,7 +559,7 @@ void free_pose_channels(bPose *pose)
if (pose->chanbase.first) {
for (pchan = pose->chanbase.first; pchan; pchan=pchan->next)
free_pose_channel(pchan);
-
+
BLI_freelistN(&pose->chanbase);
}
}
@@ -564,14 +573,14 @@ void free_pose(bPose *pose)
/* free pose-groups */
if (pose->agroups.first)
BLI_freelistN(&pose->agroups);
-
+
/* free IK solver state */
BIK_clear_data(pose);
-
+
/* free IK solver param */
if (pose->ikparam)
MEM_freeN(pose->ikparam);
-
+
/* free pose */
MEM_freeN(pose);
}
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 6b8b604cb94..a7d1ac10195 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -29,16 +29,21 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <stdio.h>
#include <math.h>
#include <string.h>
#include "MEM_guardedalloc.h"
+
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_math.h"
#include "BLI_rand.h"
+
#include "DNA_listBase.h"
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
#include "DNA_group_types.h"
@@ -53,6 +58,7 @@
#include "DNA_vfont_types.h"
#include "BKE_anim.h"
+#include "BKE_animsys.h"
#include "BKE_curve.h"
#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
@@ -60,7 +66,6 @@
#include "BKE_font.h"
#include "BKE_group.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
@@ -73,17 +78,157 @@
#include <config.h>
#endif
+// XXX bad level call...
#include "ED_mesh.h"
+/* --------------------- */
+/* forward declarations */
+
static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated);
+/* ******************************************************************** */
+/* Animation Visualisation */
+
+/* Initialise the default settings for animation visualisation */
+void animviz_settings_init(bAnimVizSettings *avs)
+{
+ /* sanity check */
+ if (avs == NULL)
+ return;
+
+ /* ghosting settings */
+ avs->ghost_bc= avs->ghost_ac= 10;
+
+ avs->ghost_sf= 1; // xxx - take from scene instead?
+ avs->ghost_ef= 250; // xxx - take from scene instead?
+
+ avs->ghost_step= 1;
+
+
+ /* path settings */
+ avs->path_bc= avs->path_ac= 10;
+
+ avs->path_sf= 1; // xxx - take from scene instead?
+ avs->path_ef= 250; // xxx - take from scene instead?
+
+ avs->path_viewflag= (MOTIONPATH_VIEW_KFRAS|MOTIONPATH_VIEW_KFNOS);
+
+ avs->path_step= 1;
+}
+
+/* ------------------- */
+
+/* Free the given motion path's cache */
+void animviz_free_motionpath_cache(bMotionPath *mpath)
+{
+ /* sanity check */
+ if (mpath == NULL)
+ return;
+
+ /* free the path if necessary */
+ if (mpath->points)
+ MEM_freeN(mpath->points);
+
+ /* reset the relevant parameters */
+ mpath->points= NULL;
+ mpath->length= 0;
+}
+
+/* Free the given motion path instance and its data
+ * NOTE: this frees the motion path given!
+ */
+void animviz_free_motionpath(bMotionPath *mpath)
+{
+ /* sanity check */
+ if (mpath == NULL)
+ return;
+
+ /* free the cache first */
+ animviz_free_motionpath_cache(mpath);
+
+ /* now the instance itself */
+ MEM_freeN(mpath);
+}
+
+/* ------------------- */
+
+/* Setup motion paths for the given data
+ * - scene: current scene (for frame ranges, etc.)
+ * - ob: object to add paths for (must be provided)
+ * - pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed)
+ */
+bMotionPath *animviz_verify_motionpaths(Scene *scene, Object *ob, bPoseChannel *pchan)
+{
+ bAnimVizSettings *avs;
+ bMotionPath *mpath, **dst;
+
+ /* sanity checks */
+ if (ELEM(NULL, scene, ob))
+ return NULL;
+
+ /* get destination data */
+ if (pchan) {
+ /* paths for posechannel - assume that posechannel belongs to the object */
+ avs= &ob->pose->avs;
+ dst= &pchan->mpath;
+ }
+ else {
+ /* paths for object */
+ avs= &ob->avs;
+ 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;
+
+ /* 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;
+ mpath->end_frame= avs->path_ef;
+
+ mpath->length= mpath->end_frame - mpath->start_frame;
+
+ if (avs->path_bakeflag & MOTIONPATH_BAKE_HEADS)
+ mpath->flag |= MOTIONPATH_FLAG_BHEAD;
+
+ /* allocate a cache */
+ mpath->points= MEM_callocN(sizeof(bMotionPathVert)*mpath->length, "bMotionPathVerts");
+
+ /* return it */
+ return mpath;
+}
+
+
+/* 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
+ */
+void animviz_calc_motionpaths(Scene *scene, Object *ob)
+{
+
+}
+
+/* ******************************************************************** */
+/* Curve Paths - for curve deforms and/or curve following */
+
+/* free curve path data
+ * NOTE: frees the path itself!
+ */
void free_path(Path *path)
{
if(path->data) MEM_freeN(path->data);
MEM_freeN(path);
}
-
+/* calculate a curve-deform path for a curve
+ * - only called from displist.c -> makeDispListCurveTypes
+ */
void calc_curvepath(Object *ob)
{
BevList *bl;
@@ -96,7 +241,6 @@ void calc_curvepath(Object *ob)
float fac, d=0, fac1, fac2;
int a, tot, cycl=0;
-
/* in a path vertices are with equal differences: path->len = number of verts */
/* NOW WITH BEVELCURVE!!! */
@@ -143,7 +287,7 @@ void calc_curvepath(Object *ob)
}
path->totdist= *fp;
-
+
/* the path verts in path->data */
/* now also with TILT value */
pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*4*path->len, "pathdata"); // XXX - why *4? - in 2.4x each element was 4 and the size was 16, so better leave for now - Campbell
@@ -155,7 +299,7 @@ void calc_curvepath(Object *ob)
maxdist= dist+tot;
fac= 1.0f/((float)path->len-1.0f);
fac = fac * path->totdist;
-
+
for(a=0; a<path->len; a++) {
d= ((float)a)*fac;
@@ -175,7 +319,7 @@ void calc_curvepath(Object *ob)
fac2= *(fp)-d;
fac1= fac2/fac1;
fac2= 1.0f-fac1;
-
+
interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa;
pp->radius= fac1*bevp->radius + fac2*bevpn->radius;
@@ -188,11 +332,12 @@ void calc_curvepath(Object *ob)
MEM_freeN(dist);
}
+
+/* is this only used internally?*/
int interval_test(int min, int max, int p1, int cycl)
{
-
if(cycl) {
- if( p1 < min)
+ if(p1 < min)
p1= ((p1 -min) % (max-min+1)) + max+1;
else if(p1 > max)
p1= ((p1 -min) % (max-min+1)) + min;
@@ -204,8 +349,11 @@ int interval_test(int min, int max, int p1, int cycl)
return p1;
}
-/* warning, *vec needs FOUR items! */
-/* ctime is normalized range <0-1> */
+
+/* calculate the deformation implied by the curve path at a given parametric position, and returns whether this operation succeeded
+ * - *vec needs FOUR items!
+ * - ctime is normalized range <0-1>
+ */
int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */
{
Curve *cu;
@@ -305,7 +453,8 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat,
return 1;
}
-/* ****************** DUPLICATOR ************** */
+/* ******************************************************************** */
+/* Dupli-Geometry */
static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated)
{
@@ -407,7 +556,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level,
enable_cu_speed= 1;
}
-struct vertexDupliData {
+typedef struct vertexDupliData {
ID *id; /* scene or group, for recursive loops */
int level;
int animated;
@@ -417,12 +566,14 @@ struct vertexDupliData {
Scene *scene;
Object *ob, *par;
float (*orco)[3];
-};
+} vertexDupliData;
+
+/* ------------- */
static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
DupliObject *dob;
- struct vertexDupliData *vdd= userData;
+ vertexDupliData *vdd= userData;
float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4];
VECCOPY(vec, co);
@@ -466,7 +617,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
Mesh *me= par->data;
Base *base = NULL;
DerivedMesh *dm;
- struct vertexDupliData vdd;
+ vertexDupliData vdd;
Scene *sce = NULL;
Group *group = NULL;
GroupObject * go = NULL;
@@ -1070,7 +1221,8 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, i
MEM_freeN(chartransdata);
}
-/* ***************************** */
+/* ------------- */
+
static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated)
{
if((ob->transflag & OB_DUPLI)==0)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 24d5b9cd882..55cea3de188 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -167,9 +167,9 @@ void object_free_particlesystems(Object *ob)
{
while(ob->particlesystem.first){
ParticleSystem *psys = ob->particlesystem.first;
-
+
BLI_remlink(&ob->particlesystem,psys);
-
+
psys_free(ob,psys);
}
}
@@ -194,9 +194,9 @@ void object_free_modifiers(Object *ob)
{
while (ob->modifiers.first) {
ModifierData *md = ob->modifiers.first;
-
+
BLI_remlink(&ob->modifiers, md);
-
+
modifier_free(md);
}
@@ -283,6 +283,8 @@ void free_object(Object *ob)
BLI_freelistN(&ob->defbase);
if(ob->pose)
free_pose(ob->pose);
+ if(ob->mpath)
+ animviz_free_motionpath(ob->mpath);
free_properties(&ob->prop);
object_free_modifiers(ob);
@@ -332,6 +334,7 @@ void unlink_object(Scene *scene, Object *ob)
unlink_actuators(&ob->actuators);
/* check all objects: parents en bevels and fields, also from libraries */
+ // FIXME: need to check all animation blocks (drivers)
obt= G.main->object.first;
while(obt) {
if(obt->proxy==ob)
@@ -982,7 +985,7 @@ Object *add_only_object(int type, char *name)
ob->quat[0]= ob->dquat[0]= 1.0f;
/* rotation locks should be 4D for 4 component rotations by default... */
ob->protectflag = OB_LOCK_ROT4D;
-
+
unit_m4(ob->constinv);
unit_m4(ob->parentinv);
unit_m4(ob->obmat);
@@ -1021,6 +1024,9 @@ Object *add_only_object(int type, char *name)
ob->fluidsimSettings = NULL;
ob->pc_ids.first = ob->pc_ids.last = NULL;
+
+ /* Animation Visualisation defaults */
+ animviz_settings_init(&ob->avs);
return ob;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index b99efc5be88..8f127fc65cf 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1981,6 +1981,19 @@ static void direct_link_animdata(FileData *fd, AnimData *adt)
adt->actstrip= NULL;
}
+/* ************ READ MOTION PATHS *************** */
+
+/* direct data for cache */
+static void direct_link_motionpath(FileData *fd, bMotionPath *mpath)
+{
+ /* sanity check */
+ if (mpath == NULL)
+ return;
+
+ /* relink points cache */
+ mpath->points= newdataadr(fd, mpath->points);
+}
+
/* ************ READ NODE TREE *************** */
/* singe node tree (also used for material/scene trees), ntree is not NULL */
@@ -3763,6 +3776,10 @@ static void direct_link_pose(FileData *fd, bPose *pose)
if (pchan->prop)
IDP_DirectLinkProperty(pchan->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ pchan->mpath= newdataadr(fd, pchan->mpath);
+ if (pchan->mpath)
+ direct_link_motionpath(fd, pchan->mpath);
+
pchan->iktree.first= pchan->iktree.last= NULL;
pchan->path= NULL;
}
@@ -3975,6 +3992,10 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->pose= newdataadr(fd, ob->pose);
direct_link_pose(fd, ob->pose);
+
+ ob->mpath= newdataadr(fd, ob->mpath);
+ if (ob->mpath)
+ direct_link_motionpath(fd, ob->mpath);
link_list(fd, &ob->defbase);
// XXX depreceated - old animation system <<<
@@ -10306,10 +10327,64 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (1) {
Scene *sce;
+ Object *ob;
+ /* game engine changes */
for(sce = main->scene.first; sce; sce = sce->id.next) {
sce->gm.eyeseparation = 0.10;
}
+
+ /* anim viz changes */
+ for (ob= main->object.first; ob; ob= ob->id.next) {
+ /* initialise object defaults */
+ animviz_settings_init(&ob->avs);
+
+ /* if armature, copy settings for pose from armature data */
+ if (ob->pose && ob->data) {
+ bArmature *arm= (bArmature *)ob->data;
+ 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;
+
+ /* 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;
+ if (arm->pathflag & ARM_PATH_KFRAS)
+ 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;
+ }
+ }
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index d60d65f81c2..3373cc1ca71 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1058,6 +1058,19 @@ static void write_animdata(WriteData *wd, AnimData *adt)
write_nladata(wd, &adt->nla_tracks);
}
+static void write_motionpath(WriteData *wd, bMotionPath *mpath)
+{
+ /* sanity checks */
+ if (mpath == NULL)
+ return;
+
+ /* firstly, just write the motionpath struct */
+ writestruct(wd, DATA, "bMotionPath", 1, mpath);
+
+ /* now write the array of data */
+ writestruct(wd, DATA, "bMotionPathVert", mpath->length, mpath->points);
+}
+
static void write_constraints(WriteData *wd, ListBase *conlist)
{
bConstraint *con;
@@ -1120,6 +1133,8 @@ static void write_pose(WriteData *wd, bPose *pose)
write_constraints(wd, &chan->constraints);
+ write_motionpath(wd, chan->mpath);
+
/* prevent crashes with autosave, when a bone duplicated in editmode has not yet been assigned to its posechannel */
if (chan->bone)
chan->selectflag= chan->bone->flag & BONE_SELECTED; /* gets restored on read, for library armatures */
@@ -1252,6 +1267,7 @@ static void write_objects(WriteData *wd, ListBase *idbase)
write_pose(wd, ob->pose);
write_defgroups(wd, &ob->defbase);
write_constraints(wd, &ob->constraints);
+ write_motionpath(wd, ob->mpath);
writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
writestruct(wd, DATA, "SoftBody", 1, ob->soft);
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index aeb42142abd..df5f551fb0c 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -227,6 +227,7 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
if (pchan->path) {
/* if the pathsf and pathef aren't initialised, abort! */
+ // XXX can now have negative frames, so this check needs improvement
if (ELEM(0, pchan->pathsf, pchan->pathef))
return;
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
new file mode 100644
index 00000000000..c999de92ea2
--- /dev/null
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -0,0 +1,563 @@
+/**
+ * $Id: drawanim.c 24637 2009-11-18 11:40:55Z campbellbarton $
+ *
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2009 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_ID.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_dlrbTree.h"
+
+#include "BKE_anim.h"
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "BKE_armature.h"
+#include "BKE_constraint.h"
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_modifier.h"
+#include "BKE_nla.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "ED_armature.h"
+#include "ED_anim_api.h"
+#include "ED_keyframes_draw.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+#include "BLF_api.h"
+
+#include "UI_resources.h"
+
+#include "view3d_intern.h"
+
+/* ************************************ Motion Paths ************************************* */
+
+// TODO:
+// - options to draw paths with lines
+// - include support for editing the path verts
+
+/* Set up drawing environment for drawing motion paths */
+void draw_motion_paths_init(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ RegionView3D *rv3d= ar->regiondata;
+
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ glPushMatrix();
+ glLoadMatrixf(rv3d->viewmat);
+}
+
+/* Draw the given motion path for an Object or a Bone
+ * - assumes that the viewport has already been initialised properly
+ * i.e. draw_motion_paths_init() has been called
+ */
+void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar,
+ Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath)
+{
+ //RegionView3D *rv3d= ar->regiondata;
+ bMotionPathVert *mpv, *mpv_start;
+ int sfra, efra, len;
+ int i, stepsize;
+
+ /* get frame ranges */
+ if (avs->path_type == MOTIONPATH_TYPE_ACFRA) {
+ int sind;
+
+ /* With "Around Current", we only choose frames from around
+ * the current frame to draw. However, this range is still
+ * restricted by the limits of the original path.
+ */
+ sfra= CFRA - avs->path_bc;
+ efra= CFRA + avs->path_ac;
+ if (sfra < mpath->start_frame) sfra= mpath->start_frame;
+ if (efra > mpath->end_frame) efra= mpath->end_frame;
+
+ len= efra - sfra;
+
+ sind= sfra - mpath->start_frame;
+ mpv_start= (mpath->points + sind);
+ }
+ else {
+ sfra= mpath->start_frame;
+ efra = sfra + mpath->length;
+ len = mpath->length;
+ mpv_start= mpath->points;
+ }
+
+ /* draw curve-line of path */
+ glShadeModel(GL_SMOOTH);
+
+ glBegin(GL_LINE_STRIP);
+ for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
+ short sel= (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
+ float intensity; /* how faint */
+
+ /* set color
+ * - more intense for active/selected bones, less intense for unselected bones
+ * - black for before current frame, green for current frame, blue for after current frame
+ * - intensity decreases as distance from current frame increases
+ */
+ #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min)
+ if ((sfra+i) < CFRA) {
+ /* black - before cfra */
+ if (sel) {
+ // intensity= 0.5f;
+ intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f);
+ }
+ else {
+ //intensity= 0.8f;
+ intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
+ }
+ UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
+ }
+ else if ((sfra+i) > CFRA) {
+ /* blue - after cfra */
+ if (sel) {
+ //intensity = 0.5f;
+ intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f);
+ }
+ else {
+ //intensity = 0.8f;
+ intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
+ }
+ UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
+ }
+ else {
+ /* green - on cfra */
+ if (sel) {
+ intensity= 0.5f;
+ }
+ else {
+ intensity= 0.99f;
+ }
+ UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
+ }
+
+ /* draw a vertex with this color */
+ glVertex3fv(mpv->co);
+ }
+
+ glEnd();
+ glShadeModel(GL_FLAT);
+
+ glPointSize(1.0);
+
+ /* draw little black point at each frame
+ * NOTE: this is not really visible/noticable
+ */
+ glBegin(GL_POINTS);
+ for (i=0, mpv=mpv_start; i < len; i++, mpv++)
+ glVertex3fv(mpv->co);
+ glEnd();
+
+ /* Draw little white dots at each framestep value */
+ UI_ThemeColor(TH_TEXT_HI);
+ glBegin(GL_POINTS);
+ for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize)
+ glVertex3fv(mpv->co);
+ glEnd();
+
+ /* Draw frame numbers at each framestep value */
+ if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) {
+ for (i=0, mpv=mpv_start; i < len; i+=stepsize, mpv+=stepsize) {
+ char str[32];
+
+ /* only draw framenum if several consecutive highlighted points don't occur on same point */
+ if (i == 0) {
+ sprintf(str, "%d", (i+sfra));
+ view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
+ }
+ else if ((i > stepsize) && (i < len-stepsize)) {
+ bMotionPathVert *mpvP = (mpv - stepsize);
+ bMotionPathVert *mpvN = (mpv + stepsize);
+
+ if ((equals_v3v3(mpv->co, mpvP->co)==0) || (equals_v3v3(mpv->co, mpvN->co)==0)) {
+ sprintf(str, "%d", (sfra+i));
+ view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
+ }
+ }
+ }
+ }
+
+ /* Keyframes - dots and numbers */
+ if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) {
+ AnimData *adt= BKE_animdata_from_id(&ob->id);
+ DLRBT_Tree keys;
+
+ /* build list of all keyframes in active action for object or pchan */
+ BLI_dlrbTree_init(&keys);
+
+ if (adt) {
+ /* for now, it is assumed that keyframes for bones are all grouped in a single group */
+ if (pchan) {
+ bActionGroup *agrp= action_groups_find_named(adt->action, pchan->name);
+
+ if (agrp) {
+ agroup_to_keylist(adt, agrp, &keys, NULL);
+ BLI_dlrbTree_linkedlist_sync(&keys);
+ }
+ }
+ else {
+ action_to_keylist(adt, adt->action, &keys, NULL);
+ BLI_dlrbTree_linkedlist_sync(&keys);
+ }
+ }
+
+ /* Draw slightly-larger yellow dots at each keyframe */
+ UI_ThemeColor(TH_VERTEX_SELECT);
+ glPointSize(4.0f); // XXX perhaps a bit too big
+
+ glBegin(GL_POINTS);
+ for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
+ float mframe= (float)(sfra + i);
+
+ if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
+ glVertex3fv(mpv->co);
+ }
+ glEnd();
+
+ glPointSize(1.0f);
+
+ /* Draw frame numbers of keyframes */
+ if (avs->path_viewflag & (MOTIONPATH_VIEW_FNUMS|MOTIONPATH_VIEW_KFNOS)) {
+ for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
+ float mframe= (float)(sfra + i);
+
+ if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
+ char str[32];
+
+ sprintf(str, "%d", (sfra+i));
+ view3d_cached_text_draw_add(mpv->co[0], mpv->co[1], mpv->co[2], str, 0);
+ }
+ }
+ }
+
+ BLI_dlrbTree_free(&keys);
+ }
+}
+
+/* Clean up drawing environment after drawing motion paths */
+void draw_motion_paths_cleanup(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ glPopMatrix();
+}
+
+#if 0 // XXX temp file guards
+
+/* ***************************** Onion Skinning (Ghosts) ******************************** */
+
+#if 0 // XXX only for bones
+/* helper function for ghost drawing - sets/removes flags for temporarily
+ * hiding unselected bones while drawing ghosts
+ */
+static void ghost_poses_tag_unselected(Object *ob, short unset)
+{
+ bArmature *arm= ob->data;
+ bPose *pose= ob->pose;
+ bPoseChannel *pchan;
+
+ /* don't do anything if no hiding any bones */
+ if ((arm->flag & ARM_GHOST_ONLYSEL)==0)
+ return;
+
+ /* loop over all pchans, adding/removing tags as appropriate */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
+ if (unset) {
+ /* remove tags from all pchans if cleaning up */
+ pchan->bone->flag &= ~BONE_HIDDEN_PG;
+ }
+ else {
+ /* set tags on unselected pchans only */
+ if ((pchan->bone->flag & BONE_SELECTED)==0)
+ pchan->bone->flag |= BONE_HIDDEN_PG;
+ }
+ }
+ }
+}
+#endif // XXX only for bones
+
+/* draw ghosts that occur within a frame range
+ * note: object should be in posemode
+ */
+static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+{
+ Object *ob= base->object;
+ AnimData *adt= BKE_animdata_from_id(&ob->id);
+ bArmature *arm= ob->data;
+ bPose *posen, *poseo;
+ float start, end, stepsize, range, colfac;
+ int cfrao, flago, ipoflago;
+
+ start = (float)arm->ghostsf;
+ end = (float)arm->ghostef;
+ if (end <= start)
+ return;
+
+ stepsize= (float)(arm->ghostsize);
+ range= (float)(end - start);
+
+ /* store values */
+ ob->mode &= ~OB_MODE_POSE;
+ cfrao= CFRA;
+ flago= arm->flag;
+ arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
+ ipoflago= ob->ipoflag;
+ ob->ipoflag |= OB_DISABLE_PATH;
+
+ /* copy the pose */
+ poseo= ob->pose;
+ copy_pose(&posen, ob->pose, 1);
+ ob->pose= posen;
+ armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
+
+ glEnable(GL_BLEND);
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ /* draw from first frame of range to last */
+ for (CFRA= (int)start; CFRA < end; CFRA += (int)stepsize) {
+ colfac = (end - (float)CFRA) / range;
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
+
+ BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ where_is_pose(scene, ob);
+ draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
+ }
+ glDisable(GL_BLEND);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ free_pose(posen);
+
+ /* restore */
+ CFRA= cfrao;
+ ob->pose= poseo;
+ arm->flag= flago;
+ armature_rebuild_pose(ob, ob->data);
+ ob->mode |= OB_MODE_POSE;
+ ob->ipoflag= ipoflago;
+}
+
+/* draw ghosts on keyframes in action within range
+ * - object should be in posemode
+ */
+static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+{
+ Object *ob= base->object;
+ AnimData *adt= BKE_animdata_from_id(&ob->id);
+ bAction *act= (adt) ? adt->action : NULL;
+ bArmature *arm= ob->data;
+ bPose *posen, *poseo;
+ DLRBT_Tree keys;
+ ActKeyColumn *ak, *akn;
+ float start, end, range, colfac, i;
+ int cfrao, flago;
+
+ start = (float)arm->ghostsf;
+ end = (float)arm->ghostef;
+ if (end <= start)
+ return;
+
+ /* get keyframes - then clip to only within range */
+ BLI_dlrbTree_init(&keys);
+ action_to_keylist(adt, act, &keys, NULL);
+ BLI_dlrbTree_linkedlist_sync(&keys);
+
+ range= 0;
+ for (ak= keys.first; ak; ak= akn) {
+ akn= ak->next;
+
+ if ((ak->cfra < start) || (ak->cfra > end))
+ BLI_freelinkN((ListBase *)&keys, ak);
+ else
+ range++;
+ }
+ if (range == 0) return;
+
+ /* store values */
+ ob->mode &= ~OB_MODE_POSE;
+ cfrao= CFRA;
+ flago= arm->flag;
+ arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
+ ob->ipoflag |= OB_DISABLE_PATH;
+
+ /* copy the pose */
+ poseo= ob->pose;
+ copy_pose(&posen, ob->pose, 1);
+ ob->pose= posen;
+ armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
+
+ glEnable(GL_BLEND);
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ /* draw from first frame of range to last */
+ for (ak=keys.first, i=0; ak; ak=ak->next, i++) {
+ colfac = i/range;
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
+
+ CFRA= (int)ak->cfra;
+
+ BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ where_is_pose(scene, ob);
+ draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
+ }
+ glDisable(GL_BLEND);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ BLI_dlrbTree_free(&keys);
+ free_pose(posen);
+
+ /* restore */
+ CFRA= cfrao;
+ ob->pose= poseo;
+ arm->flag= flago;
+ armature_rebuild_pose(ob, ob->data);
+ ob->mode |= OB_MODE_POSE;
+}
+
+/* draw ghosts around current frame
+ * - object is supposed to be armature in posemode
+ */
+static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+{
+ Object *ob= base->object;
+ AnimData *adt= BKE_animdata_from_id(&ob->id);
+ bArmature *arm= ob->data;
+ bPose *posen, *poseo;
+ float cur, start, end, stepsize, range, colfac, actframe, ctime;
+ int cfrao, flago;
+
+ /* pre conditions, get an action with sufficient frames */
+ if ELEM(NULL, adt, adt->action)
+ return;
+
+ calc_action_range(adt->action, &start, &end, 0);
+ if (start == end)
+ return;
+
+ stepsize= (float)(arm->ghostsize);
+ range= (float)(arm->ghostep)*stepsize + 0.5f; /* plus half to make the for loop end correct */
+
+ /* store values */
+ ob->mode &= ~OB_MODE_POSE;
+ cfrao= CFRA;
+ actframe= BKE_nla_tweakedit_remap(adt, (float)CFRA, 0);
+ flago= arm->flag;
+ arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
+
+ /* copy the pose */
+ poseo= ob->pose;
+ copy_pose(&posen, ob->pose, 1);
+ ob->pose= posen;
+ armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
+
+ glEnable(GL_BLEND);
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+
+ /* draw from darkest blend to lowest */
+ for(cur= stepsize; cur<range; cur+=stepsize) {
+ ctime= cur - (float)fmod(cfrao, stepsize); /* ensures consistant stepping */
+ colfac= ctime/range;
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
+
+ /* only within action range */
+ if (actframe+ctime >= start && actframe+ctime <= end) {
+ CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe+ctime, NLATIME_CONVERT_MAP);
+
+ if (CFRA != cfrao) {
+ BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ where_is_pose(scene, ob);
+ draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
+ }
+ }
+
+ ctime= cur + (float)fmod((float)cfrao, stepsize) - stepsize+1.0f; /* ensures consistant stepping */
+ colfac= ctime/range;
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
+
+ /* only within action range */
+ if ((actframe-ctime >= start) && (actframe-ctime <= end)) {
+ CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe-ctime, NLATIME_CONVERT_MAP);
+
+ if (CFRA != cfrao) {
+ BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ where_is_pose(scene, ob);
+ draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
+ }
+ }
+ }
+ glDisable(GL_BLEND);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ free_pose(posen);
+
+ /* restore */
+ CFRA= cfrao;
+ ob->pose= poseo;
+ arm->flag= flago;
+ armature_rebuild_pose(ob, ob->data);
+ ob->mode |= OB_MODE_POSE;
+}
+
+
+
+#endif // XXX temp file guards
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index bf5d516c03a..a8e140dbca3 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -43,6 +43,9 @@ struct wmWindowManager;
struct EditMesh;
struct ViewContext;
struct ARegionType;
+struct bPoseChannel;
+struct bAnimVizSettings;
+struct bMotionPath;
#define BL_NEAR_CLIP 0.001
@@ -84,6 +87,15 @@ void VIEW3D_OT_drawtype(struct wmOperatorType *ot);
void view3d_boxview_copy(ScrArea *sa, ARegion *ar);
+/* drawanim.c */
+void draw_motion_paths_init(Scene *scene, View3D *v3d, struct ARegion *ar);
+void draw_motion_path_instance(Scene *scene, View3D *v3d, struct ARegion *ar,
+ struct Object *ob, struct bPoseChannel *pchan,
+ struct bAnimVizSettings *avs, struct bMotionPath *mpath);
+void draw_motion_paths_cleanup(Scene *scene, View3D *v3d, struct ARegion *ar);
+
+
+
/* drawobject.c */
void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, int flag);
int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index e7c8070b7c5..17af631350a 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -94,14 +94,14 @@
#include "view3d_intern.h" // own include
-
+// TODO: should return whether there is valid context to continue
void view3d_set_viewcontext(bContext *C, ViewContext *vc)
{
memset(vc, 0, sizeof(ViewContext));
vc->ar= CTX_wm_region(C);
vc->scene= CTX_data_scene(C);
vc->v3d= CTX_wm_view3d(C);
- vc->rv3d= vc->ar->regiondata;
+ vc->rv3d= CTX_wm_region_view3d(C);
vc->obact= CTX_data_active_object(C);
vc->obedit= CTX_data_edit_object(C);
}
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 9847b3a9219..aa3b921565f 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -46,13 +46,23 @@ struct Object;
/* Motion Paths ------------------------------------ */
/* (used for Pose Channels and Objects) */
-/* Data point for motion path */
+/* Data point for motion path (mpv) */
typedef struct bMotionPathVert {
float co[3]; /* coordinates of point in 3D-space */
int flag; /* quick settings */
} bMotionPathVert;
-/* Motion Path data cache - for elements providing transforms (i.e. Objects or PoseChannels) */
+/* bMotionPathVert->flag */
+typedef enum eMotionPathVert_Flag {
+ /* vert is selected */
+ MOTIONPATH_VERT_SEL = (1<<0),
+} eMotionPathVert_Flag;
+
+/* ........ */
+
+/* Motion Path data cache (mpath)
+ * - for elements providing transforms (i.e. Objects or PoseChannels)
+ */
typedef struct bMotionPath {
bMotionPathVert *points; /* path samples */
int length; /* the number of cached verts */
@@ -60,33 +70,79 @@ typedef struct bMotionPath {
int start_frame; /* for drawing paths, the start frame number */
int end_frame; /* for drawing paths, the end frame number */
- int flag; /* extra settings */
+ int flag; /* baking settings - eMotionPath_Flag */
} bMotionPath;
+/* bMotionPath->flag */
+typedef enum eMotionPath_Flag {
+ /* (for bones) path represents the head of the bone */
+ MOTIONPATH_FLAG_BHEAD = (1<<0),
+ /* motion path is being edited */
+ MOTIONPATH_FLAG_EDIT = (1<<1),
+} eMotionPath_Flag;
+/* Visualisation General --------------------------- */
+/* for Objects or Poses (but NOT PoseChannels) */
-/* Animation Visualisation Settings - for Objects or Armatures (not PoseChannels) */
+/* Animation Visualisation Settings (avs) */
typedef struct bAnimVizSettings {
+ /* Onion-Skinning Settings ----------------- */
+ 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_step; /* number of frames between each ghost shown (not for GHOST_TYPE_KEYS) */
+
int pad;
- int pathflag; /* eMotionPath_Settings */
- int pathsf, pathef; /* start and end frames of path-calculation range */
- int pathbc, pathac; /* number of frames before/after current frame of path-calculation */
+ /* Motion Path Settings ------------------- */
+ short path_type; /* eMotionPath_Types */
+ short path_step; /* number of frames between points indicated on the paths */
+
+ short path_viewflag; /* eMotionPaths_ViewFlag */
+ short path_bakeflag; /* eMotionPaths_BakeFlag */
+
+ int path_sf, path_ef; /* start and end frames of path-calculation range */
+ int path_bc, path_ac; /* number of frames before/after current frame to show */
} bAnimVizSettings;
-/* bMotionPathSettings->flag */
-typedef enum eMotionPath_Settings {
+
+/* bAnimVizSettings->ghost_type */
+typedef enum eOnionSkin_Types {
+ /* around current frame */
+ GHOST_TYPE_ACFRA = 0,
+ /* 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->path_type */
+typedef enum eMotionPaths_Types {
+ /* show the paths along their entire ranges */
+ MOTIONPATH_TYPE_RANGE = 0,
+ /* only show the parts of the paths around the current frame */
+ MOTIONPATH_TYPE_ACFRA,
+} eMotionPath_Types;
+
+/* bAnimVizSettings->path_viewflag */
+typedef enum eMotionPaths_ViewFlag {
/* show frames on path */
- MOTIONPATH_FLAG_FNUMS = (1<<0),
+ MOTIONPATH_VIEW_FNUMS = (1<<0),
/* show keyframes on path */
- MOTIONPATH_FLAG_KFRAS = (1<<1),
- /* for bones - calculate head-points for curves instead of tips */
- MOTIONPATH_FLAG_HEADS = (1<<2),
- /* show path around current frame */
- MOTIONPATH_FLAG_ACFRA = (1<<3),
+ MOTIONPATH_VIEW_KFRAS = (1<<1),
/* show keyframe/frame numbers */
- MOTIONPATH_FLAG_KFNOS = (1<<4)
-} eMotionPath_Settings;
+ MOTIONPATH_VIEW_KFNOS = (1<<2),
+} eMotionPath_ViewFlag;
+
+/* bAnimVizSettings->path_bakeflag */
+typedef enum eMotionPaths_BakeFlag {
+ /* motion paths directly associated with this block of settings needs updating */
+ MOTIONPATH_BAKE_NEEDS_RECALC = (1<<0),
+ /* for bones - calculate head-points for curves instead of tips */
+ MOTIONPATH_BAKE_HEADS = (1<<1),
+} eMotionPath_BakeFlag;
/* ************************************************ */
/* Poses */
@@ -113,9 +169,11 @@ typedef struct bPoseChannel {
short protectflag; /* protect channels from being transformed */
short agrp_index; /* index of action-group this bone belongs to (0 = default/no group) */
+// XXX depreceated.... old animation system (armature only viz) ----
int pathlen; /* for drawing paths, the amount of frames */
int pathsf; /* for drawing paths, the start frame number */
int pathef; /* for drawing paths, the end frame number */
+// XXX end of depreceated code -------------------------------------
struct Bone *bone; /* set on read file or rebuild pose */
struct bPoseChannel *parent; /* set on read file or rebuild pose */
@@ -152,8 +210,9 @@ typedef struct bPoseChannel {
float ikrotweight; /* weight of joint rotation constraint */
float iklinweight; /* weight of joint stretch constraint */
- float *path; /* totpath x 3 x float */
- struct Object *custom; /* draws custom object instead of this channel */
+ float *path; /* totpath x 3 x float */ // XXX depreceated... old animation system (armature only viz)
+ bMotionPath *mpath; /* motion path cache for this bone */
+ struct Object *custom; /* draws custom object instead of default bone shape */
} bPoseChannel;
@@ -259,6 +318,8 @@ typedef struct bPose {
int iksolver; /* ik solver to use, see ePose_IKSolverType */
void *ikdata; /* temporary IK data, depends on the IK solver. Not saved in file */
void *ikparam; /* IK solver parameters, structure depends on iksolver */
+
+ bAnimVizSettings avs; /* settings for visualisation of bone animation */
} bPose;
@@ -283,7 +344,7 @@ typedef enum ePose_Flags {
/* IK Solvers ------------------------------------ */
/* bPose->iksolver and bPose->ikparam->iksolver */
-typedef enum {
+typedef enum ePose_IKSolverType {
IKSOLVER_LEGACY = 0,
IKSOLVER_ITASC,
} ePose_IKSolverType;
@@ -310,7 +371,7 @@ typedef struct bItasc {
} bItasc;
/* bItasc->flag */
-typedef enum {
+typedef enum eItasc_Flags {
ITASC_AUTO_STEP = (1<<0),
ITASC_INITIAL_REITERATION = (1<<1),
ITASC_REITERATION = (1<<2),
@@ -318,7 +379,7 @@ typedef enum {
} eItasc_Flags;
/* bItasc->solver */
-typedef enum {
+typedef enum eItasc_Solver {
ITASC_SOLVER_SDLS = 0, /* selective damped least square, suitable for CopyPose constraint */
ITASC_SOLVER_DLS /* damped least square with numerical filtering of damping */
} eItasc_Solver;
@@ -509,15 +570,14 @@ typedef enum eSAction_Flag {
} eSAction_Flag;
/* SpaceAction Mode Settings */
-// XXX should this be used by other editors too?
typedef enum eAnimEdit_Context {
- /* action (default) */
+ /* action on the active object */
SACTCONT_ACTION = 0,
- /* editing of shapekey's IPO block */
+ /* list of all shapekeys on the active object, linked with their F-Curves */
SACTCONT_SHAPEKEY,
/* editing of gpencil data */
SACTCONT_GPENCIL,
- /* dopesheet */
+ /* dopesheet (default) */
SACTCONT_DOPESHEET,
} eAnimEdit_Context;
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index ea549f9aeba..1b0da09058a 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -92,11 +92,14 @@ typedef struct bArmature {
int pad;
int layer, layer_protected; /* for buttons to work, both variables in this order together */
+
+// XXX depreceated... old animaton system (armature only viz) ---
short ghostep, ghostsize; /* number of frames to ghosts to show, and step between them */
short ghosttype, pathsize; /* ghost drawing options and number of frames between points of path */
int ghostsf, ghostef; /* start and end frames of ghost-drawing range */
int pathsf, pathef; /* start and end frames of path-calculation range for all bones */
int pathbc, pathac; /* number of frames before/after current frame of path-calculation for all bones */
+// XXX end of depreceated code ----------------------------------
} bArmature;
/* armature->flag */
@@ -136,6 +139,7 @@ typedef enum eArmature_DeformFlag {
} eArmature_DeformFlag;
/* armature->pathflag */
+// XXX depreceated... old animation system (armature only viz)
typedef enum eArmature_PathFlag {
ARM_PATH_FNUMS = (1<<0),
ARM_PATH_KFRAS = (1<<1),
@@ -145,6 +149,7 @@ typedef enum eArmature_PathFlag {
} eArmature_PathFlag;
/* armature->ghosttype */
+// XXX depreceated... old animation system (armature only viz)
typedef enum eArmature_GhostType {
ARM_GHOST_CUR = 0,
ARM_GHOST_RANGE,
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index d780aec7895..ace56e78a46 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -35,12 +35,12 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
+#include "DNA_action_types.h"
#ifdef __cplusplus
extern "C" {
#endif
-
-struct bPose;
+
struct Object;
struct AnimData;
struct Ipo;
@@ -115,6 +115,9 @@ typedef struct Object {
struct bGPdata *gpd; /* Grease Pencil data */
+ bAnimVizSettings avs; /* settings for visualisation of object-transform animation */
+ bMotionPath *mpath; /* motion path cache for this object */
+
ListBase constraintChannels; // XXX depreceated... old animation system
ListBase effect;
ListBase disp;