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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_ipo.h121
-rw-r--r--source/blender/blenkernel/SConscript2
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c14
-rw-r--r--source/blender/blenkernel/intern/blender.c7
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c149
-rw-r--r--source/blender/blenkernel/intern/fcurve.c9
-rw-r--r--source/blender/blenkernel/intern/ipo.c2837
-rw-r--r--source/blender/blenkernel/intern/key.c5
-rw-r--r--source/blender/blenkernel/intern/library.c72
-rw-r--r--source/blender/blenkernel/intern/object.c32
-rw-r--r--source/blender/blenloader/SConscript2
-rw-r--r--source/blender/blenloader/intern/readfile.c28
-rw-r--r--source/blender/editors/space_action/action_draw.c2
-rw-r--r--source/blender/editors/space_action/action_edit.c33
-rwxr-xr-xsource/blender/makesrna/intern/rna_pose.c2
15 files changed, 739 insertions, 2576 deletions
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index fae62b4a23e..a3f451438bd 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -24,7 +24,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): 2008, Joshua Leung (Animation Cleanup)
+ * Contributor(s): 2008,2009 Joshua Leung (Animation Cleanup, Animation Systme Recode)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -35,127 +35,18 @@
extern "C" {
#endif
-
-/* -------- IPO-Curve (Bezier) Calculations ---------- */
-
-// xxx perhaps this should be in curve api not in anim api
-void correct_bezpart(float *v1, float *v2, float *v3, float *v4);
-
-
-// XXX this file will soon be depreceated...
-#if 0 // XXX old animation system
-
-typedef struct CfraElem {
- struct CfraElem *next, *prev;
- float cfra;
- int sel;
-} CfraElem;
-
+struct Main;
struct Ipo;
-struct IpoCurve;
-struct MTex;
-struct Material;
-struct Scene;
-struct Object;
-struct Sequence;
-struct ListBase;
-struct BezTriple;
-struct ID;
-struct bPoseChannel;
-struct bActionChannel;
-struct rctf;
-/* ------------ Time Management ------------ */
+void do_versions_ipo_to_animato(struct Main *main);
-float frame_to_float(struct Scene *scene, int cfra);
+/* --------------------- xxx stuff ------------------------ */
-/* ------------ IPO Management ---------- */
-
-void free_ipo_curve(struct IpoCurve *icu);
void free_ipo(struct Ipo *ipo);
-void ipo_default_v2d_cur(struct Scene *scene, int blocktype, struct rctf *cur);
-
-struct Ipo *add_ipo(struct Scene *scene, char *name, int idcode);
-struct Ipo *copy_ipo(struct Ipo *ipo);
-
-void ipo_idnew(struct Ipo *ipo);
-
-struct IpoCurve *find_ipocurve(struct Ipo *ipo, int adrcode);
-short has_ipo_code(struct Ipo *ipo, int code);
-
-/* -------------- Make Local -------------- */
-
-void make_local_obipo(struct Ipo *ipo);
-void make_local_matipo(struct Ipo *ipo);
-void make_local_keyipo(struct Ipo *ipo);
-void make_local_ipo(struct Ipo *ipo);
-
-/* ------------ IPO-Curve Sanity ---------------- */
-
-void calchandles_ipocurve(struct IpoCurve *icu);
-void testhandles_ipocurve(struct IpoCurve *icu);
-void sort_time_ipocurve(struct IpoCurve *icu);
-int test_time_ipocurve(struct IpoCurve *icu);
-
-void set_interpolation_ipocurve(struct IpoCurve *icu, short ipo);
-
-/* -------- IPO-Curve (Bezier) Calculations ---------- */
-
+// xxx perhaps this should be in curve api not in anim api
void correct_bezpart(float *v1, float *v2, float *v3, float *v4);
-int findzero(float x, float q0, float q1, float q2, float q3, float *o);
-void berekeny(float f1, float f2, float f3, float f4, float *o, int b);
-void berekenx(float *f, float *o, int b);
-
-/* -------- IPO Curve Calculation and Evaluation --------- */
-
-float eval_icu(struct IpoCurve *icu, float ipotime);
-void calc_icu(struct IpoCurve *icu, float ctime);
-float calc_ipo_time(struct Ipo *ipo, float ctime);
-void calc_ipo(struct Ipo *ipo, float ctime);
-
-void calc_ipo_range(struct Ipo *ipo, float *start, float *end);
-
-/* ------------ Keyframe Column Tools -------------- */
-
-void add_to_cfra_elem(struct ListBase *lb, struct BezTriple *bezt);
-void make_cfra_list(struct Ipo *ipo, struct ListBase *elems);
-
-/* ---------------- IPO DataAPI ----------------- */
-
-void write_ipo_poin(void *poin, int type, float val);
-float read_ipo_poin(void *poin, int type);
-
-void *give_mtex_poin(struct MTex *mtex, int adrcode );
-void *get_pchan_ipo_poin(struct bPoseChannel *pchan, int adrcode);
-void *get_ipo_poin(struct ID *id, struct IpoCurve *icu, int *type);
-
-void set_icu_vars(struct IpoCurve *icu);
-
-/* ---------------- IPO Execution --------------- */
-
-void execute_ipo(struct ID *id, struct Ipo *ipo);
-void execute_action_ipo(struct bActionChannel *achan, struct bPoseChannel *pchan);
-
-void do_ipo_nocalc(struct Scene *scene, struct Ipo *ipo);
-void do_ipo(struct Scene *scene, struct Ipo *ipo);
-void do_mat_ipo(struct Scene *scene, struct Material *ma);
-void do_ob_ipo(struct Scene *scene, struct Object *ob);
-void do_seq_ipo(struct Scene *scene, struct Sequence *seq, int cfra);
-void do_ob_ipodrivers(struct Object *ob, struct Ipo *ipo, float ctime);
-
-void do_all_data_ipos(struct Scene *scene);
-short calc_ipo_spec(struct Ipo *ipo, int adrcode, float *ctime);
-void clear_delta_obipo(struct Ipo *ipo);
-
-/* ----------- IPO <-> GameEngine API ---------------- */
-
-/* the short is an IPO_Channel... */
-
-short IPO_GetChannels(struct Ipo *ipo, short *channels);
-float IPO_GetFloatValue(struct Ipo *ipo, short c, float ctime);
-
-#endif // XXX old animation system
+
#ifdef __cplusplus
};
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index aae4addd71e..bf09b2aac03 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -52,4 +52,4 @@ if env['BF_NO_ELBEEM']:
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross'):
incs += ' ' + env['BF_PTHREADS_INC']
-env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = Split(defs), libtype=['core'], priority = [155] )
+env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = Split(defs), libtype=['core'], priority = [165] )
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index fb2a9731a40..30e5daeeb3b 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -86,7 +86,10 @@ AnimData *BKE_id_add_animdata (ID *id)
if (id_has_animdata(id)) {
IdAdtTemplate *iat= (IdAdtTemplate *)id;
- iat->adt= MEM_callocN(sizeof(AnimData), "AnimData");
+ /* check if there's already AnimData, in which case, don't add */
+ if (iat->adt == NULL)
+ iat->adt= MEM_callocN(sizeof(AnimData), "AnimData");
+
return iat->adt;
}
else
@@ -232,7 +235,8 @@ static void animsys_execute_fcurve (PointerRNA *ptr, AnimMapper *remap, FCurve *
free_path= animsys_remap_path(remap, fcu->rna_path, &path);
/* write value to setting */
- animsys_write_rna_setting(ptr, path, fcu->array_index, fcu->curval);
+ if (path)
+ animsys_write_rna_setting(ptr, path, fcu->array_index, fcu->curval);
/* free temp path-info */
if (free_path)
@@ -586,7 +590,7 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re
* or be layered on top of existing animation data.
* - Drivers should be in the appropriate order to be evaluated without problems...
*/
- if ((recalc & ADT_RECALC_DRIVERS) && (adt->recalc & ADT_RECALC_DRIVERS))
+ if ((recalc & ADT_RECALC_DRIVERS) /*&& (adt->recalc & ADT_RECALC_DRIVERS)*/) // XXX for now, don't check yet, as depsgraph hasn't been updated
{
animsys_evaluate_drivers(&id_ptr, adt, ctime);
}
@@ -615,7 +619,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
{
ID *id;
- //printf("Evaluate all animation - %f \n", ctime);
+ printf("Evaluate all animation - %f \n", ctime);
/* macro for less typing */
#define EVAL_ANIM_IDS(first) \
@@ -640,7 +644,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
EVAL_ANIM_IDS(main->camera.first);
/* shapekeys */
- // TODO...
+ EVAL_ANIM_IDS(main->key.first);
/* curves */
// TODO...
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index ae18a75daa0..2ad0c98bb79 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -74,6 +74,7 @@
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_library.h"
+#include "BKE_ipo.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_object.h"
@@ -371,12 +372,12 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
//setscreen(G.curscreen);
}
+ // XXX is this in the right place?
+ do_versions_ipos_to_animato(G.main); // XXX fixme... complicated versionpatching
+
/* baseflags, groups, make depsgraph, etc */
set_scene_bg(CTX_data_scene(C));
- /* clear BONE_UNKEYED flags, these are not valid anymore for proxies */
- framechange_poses_clear_unkeyed();
-
/* last stage of do_versions actually, that sets recalc flags for recalc poses */
for(ob= G.main->object.first; ob; ob= ob->id.next) {
if(ob->type==OB_ARMATURE)
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 57dca4ddcb5..983a9bc9ac6 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -303,50 +303,66 @@ DagForest * dag_init()
return forest;
}
-static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int isdata)
+/* isdata = object data... */
+// XXX this needs to be extended to be more flexible (so that not only objects are evaluated via depsgraph)...
+static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node, int isdata)
{
- IpoCurve *icu;
+ FCurve *fcu;
DagNode *node1;
- for(icu= ipo->curve.first; icu; icu= icu->next) {
- if(icu->driver) {
-
- if (icu->driver->type == IPO_DRIVER_TYPE_PYTHON) {
-
- if ((icu->driver->flag & IPO_DRIVER_FLAG_INVALID) || (icu->driver->name[0] == '\0'))
- continue; /* empty or invalid expression */
+ for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
+ ChannelDriver *driver= fcu->driver;
+
+ if (driver->type == DRIVER_TYPE_PYTHON) {
+ /* PyDriver / 'Expression' */
+
+ /* skip if invalid in some way */
+ if ((driver->flag & DRIVER_FLAG_INVALID) || (driver->expression[0] == '\0'))
+ continue;
#ifndef DISABLE_PYTHON
- else {
- /* now we need refs to all objects mentioned in this
- * pydriver expression, to call 'dag_add_relation'
- * for each of them */
- Object **obarray = BPY_pydriver_get_objects(icu->driver);
- if (obarray) {
- Object *ob, **oba = obarray;
-
- while (*oba) {
- ob = *oba;
- node1 = dag_get_node(dag, ob);
- if (ob->type == OB_ARMATURE)
- dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Python Ipo Driver");
- else
- dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Python Ipo Driver");
- oba++;
- }
-
- MEM_freeN(obarray);
+ else {
+ /* now we need refs to all objects mentioned in this
+ * pydriver expression, to call 'dag_add_relation'
+ * for each of them */
+ Object **obarray = BPY_pydriver_get_objects(fcu->driver);
+ if (obarray) {
+ Object *ob, **oba = obarray;
+
+ while (*oba) {
+ ob = *oba;
+ node1 = dag_get_node(dag, ob);
+ if (ob->type == OB_ARMATURE)
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Python Driver");
+ else
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Python Driver");
+ oba++;
}
+
+ MEM_freeN(obarray);
}
-#endif /* DISABLE_PYTHON */
- }
- else if (icu->driver->ob) {
- node1 = dag_get_node(dag, icu->driver->ob);
- if(icu->driver->blocktype==ID_AR)
- dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Ipo Driver");
- else
- dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Ipo Driver");
}
+#endif /* DISABLE_PYTHON */
+ }
+ else if (driver->type == DRIVER_TYPE_ROTDIFF) {
+ // XXX rotational difference
+ }
+ else {
+ /* normal channel-drives-channel */
+ node1 = dag_get_node(dag, driver->id); // XXX we assume that id is an object...
+
+ // XXX what happens for bone drivers?
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Ipo Driver");
}
+#if 0 // XXX old 'normal' type
+
+ else if (icu->driver->ob) {
+ node1 = dag_get_node(dag, icu->driver->ob);
+ if(icu->driver->blocktype==ID_AR)
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Ipo Driver");
+ else
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Ipo Driver");
+ }
+#endif // XXX old 'normal' type
}
}
@@ -371,7 +387,6 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec
static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, Object *ob, int mask)
{
bConstraint *con;
- bConstraintChannel *conchan;
DagNode * node;
DagNode * node2;
DagNode * node3;
@@ -426,6 +441,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
/* driver dependencies, nla modifiers */
+#if 0 // XXX old animation system
if(ob->ipo)
dag_add_driver_relation(ob->ipo, dag, node, 0);
@@ -466,6 +482,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
}
}
+#endif // XXX old animation system
+ if (ob->adt)
+ dag_add_driver_relation(ob->adt, dag, node, (ob->type == OB_ARMATURE)); // XXX isdata arg here doesn't give an accurate picture of situation
+
+ key= ob_get_key(ob);
+ if (key && key->adt)
+ dag_add_driver_relation(key->adt, dag, node, 1);
+
if (ob->modifiers.first) {
ModifierData *md;
@@ -515,11 +539,12 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA|DAG_RL_OB_OB, "Proxy");
/* inverted relation, so addtoroot shouldn't be set to zero */
}
+
+
if (ob->type==OB_CAMERA) {
Camera *cam = (Camera *)ob->data;
- if (cam->ipo) {
- dag_add_driver_relation(cam->ipo, dag, node, 1);
- }
+ if (cam->adt)
+ dag_add_driver_relation(cam->adt, dag, node, 1);
if (cam->dof_ob) {
node2 = dag_get_node(dag, cam->dof_ob);
dag_add_relation(dag,node2,node,DAG_RL_OB_OB, "Camera DoF");
@@ -527,10 +552,10 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
if (ob->type==OB_LAMP) {
Lamp *la = (Lamp *)ob->data;
- if (la->ipo) {
- dag_add_driver_relation(la->ipo, dag, node, 1);
- }
+ if (la->adt)
+ dag_add_driver_relation(la->adt, dag, node, 1);
}
+
if (ob->transflag & OB_DUPLI) {
if((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
GroupObject *go;
@@ -566,9 +591,8 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
node2 = dag_get_node(dag, cu->taperobj);
dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Curve Taper");
}
- if(cu->ipo)
- dag_add_driver_relation(cu->ipo, dag, node, 1);
-
+ if (cu->adt)
+ dag_add_driver_relation(cu->adt, dag, node, 1);
}
else if(ob->type==OB_FONT) {
Curve *cu= ob->data;
@@ -1953,24 +1977,6 @@ static int object_modifiers_use_time(Object *ob)
return 0;
}
-#if 0 // XXX old animation system
-static int exists_channel(Object *ob, char *name)
-{
- bActionStrip *strip;
-
- if(ob->action)
- if(get_action_channel(ob->action, name))
- return 1;
-
- for (strip=ob->nlastrips.first; strip; strip=strip->next)
- if(get_action_channel(strip->act, name))
- return 1;
-
- return 0;
-}
-#endif // XXX old animation system
-
-
static short animdata_use_time(AnimData *adt)
{
NlaTrack *nlt;
@@ -2023,14 +2029,8 @@ static void dag_object_time_update_flags(Object *ob)
}
#if 0 // XXX old animation system
- if(ob->action || ob->nlastrips.first) {
- /* since actions now are mixed, we set the recalcs on the safe side */
- ob->recalc |= OB_RECALC_OB;
- if(ob->type==OB_ARMATURE)
- ob->recalc |= OB_RECALC_DATA;
- else if(exists_channel(ob, "Shape"))
- ob->recalc |= OB_RECALC_DATA;
- else if(ob->dup_group) {
+ if(ob->nlastrips.first) {
+ if(ob->dup_group) {
bActionStrip *strip;
/* this case is for groups with nla, whilst nla target has no action or nla */
for(strip= ob->nlastrips.first; strip; strip= strip->next) {
@@ -2041,6 +2041,7 @@ static void dag_object_time_update_flags(Object *ob)
}
#endif // XXX old animation system
if(animdata_use_time(ob->adt)) ob->recalc |= OB_RECALC;
+ if((ob->adt) && (ob->type==OB_ARMATURE)) ob->recalc |= OB_RECALC_DATA;
if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
if((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
@@ -2316,6 +2317,7 @@ void DAG_pose_sort(Object *ob)
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
+#if 0 // XXX old animation system... driver stuff to watch out for
if(con->ipo) {
IpoCurve *icu;
for(icu= con->ipo->curve.first; icu; icu= icu->next) {
@@ -2327,7 +2329,7 @@ void DAG_pose_sort(Object *ob)
if(target) {
node2 = dag_get_node(dag, target);
dag_add_relation(dag, node2, node, 0, "Ipo Driver");
-
+
/* uncommented this line, results in dependencies
* not being added properly for this constraint,
* what is the purpose of this? - brecht */
@@ -2336,6 +2338,7 @@ void DAG_pose_sort(Object *ob)
}
}
}
+#endif // XXX old animation system... driver stuff to watch out for
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index f547b483092..e4c4e7a37b4 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1190,7 +1190,7 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
cycles= data->after_cycles;
}
}
- if ELEM3(0, side, mode, cycles)
+ if ELEM(0, side, mode)
return;
/* extrapolation mode is 'cyclic' - find relative place within a cycle */
@@ -1209,7 +1209,12 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
if (cycdx == 0)
return;
/* check that cyclic is still enabled for the specified time */
- if ( ((float)side * (evaltime - ofs) / cycdx) > cycles )
+ if (cycles == 0) {
+ /* catch this case so that we don't exit when we have cycles=0
+ * as this indicates infinite cycles...
+ */
+ }
+ else if ( ((float)side * (evaltime - ofs) / cycdx) > cycles )
return;
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 16d173bf5d6..0c9897f9b30 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -23,13 +23,19 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): 2008, Joshua Leung (IPO System cleanup)
+ * Contributor(s): 2008,2009 Joshua Leung (IPO System cleanup, Animation System Recode)
*
* ***** END GPL LICENSE BLOCK *****
*/
-#if 0 // XXX old animation system
-
+/* NOTE:
+ *
+ * This file is no longer used to provide tools for the depreceated IPO system. Instead, it
+ * is only used to house the conversion code to the new system.
+ *
+ * -- Joshua Leung, Jan 2009
+ */
+
#include <math.h>
#include <stdio.h>
#include <string.h>
@@ -40,8 +46,10 @@
#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_curve_types.h"
#include "DNA_camera_types.h"
#include "DNA_lamp_types.h"
@@ -61,13 +69,16 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_dynstr.h"
#include "BKE_utildefines.h"
+#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_blender.h"
#include "BKE_curve.h"
#include "BKE_constraint.h"
+#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_ipo.h"
#include "BKE_library.h"
@@ -75,1744 +86,732 @@
#include "BKE_mesh.h"
#include "BKE_object.h"
-#ifndef DISABLE_PYTHON
-#include "BPY_extern.h" /* for BPY_pydriver_eval() */
-#endif
-
-#define SMALL -1.0e-10
-
-/* ***************************** Adrcode Blocktype Defines ********************************* */
-
-/* This array concept was meant to make sure that defines such as OB_LOC_X
- don't have to be enumerated, also for backward compatibility, future changes,
- and to enable it all can be accessed with a for-next loop.
-
- This should whole adrcode system should eventually be replaced by a proper Data API
-*/
-
-
-int co_ar[CO_TOTIPO]= {
- CO_ENFORCE, CO_HEADTAIL
-};
-
-int ob_ar[OB_TOTIPO]= {
- OB_LOC_X, OB_LOC_Y, OB_LOC_Z, OB_DLOC_X, OB_DLOC_Y, OB_DLOC_Z,
- OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z,
- OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z, OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z,
- OB_LAY, OB_TIME, OB_COL_R, OB_COL_G, OB_COL_B, OB_COL_A,
- OB_PD_FSTR, OB_PD_FFALL, OB_PD_SDAMP, OB_PD_RDAMP, OB_PD_PERM, OB_PD_FMAXD
-};
-
-int ac_ar[AC_TOTIPO]= {
- AC_LOC_X, AC_LOC_Y, AC_LOC_Z,
- AC_EUL_X, AC_EUL_Y, AC_EUL_Z,
- AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z,
- AC_SIZE_X, AC_SIZE_Y, AC_SIZE_Z
-};
-
-int ma_ar[MA_TOTIPO]= {
- MA_COL_R, MA_COL_G, MA_COL_B,
- MA_SPEC_R, MA_SPEC_G, MA_SPEC_B,
- MA_MIR_R, MA_MIR_G, MA_MIR_B,
- MA_REF, MA_ALPHA, MA_EMIT, MA_AMB,
- MA_SPEC, MA_HARD, MA_SPTR, MA_IOR,
- MA_MODE, MA_HASIZE, MA_TRANSLU, MA_RAYM,
- MA_FRESMIR, MA_FRESMIRI, MA_FRESTRA, MA_FRESTRAI, MA_ADD,
-
- MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z,
- MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z,
- MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
- MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF, MA_MAP1+MAP_NORF, MA_MAP1+MAP_VARF, MA_MAP1+MAP_DISP
-};
-
-int te_ar[TE_TOTIPO] ={
-
- TE_NSIZE, TE_NDEPTH, TE_NTYPE, TE_TURB,
-
- TE_VNW1, TE_VNW2, TE_VNW3, TE_VNW4,
- TE_VNMEXP, TE_VN_COLT, TE_VN_DISTM,
-
- TE_ISCA, TE_DISTA,
-
- TE_MG_TYP, TE_MGH, TE_MG_LAC, TE_MG_OCT, TE_MG_OFF, TE_MG_GAIN,
-
- TE_N_BAS1, TE_N_BAS2,
-
- TE_COL_R, TE_COL_G, TE_COL_B, TE_BRIGHT, TE_CONTRA
-};
-
-int seq_ar[SEQ_TOTIPO]= {
- SEQ_FAC1
-};
-int cu_ar[CU_TOTIPO]= {
- CU_SPEED
-};
-int wo_ar[WO_TOTIPO]= {
- WO_HOR_R, WO_HOR_G, WO_HOR_B, WO_ZEN_R, WO_ZEN_G, WO_ZEN_B,
- WO_EXPOS, WO_MISI, WO_MISTDI, WO_MISTSTA, WO_MISTHI,
- WO_STAR_R, WO_STAR_G, WO_STAR_B, WO_STARDIST, WO_STARSIZE,
+/* *************************************************** */
+/* Old-Data Freeing Tools */
- MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z,
- MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z,
- MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
- MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF, MA_MAP1+MAP_NORF, MA_MAP1+MAP_VARF
-};
-
-int la_ar[LA_TOTIPO]= {
- LA_ENERGY, LA_COL_R, LA_COL_G, LA_COL_B,
- LA_DIST, LA_SPOTSI, LA_SPOTBL,
- LA_QUAD1, LA_QUAD2, LA_HALOINT,
-
- MA_MAP1+MAP_OFS_X, MA_MAP1+MAP_OFS_Y, MA_MAP1+MAP_OFS_Z,
- MA_MAP1+MAP_SIZE_X, MA_MAP1+MAP_SIZE_Y, MA_MAP1+MAP_SIZE_Z,
- MA_MAP1+MAP_R, MA_MAP1+MAP_G, MA_MAP1+MAP_B,
- MA_MAP1+MAP_DVAR, MA_MAP1+MAP_COLF
-};
-
-/* yafray: aperture & focal distance curves added */
-/* qdn: FDIST now available to Blender as well for defocus node */
-int cam_ar[CAM_TOTIPO]= {
- CAM_LENS, CAM_STA, CAM_END, CAM_YF_APERT, CAM_YF_FDIST, CAM_SHIFT_X, CAM_SHIFT_Y
-};
-
-int snd_ar[SND_TOTIPO]= {
- SND_VOLUME, SND_PITCH, SND_PANNING, SND_ATTEN
-};
-
-int fluidsim_ar[FLUIDSIM_TOTIPO]= {
- FLUIDSIM_VISC, FLUIDSIM_TIME,
- FLUIDSIM_GRAV_X , FLUIDSIM_GRAV_Y , FLUIDSIM_GRAV_Z ,
- FLUIDSIM_VEL_X , FLUIDSIM_VEL_Y , FLUIDSIM_VEL_Z ,
- FLUIDSIM_ACTIVE,
- FLUIDSIM_ATTR_FORCE_STR, FLUIDSIM_ATTR_FORCE_RADIUS,
- FLUIDSIM_VEL_FORCE_STR, FLUIDSIM_VEL_FORCE_RADIUS,
-};
-
-int part_ar[PART_TOTIPO]= {
- PART_EMIT_FREQ, PART_EMIT_LIFE, PART_EMIT_VEL, PART_EMIT_AVE, PART_EMIT_SIZE,
- PART_AVE, PART_SIZE, PART_DRAG, PART_BROWN, PART_DAMP, PART_LENGTH, PART_CLUMP,
- PART_GRAV_X, PART_GRAV_Y, PART_GRAV_Z, PART_KINK_AMP, PART_KINK_FREQ, PART_KINK_SHAPE,
- PART_BB_TILT, PART_PD_FSTR, PART_PD_FFALL, PART_PD_FMAXD, PART_PD2_FSTR, PART_PD2_FFALL, PART_PD2_FMAXD
-};
-
-/* ************************** Data-Level Functions ************************* */
-
-/* ---------------------- Freeing --------------------------- */
-
-/* frees the ipo curve itself too */
-void free_ipo_curve (IpoCurve *icu)
-{
- if (icu == NULL)
- return;
-
- if (icu->bezt)
- MEM_freeN(icu->bezt);
- if (icu->driver)
- MEM_freeN(icu->driver);
-
- MEM_freeN(icu);
-}
-
-/* do not free ipo itself */
+/* Free data from old IPO-Blocks (those which haven't been converted), but not IPO block itself */
+// XXX this shouldn't be necessary anymore, but may occur while not all data is converted yet
void free_ipo (Ipo *ipo)
{
IpoCurve *icu, *icn;
-
- if (ipo == NULL)
- return;
+ int n= 0;
for (icu= ipo->curve.first; icu; icu= icn) {
icn= icu->next;
+ n++;
- /* must remove the link before freeing, as the curve is freed too */
- BLI_remlink(&ipo->curve, icu);
- free_ipo_curve(icu);
- }
-}
-
-/* ---------------------- Init --------------------------- */
-
-/* on adding new ipos, or for empty views */
-// XXX users usually find these zoom settings problematic...
-void ipo_default_v2d_cur (Scene *scene, int blocktype, rctf *cur)
-{
- switch (blocktype) {
- case ID_CA:
- cur->xmin= (float)scene->r.sfra;
- cur->xmax= (float)scene->r.efra;
- cur->ymin= 0.0f;
- cur->ymax= 100.0f;
- break;
-
- case ID_MA: case ID_WO: case ID_LA:
- case ID_CU: case ID_CO:
- cur->xmin= (float)(scene->r.sfra - 0.1f);
- cur->xmax= (float)scene->r.efra;
- cur->ymin= (float)-0.1f;
- cur->ymax= (float)+1.1f;
- break;
+ if (icu->bezt) MEM_freeN(icu->bezt);
+ if (icu->bp) MEM_freeN(icu->bp);
+ if (icu->driver) MEM_freeN(icu->driver);
- case ID_TE:
- cur->xmin= (float)(scene->r.sfra - 0.1f);
- cur->xmax= (float)scene->r.efra;
- cur->ymin= (float)-0.1f;
- cur->ymax= (float)+1.1f;
- break;
-
- case ID_SEQ:
- cur->xmin= -5.0f;
- cur->xmax= 105.0f;
- cur->ymin= (float)-0.1f;
- cur->ymax= (float)+1.1f;
- break;
-
- case ID_KE:
- cur->xmin= (float)(scene->r.sfra - 0.1f);
- cur->xmax= (float)scene->r.efra;
- cur->ymin= (float)-0.1f;
- cur->ymax= (float)+2.1f;
- break;
-
- default: /* ID_OB and everything else */
- cur->xmin= (float)scene->r.sfra;
- cur->xmax= (float)scene->r.efra;
- cur->ymin= -5.0f;
- cur->ymax= +5.0f;
- break;
+ BLI_freelinkN(&ipo->curve, icu);
}
-}
-
-/* create a new IPO block (allocates the block) */
-Ipo *add_ipo (Scene *scene, char name[], int blocktype)
-{
- Ipo *ipo;
- ipo= alloc_libblock(&G.main->ipo, ID_IP, name);
- ipo->blocktype= blocktype;
- if(scene) ipo_default_v2d_cur(scene, blocktype, &ipo->cur);
-
- return ipo;
+ printf("Freed %d (Unconverted) Ipo-Curves from IPO '%s' \n", n, ipo->id.name+2);
}
-/* ---------------------- Copy --------------------------- */
+/* *************************************************** */
+/* ADRCODE to RNA-Path Conversion Code */
-/* duplicate an IPO block and all its data */
-Ipo *copy_ipo (Ipo *src)
+/* Object types */
+static char *ob_adrcodes_to_paths (int adrcode, int *array_index)
{
- Ipo *dst;
- IpoCurve *icu;
-
- if (src == NULL)
- return NULL;
+ /* set array index like this in-case nothing sets it correctly */
+ *array_index= 0;
- dst= copy_libblock(src);
- BLI_duplicatelist(&dst->curve, &src->curve);
-
- for (icu= src->curve.first; icu; icu= icu->next) {
- icu->bezt= MEM_dupallocN(icu->bezt);
+ /* result depends on adrcode */
+ switch (adrcode) {
+ case OB_LOC_X:
+ *array_index= 0; return "location";
+ case OB_LOC_Y:
+ *array_index= 1; return "location";
+ case OB_LOC_Z:
+ *array_index= 2; return "location";
+ case OB_DLOC_X:
+ *array_index= 0; return "delta_location";
+ case OB_DLOC_Y:
+ *array_index= 1; return "delta_location";
+ case OB_DLOC_Z:
+ *array_index= 2; return "delta_location";
- if (icu->driver)
- icu->driver= MEM_dupallocN(icu->driver);
+ case OB_ROT_X:
+ *array_index= 0; return "rotation";
+ case OB_ROT_Y:
+ *array_index= 1; return "rotation";
+ case OB_ROT_Z:
+ *array_index= 2; return "rotation";
+ case OB_DROT_X:
+ *array_index= 0; return "delta_rotation";
+ case OB_DROT_Y:
+ *array_index= 1; return "delta_rotation";
+ case OB_DROT_Z:
+ *array_index= 2; return "delta_rotation";
+
+ case OB_SIZE_X:
+ *array_index= 0; return "scale";
+ case OB_SIZE_Y:
+ *array_index= 1; return "scale";
+ case OB_SIZE_Z:
+ *array_index= 2; return "scale";
+ case OB_DSIZE_X:
+ *array_index= 0; return "delta_scale";
+ case OB_DSIZE_Y:
+ *array_index= 1; return "delta_scale";
+ case OB_DSIZE_Z:
+ *array_index= 2; return "delta_scale";
+
+#if 0
+ case OB_LAY: // XXX EVIL BITFLAG ALERT! this one will need special attention...
+ // poin= &(ob->lay); *type= IPO_INT_BIT; break;
+ return NULL;
+
+ case OB_COL_R:
+ poin= &(ob->col[0]); break;
+ case OB_COL_G:
+ poin= &(ob->col[1]); break;
+ case OB_COL_B:
+ poin= &(ob->col[2]); break;
+ case OB_COL_A:
+ poin= &(ob->col[3]); break;
+
+ case OB_PD_FSTR:
+ if (ob->pd) poin= &(ob->pd->f_strength);
+ break;
+ case OB_PD_FFALL:
+ if (ob->pd) poin= &(ob->pd->f_power);
+ break;
+ case OB_PD_SDAMP:
+ if (ob->pd) poin= &(ob->pd->pdef_damp);
+ break;
+ case OB_PD_RDAMP:
+ if (ob->pd) poin= &(ob->pd->pdef_rdamp);
+ break;
+ case OB_PD_PERM:
+ if (ob->pd) poin= &(ob->pd->pdef_perm);
+ break;
+ case OB_PD_FMAXD:
+ if (ob->pd) poin= &(ob->pd->maxdist);
+ break;
+#endif
}
- return dst;
-}
-
-/* ---------------------- Relink --------------------------- */
-
-/* uses id->newid to match pointers with other copied data
- * - called after single-user or other such
- */
-void ipo_idnew (Ipo *ipo)
-{
- if (ipo) {
- IpoCurve *icu;
-
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- if (icu->driver)
- ID_NEW(icu->driver->ob);
- }
- }
-}
-
-/* --------------------- Find + Check ----------------------- */
-
-/* find the IPO-curve within a given IPO-block with the adrcode of interest */
-IpoCurve *find_ipocurve (Ipo *ipo, int adrcode)
-{
- if (ipo) {
- IpoCurve *icu;
-
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- if (icu->adrcode == adrcode)
- return icu;
- }
- }
return NULL;
}
-/* return whether the given IPO block has a IPO-curve with the given adrcode */
-short has_ipo_code(Ipo *ipo, int adrcode)
-{
- /* return success of faliure from trying to find such an IPO-curve */
- return (find_ipocurve(ipo, adrcode) != NULL);
-}
-
-/* ---------------------- Make Local --------------------------- */
-
-
-/* make the given IPO local (for Objects)
- * - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
+/* PoseChannel types
+ * NOTE: pchan name comes from 'actname' added earlier...
*/
-void make_local_obipo (Ipo *src)
+static char *pchan_adrcodes_to_paths (int adrcode, int *array_index)
{
- Object *ob;
- Ipo *dst;
- int local=0, lib=0;
+ /* set array index like this in-case nothing sets it correctly */
+ *array_index= 0;
- /* check if only local and/or lib */
- for (ob= G.main->object.first; ob; ob= ob->id.next) {
- if (ob->ipo == src) {
- if (ob->id.lib) lib= 1;
- else local= 1;
- }
- }
-
- /* only local - set flag */
- if (local && lib==0) {
- src->id.lib= 0;
- src->id.flag= LIB_LOCAL;
- new_id(0, (ID *)src, 0);
- }
- /* mixed: make copy */
- else if (local && lib) {
- dst= copy_ipo(src);
- dst->id.us= 0;
+ /* result depends on adrcode */
+ switch (adrcode) {
+ case AC_QUAT_W:
+ *array_index= 0; return "rotation";
+ case AC_QUAT_X:
+ *array_index= 1; return "rotation";
+ case AC_QUAT_Y:
+ *array_index= 2; return "rotation";
+ case AC_QUAT_Z:
+ *array_index= 3; return "rotation";
+
+#if 0 // XXX these were not 'official' channels (i.e. not in bf-releases)... these will need separate wrapping to work...
+ case AC_EUL_X:
+ *array_index= 0; return "rotation";
+ case AC_EUL_Y:
+ *array_index= 1; return "rotation";
+ case AC_EUL_Z:
+ *array_index= 2; return "rotation";
+#endif
+ case -1: // XXX special case for rotation drivers... until eulers are added...
+ *array_index= 0; return "rotation";
+
+ case AC_LOC_X:
+ *array_index= 0; return "location";
+ case AC_LOC_Y:
+ *array_index= 1; return "location";
+ case AC_LOC_Z:
+ *array_index= 2; return "location";
- for (ob= G.main->object.first; ob; ob= ob->id.next) {
- if (ob->ipo == src) {
- if (ob->id.lib == NULL) {
- ob->ipo= dst;
- dst->id.us++;
- src->id.us--;
- }
- }
- }
- }
-}
-
-/* make the given IPO local (for Materials)
- * - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
-void make_local_matipo (Ipo *src)
-{
- Material *ma;
- Ipo *dst;
- int local=0, lib=0;
-
- /* check if only local and/or lib */
- for (ma= G.main->mat.first; ma; ma= ma->id.next) {
- if (ma->ipo == src) {
- if (ma->id.lib) lib= 1;
- else local= 1;
- }
+ case AC_SIZE_X:
+ *array_index= 0; return "scale";
+ case AC_SIZE_Y:
+ *array_index= 1; return "scale";
+ case AC_SIZE_Z:
+ *array_index= 2; return "scale";
}
- /* only local - set flag */
- if (local && lib==0) {
- src->id.lib= 0;
- src->id.flag= LIB_LOCAL;
- new_id(0, (ID *)src, 0);
- }
- /* mixed: make copy */
- else if (local && lib) {
- dst= copy_ipo(src);
- dst->id.us= 0;
-
- for (ma= G.main->mat.first; ma; ma= ma->id.next) {
- if (ma->ipo == src) {
- if (ma->id.lib == NULL) {
- ma->ipo= dst;
- dst->id.us++;
- src->id.us--;
- }
- }
- }
- }
+ /* for debugging only */
+ printf("ERROR: unmatched PoseChannel setting (code %d) \n", adrcode);
+ return NULL;
}
-/* make the given IPO local (for ShapeKeys)
- * - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
+/* ShapeKey types
+ * NOTE: as we don't have access to the keyblock where the data comes from (for now),
+ * we'll just use numerical indicies for now...
*/
-void make_local_keyipo (Ipo *src)
+static char *shapekey_adrcodes_to_paths (int adrcode, int *array_index)
{
- Key *key;
- Ipo *dst;
- int local=0, lib=0;
-
- /* check if only local and/or lib */
- for (key= G.main->key.first; key; key= key->id.next) {
- if (key->ipo == src) {
- if (key->id.lib) lib= 1;
- else local= 1;
- }
- }
+ static char buf[128];
- /* only local - set flag */
- if (local && lib==0) {
- src->id.lib= 0;
- src->id.flag= LIB_LOCAL;
- new_id(0, (ID *)src, 0);
- }
- /* mixed: make copy */
- else if (local && lib) {
- dst= copy_ipo(src);
- dst->id.us= 0;
-
- for (key= G.main->key.first; key; key= key->id.next) {
- if (key->ipo == src) {
- if (key->id.lib == NULL) {
- key->ipo= dst;
- dst->id.us++;
- src->id.us--;
- }
- }
- }
- }
+ /* block will be attached to ID_KE block, and setting that we alter is the 'value' (which sets keyblock.curval) */
+ // XXX adrcode 0 was dummy 'speed' curve
+ sprintf(buf, "keys[%d].value", adrcode-1); // XXX this doesn't seem too safe...
+ return buf;
}
+/* ------- */
-/* generic call to make IPO's local */
-void make_local_ipo (Ipo *ipo)
+/* Allocate memory for RNA-path for some property given a blocktype, adrcode, and 'root' parts of path
+ * Input:
+ * - blocktype, adrcode - determines setting to get
+ * - actname, constname - used to build path
+ * Output:
+ * - array_index - index in property's array (if applicable) to use
+ * - return - the allocated path...
+ */
+char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], int *array_index)
{
- /* can't touch lib-linked data */
- if (ipo->id.lib == NULL)
- return;
-
- /* with only one user, just set local flag */
- if (ipo->id.us == 1) {
- ipo->id.lib= 0;
- ipo->id.flag= LIB_LOCAL;
- new_id(0, (ID *)ipo, 0);
- return;
- }
+ DynStr *path= BLI_dynstr_new();
+ char *propname=NULL, *rpath=NULL;
+ char buf[512];
+ int dummy_index= 0;
- /* when more than 1 user, can only make local for certain blocktypes */
- switch (ipo->blocktype) {
- case ID_OB:
- make_local_obipo(ipo);
+ /* get property name based on blocktype */
+ switch (blocktype) {
+ case ID_OB: /* object */
+ propname= ob_adrcodes_to_paths(adrcode, &dummy_index);
break;
- case ID_MA:
- make_local_matipo(ipo);
+
+ case ID_PO: /* pose channel */
+ propname= pchan_adrcodes_to_paths(adrcode, &dummy_index);
break;
- case ID_KE:
- make_local_keyipo(ipo);
+
+ case ID_KE: /* shapekeys */
+ propname= shapekey_adrcodes_to_paths(adrcode, &dummy_index);
break;
- }
-}
-
-/* ***************************** Keyframe Column Tools ********************************* */
-
-/* add a BezTriple to a column */
-void add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
-{
- CfraElem *ce, *cen;
-
- for (ce= lb->first; ce; ce= ce->next) {
- /* double key? */
- if (ce->cfra == bezt->vec[1][0]) {
- if (bezt->f2 & SELECT) ce->sel= bezt->f2;
- return;
- }
- /* should key be inserted before this column? */
- else if (ce->cfra > bezt->vec[1][0]) break;
- }
-
- /* create a new column */
- cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
- if (ce) BLI_insertlinkbefore(lb, ce, cen);
- else BLI_addtail(lb, cen);
-
- cen->cfra= bezt->vec[1][0];
- cen->sel= bezt->f2;
-}
-
-/* make a list of keyframe 'columns' in an IPO block */
-void make_cfra_list (Ipo *ipo, ListBase *elems)
-{
- IpoCurve *icu;
- BezTriple *bezt;
- int a;
-
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- if (icu->flag & IPO_VISIBLE) {
- /* ... removed old checks for adrcode types from here ...
- * - (was this used for IpoKeys in the past?)
- */
- bezt= icu->bezt;
- if (bezt) {
- for (a=0; a < icu->totvert; a++, bezt++) {
- add_to_cfra_elem(elems, bezt);
- }
- }
- }
+ /* XXX problematic blocktypes */
+ case ID_CU:
+ propname= "speed"; // XXX this was a 'dummy curve' that didn't really correspond to any real var...
+ break;
+
+ case ID_SEQ:
+ //SEQ_FAC1:
+ // poin= &(seq->facf0); // XXX this doesn't seem to be included anywhere in sequencer RNA...
+ break;
+
+ /* special hacks */
+ case -1:
+ /* special case for rotdiff drivers... we don't need a property for this... */
+ break;
+
+ // TODO... add other blocktypes...
+ default:
+ printf("IPO2ANIMATO WARNING: No path for blocktype %d, adrcode %d yet \n", blocktype, adrcode);
+ break;
}
-}
-
-/* ***************************** Timing Stuff ********************************* */
-
-/* This (evil) function is needed to cope with two legacy Blender rendering features
- * mblur (motion blur that renders 'subframes' and blurs them together), and fields
- * rendering. Thus, the use of ugly globals from object.c
- */
-// BAD... EVIL... JUJU...!!!!
-float frame_to_float (Scene *scene, int cfra) /* see also bsystem_time in object.c */
-{
- extern float bluroffs; /* bad stuff borrowed from object.c */
- extern float fieldoffs;
- float ctime;
- ctime= (float)cfra;
- ctime+= bluroffs+fieldoffs;
- ctime*= scene->r.framelen;
-
- return ctime;
-}
-
-/* Calculate the extents of IPO block's keyframes */
-void calc_ipo_range (Ipo *ipo, float *start, float *end)
-{
- IpoCurve *icu;
- float min=999999999.0f, max=-999999999.0f;
- short foundvert=0;
-
- if (ipo) {
- for (icu=ipo->curve.first; icu; icu=icu->next) {
- if (icu->totvert) {
- min= MIN2(min, icu->bezt[0].vec[1][0]);
- max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
- foundvert=1;
- }
- }
- }
-
- /* minimum length is 1 frame */
- if (foundvert) {
- if (min == max) max += 1.0f;
- *start= min;
- *end= max;
- }
- else {
- *start= 0.0f;
- *end= 1.0f;
- }
-}
-
-/* ***************************** IPO Curve Sanity ********************************* */
-/* The functions here are used in various parts of Blender, usually after some editing
- * of keyframe data has occurred. They ensure that keyframe data is properly ordered and
- * that the handles are correctly
- */
-
-/* This function recalculates the handles of an IPO-Curve
- * If the BezTriples have been rearranged, sort them first before using this.
- */
-void calchandles_ipocurve (IpoCurve *icu)
-{
- BezTriple *bezt, *prev, *next;
- int a= icu->totvert;
-
- /* Error checking:
- * - need at least two points
- * - need bezier keys
- * - only bezier-interpolation has handles (for now)
+ /* check if any property found
+ * - blocktype < 0 is special case for a specific type of driver, where we don't need a property name...
*/
- if (ELEM(NULL, icu, icu->bezt) || (a < 2) || ELEM(icu->ipo, IPO_CONST, IPO_LIN))
- return;
-
- /* get initial pointers */
- bezt= icu->bezt;
- prev= NULL;
- next= (bezt + 1);
-
- /* loop over all beztriples, adjusting handles */
- while (a--) {
- /* clamp timing of handles to be on either side of beztriple */
- if (bezt->vec[0][0] > bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
- if (bezt->vec[2][0] < bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
-
- /* calculate autohandles */
- if (icu->flag & IPO_AUTO_HORIZ)
- calchandleNurb(bezt, prev, next, 2); /* 2==special autohandle && keep extrema horizontal */
- else
- calchandleNurb(bezt, prev, next, 1); /* 1==special autohandle */
-
- /* for automatic ease in and out */
- if ((bezt->h1==HD_AUTO) && (bezt->h2==HD_AUTO)) {
- /* only do this on first or last beztriple */
- if ((a==0) || (a==icu->totvert-1)) {
- /* set both handles to have same horizontal value as keyframe */
- if (icu->extrap==IPO_HORIZ) {
- bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
- }
- }
- }
+ if ((propname == NULL) && (blocktype > 0)) {
+ /* nothing was found, so exit */
+ if (array_index)
+ *array_index= 0;
+
+ BLI_dynstr_free(path);
- /* advance pointers for next iteration */
- prev= bezt;
- if (a == 1) next= NULL;
- else next++;
- bezt++;
+ return NULL;
}
-}
-
-/* Use when IPO-Curve with handles has changed
- * It treats all BezTriples with the following rules:
- * - PHASE 1: do types have to be altered?
- * -> Auto handles: become aligned when selection status is NOT(000 || 111)
- * -> Vector handles: become 'nothing' when (one half selected AND other not)
- * - PHASE 2: recalculate handles
-*/
-void testhandles_ipocurve (IpoCurve *icu)
-{
- BezTriple *bezt;
- int a;
-
- /* only beztriples have handles (bpoints don't though) */
- if (ELEM(NULL, icu, icu->bezt))
- return;
-
- /* loop over beztriples */
- for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) {
- short flag= 0;
-
- /* flag is initialised as selection status
- * of beztriple control-points (labelled 0,1,2)
- */
- if (bezt->f1 & SELECT) flag |= (1<<0); // == 1
- if (bezt->f2 & SELECT) flag |= (1<<1); // == 2
- if (bezt->f3 & SELECT) flag |= (1<<2); // == 4
-
- /* one or two handles selected only */
- if (ELEM(flag, 0, 7)==0) {
- /* auto handles become aligned */
- if (bezt->h1==HD_AUTO)
- bezt->h1= HD_ALIGN;
- if(bezt->h2==HD_AUTO)
- bezt->h2= HD_ALIGN;
-
- /* vector handles become 'free' when only one half selected */
- if(bezt->h1==HD_VECT) {
- /* only left half (1 or 2 or 1+2) */
- if (flag < 4)
- bezt->h1= 0;
- }
- if(bezt->h2==HD_VECT) {
- /* only right half (4 or 2+4) */
- if (flag > 3)
- bezt->h2= 0;
- }
- }
+ else {
+ if (array_index)
+ *array_index= dummy_index;
}
-
- /* recalculate handles */
- calchandles_ipocurve(icu);
-}
-
-/* This function sorts BezTriples so that they are arranged in chronological order,
- * as tools working on IPO-Curves expect that the BezTriples are in order.
- */
-void sort_time_ipocurve(IpoCurve *icu)
-{
- short ok= 1;
- /* keep adjusting order of beztriples until nothing moves (bubble-sort) */
- while (ok) {
- ok= 0;
-
- /* currently, will only be needed when there are beztriples */
- if (icu->bezt) {
- BezTriple *bezt;
- int a;
-
- /* loop over ALL points to adjust position in array and recalculate handles */
- for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) {
- /* check if thee's a next beztriple which we could try to swap with current */
- if (a < (icu->totvert-1)) {
- /* swap if one is after the other (and indicate that order has changed) */
- if (bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
- SWAP(BezTriple, *bezt, *(bezt+1));
- ok= 1;
- }
-
- /* if either one of both of the points exceeds crosses over the keyframe time... */
- if ( (bezt->vec[0][0] > bezt->vec[1][0]) && (bezt->vec[2][0] < bezt->vec[1][0]) ) {
- /* swap handles if they have switched sides for some reason */
- SWAP(float, bezt->vec[0][0], bezt->vec[2][0]);
- SWAP(float, bezt->vec[0][1], bezt->vec[2][1]);
- }
- else {
- /* clamp handles */
- if (bezt->vec[0][0] > bezt->vec[1][0])
- bezt->vec[0][0]= bezt->vec[1][0];
- if (bezt->vec[2][0] < bezt->vec[1][0])
- bezt->vec[2][0]= bezt->vec[1][0];
- }
- }
- }
- }
+ /* append preceeding bits to path */
+ if ((actname && actname[0]) && (constname && constname[0])) {
+ /* Constraint in Pose-Channel */
+ sprintf(buf, "pose.pose_channels[\"%s\"].constraints[\"%s\"]", actname, constname);
}
-}
-
-/* This function tests if any BezTriples are out of order, thus requiring a sort */
-int test_time_ipocurve (IpoCurve *icu)
-{
- int a;
-
- /* currently, only need to test beztriples */
- if (icu->bezt) {
- BezTriple *bezt;
-
- /* loop through all beztriples, stopping when one exceeds the one after it */
- for (a=0, bezt= icu->bezt; a < (icu->totvert - 1); a++, bezt++) {
- if (bezt->vec[1][0] > (bezt+1)->vec[1][0])
- return 1;
- }
+ else if (actname && actname[0]) {
+ /* Pose-Channel */
+ sprintf(buf, "pose.pose_channels[\"%s\"]", actname);
}
-
- /* none need any swapping */
- return 0;
-}
-
-/* --------- */
-
-/* The total length of the handles is not allowed to be more
- * than the horizontal distance between (v1-v4).
- * This is to prevent curve loops.
-*/
-void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
-{
- float h1[2], h2[2], len1, len2, len, fac;
-
- /* calculate handle deltas */
- h1[0]= v1[0]-v2[0];
- h1[1]= v1[1]-v2[1];
- h2[0]= v4[0]-v3[0];
- h2[1]= v4[1]-v3[1];
-
- /* calculate distances:
- * - len = span of time between keyframes
- * - len1 = length of handle of start key
- * - len2 = length of handle of end key
- */
- len= v4[0]- v1[0];
- len1= (float)fabs(h1[0]);
- len2= (float)fabs(h2[0]);
-
- /* if the handles have no length, no need to do any corrections */
- if ((len1+len2) == 0.0)
- return;
-
- /* the two handles cross over each other, so force them
- * apart using the proportion they overlap
- */
- if ((len1+len2) > len) {
- fac= len/(len1+len2);
-
- v2[0]= (v1[0]-fac*h1[0]);
- v2[1]= (v1[1]-fac*h1[1]);
+ else if (constname && constname[0]) {
+ /* Constraint in Object */
+ sprintf(buf, "constraints[\"%s\"]", constname);
+ }
+ else
+ strcpy(buf, ""); /* empty string */
+ BLI_dynstr_append(path, buf);
+
+ /* append property to path (only if applicable) */
+ if (blocktype > 0) {
+ /* need to add dot before property if there was anything precceding this */
+ if (buf[0])
+ BLI_dynstr_append(path, ".");
- v3[0]= (v4[0]-fac*h2[0]);
- v3[1]= (v4[1]-fac*h2[1]);
+ /* now write name of property */
+ BLI_dynstr_append(path, propname);
}
-}
-
-/* This function sets the interpolation mode for an entire Ipo-Curve.
- * It is primarily used for patching old files, but is also used in the interface
- * to make sure that all segments of the curve use the same interpolation.
- */
-// XXX move to readfile.c for patching old files only..
-void set_interpolation_ipocurve (IpoCurve *icu, short ipo)
-{
- BezTriple *bezt;
- int a;
- /* validate arguments */
- if (icu == NULL) return;
- if (ELEM3(ipo, IPO_CONST, IPO_LIN, IPO_BEZ)==0) return;
-
- /* set interpolation mode for whole curve */
- icu->ipo= ipo;
+ /* convert to normal MEM_malloc'd string */
+ rpath= BLI_dynstr_get_cstring(path);
+ BLI_dynstr_free(path);
- /* set interpolation mode of all beztriples */
- for (a=0, bezt=icu->bezt; a<icu->totvert; a++, bezt++)
- bezt->ipo= ipo;
+ /* return path... */
+ return rpath;
}
-/* ***************************** Curve Calculations ********************************* */
+/* *************************************************** */
+/* Conversion Utilities */
-/* find root/zero */
-int findzero (float x, float q0, float q1, float q2, float q3, float *o)
+/* Convert IpoDriver to ChannelDriver - will free the old data (i.e. the old driver) */
+static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
{
- double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
- int nr= 0;
-
- c0= q0 - x;
- c1= 3 * (q1 - q0);
- c2= 3 * (q0 - 2*q1 + q2);
- c3= q3 - q0 + 3 * (q1 - q2);
+ ChannelDriver *cdriver;
- if (c3 != 0.0) {
- a= c2/c3;
- b= c1/c3;
- c= c0/c3;
- a= a/3;
-
- p= b/3 - a*a;
- q= (2*a*a*a - a*b + c) / 2;
- d= q*q + p*p*p;
-
- if (d > 0.0) {
- t= sqrt(d);
- o[0]= (float)(Sqrt3d(-q+t) + Sqrt3d(-q-t) - a);
-
- if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
- else return 0;
- }
- else if (d == 0.0) {
- t= Sqrt3d(-q);
- o[0]= (float)(2*t - a);
-
- if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
- o[nr]= (float)(-t-a);
-
- if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
- else return nr;
- }
- else {
- phi= acos(-q / sqrt(-(p*p*p)));
- t= sqrt(-p);
- p= cos(phi/3);
- q= sqrt(3 - 3*p*p);
- o[0]= (float)(2*t*p - a);
-
- if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
- o[nr]= (float)(-t * (p + q) - a);
-
- if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) nr++;
- o[nr]= (float)(-t * (p - q) - a);
-
- if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
- else return nr;
- }
+ /* allocate memory for new driver */
+ cdriver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
+
+ /* if 'pydriver', just copy data across */
+ if (idriver->type == IPO_DRIVER_TYPE_PYTHON) {
+ /* PyDriver only requires the expression to be copied */
+ cdriver->type = DRIVER_TYPE_PYTHON;
+ strcpy(cdriver->expression, idriver->name); // XXX is this safe?
}
else {
- a=c2;
- b=c1;
- c=c0;
-
- if (a != 0.0) {
- // discriminant
- p= b*b - 4*a*c;
-
- if (p > 0) {
- p= sqrt(p);
- o[0]= (float)((-b-p) / (2 * a));
+ /* what to store depends on the 'blocktype' (ID_OB or ID_PO - object or posechannel) */
+ if (idriver->blocktype == ID_AR) {
+ /* ID_PO */
+ if (idriver->adrcode == OB_ROT_DIFF) {
+ /* Rotational Difference is a special type of driver now... */
+ cdriver->type= DRIVER_TYPE_ROTDIFF;
- if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
- o[nr]= (float)((-b+p)/(2*a));
+ /* driver must use bones from same armature... */
+ cdriver->id= cdriver->id2= (ID *)idriver->ob;
- if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
- else return nr;
- }
- else if (p == 0) {
- o[0]= (float)(-b / (2 * a));
- if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
- else return 0;
- }
- }
- else if (b != 0.0) {
- o[0]= (float)(-c/b);
-
- if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
- else return 0;
- }
- else if (c == 0.0) {
- o[0]= 0.0;
- return 1;
- }
-
- return 0;
- }
-}
-
-void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
-{
- float t, c0, c1, c2, c3;
- int a;
-
- c0= f1;
- c1= 3.0f * (f2 - f1);
- c2= 3.0f * (f1 - 2.0f*f2 + f3);
- c3= f4 - f1 + 3.0f * (f2 - f3);
-
- for (a=0; a < b; a++) {
- t= o[a];
- o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
- }
-}
-
-void berekenx (float *f, float *o, int b)
-{
- float t, c0, c1, c2, c3;
- int a;
-
- c0= f[0];
- c1= 3 * (f[3] - f[0]);
- c2= 3 * (f[0] - 2*f[3] + f[6]);
- c3= f[9] - f[0] + 3 * (f[3] - f[6]);
-
- for (a=0; a < b; a++) {
- t= o[a];
- o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
- }
-}
-
-/* ***************************** IPO - Calculations ********************************* */
-
-/* ---------------------- Curve Evaluation --------------------------- */
-
-/* helper function for evaluating drivers:
- * - we need the local transform = current transform - (parent transform + bone transform)
- * - (local transform is on action channel level)
- */
-static void posechannel_get_local_transform (bPoseChannel *pchan, float loc[], float eul[], float size[])
-{
- float parmat[4][4], offs_bone[4][4], imat[4][4];
- float diff_mat[4][4];
-
- /* get first the parent + bone transform in parmat */
- if (pchan->parent) {
- /* bone transform itself */
- Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
-
- /* The bone's root offset (is in the parent's coordinate system) */
- VECCOPY(offs_bone[3], pchan->bone->head);
-
- /* Get the length translation of parent (length along y axis) */
- offs_bone[3][1]+= pchan->parent->bone->length;
-
- Mat4MulSerie(parmat, pchan->parent->pose_mat, offs_bone, NULL, NULL, NULL, NULL, NULL, NULL);
-
- /* invert it */
- Mat4Invert(imat, parmat);
- }
- else {
- Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
- VECCOPY(offs_bone[3], pchan->bone->head);
-
- /* invert it */
- Mat4Invert(imat, offs_bone);
- }
-
- /* difference: current transform - (parent transform + bone transform) */
- Mat4MulMat4(diff_mat, pchan->pose_mat, imat);
-
- /* extract relevant components */
- if (loc)
- VECCOPY(loc, diff_mat[3]);
- if (eul)
- Mat4ToEul(diff_mat, eul);
- if (size)
- Mat4ToSize(diff_mat, size);
-}
-
-/* evaluate an IPO-driver to get a 'time' value to use instead of "ipotime"
- * - "ipotime" is the frame at which IPO-curve is being evaluated
- * - has to return a float value
- */
-static float eval_driver (IpoDriver *driver, float ipotime)
-{
-#ifndef DISABLE_PYTHON
- /* currently, drivers are either PyDrivers (evaluating a PyExpression, or Object/Pose-Channel transforms) */
- if (driver->type == IPO_DRIVER_TYPE_PYTHON) {
- /* check for empty or invalid expression */
- if ( (driver->name[0] == '\0') ||
- (driver->flag & IPO_DRIVER_FLAG_INVALID) )
- {
- return 0.0f;
- }
-
- /* this evaluates the expression using Python,and returns its result:
- * - on errors it reports, then returns 0.0f
- */
- return BPY_pydriver_eval(driver);
- }
- else
-#endif /* DISABLE_PYTHON */
- {
- Object *ob= driver->ob;
-
- /* must have an object to evaluate */
- if (ob == NULL)
- return 0.0f;
-
- /* if a proxy, use the proxy source*/
- if (ob->proxy_from)
- ob= ob->proxy_from;
-
- /* use given object as driver */
- if (driver->blocktype == ID_OB) {
- /* depsgraph failure: ob ipos are calculated in where_is_object, this might get called too late */
- if ((ob->ipo) && (ob->ctime != ipotime)) {
- /* calculate the value of relevant channel on the Object, but do not write the value
- * calculated on to the Object but onto "ipotime" instead
+ /* paths for the two targets get the pointers to the relevant Pose-Channels
+ * - return pointers to Pose-Channels not rotation channels, as calculation code is picky
+ * - old bone names were stored in same var, in idriver->name
+ *
+ * - we use several hacks here - blocktype == -1 specifies that no property needs to be found, and
+ * providing a name for 'actname' will automatically imply Pose-Channel with name 'actname'
*/
- calc_ipo_spec(ob->ipo, driver->adrcode, &ipotime);
- return ipotime;
+ cdriver->rna_path= get_rna_access(-1, -1, idriver->name, NULL, NULL);
+ cdriver->rna_path2= get_rna_access(-1, -1, idriver->name+DRIVER_NAME_OFFS, NULL, NULL);
}
-
- /* return the value of the relevant channel */
- switch (driver->adrcode) {
- case OB_LOC_X:
- return ob->loc[0];
- case OB_LOC_Y:
- return ob->loc[1];
- case OB_LOC_Z:
- return ob->loc[2];
- case OB_ROT_X: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
- return (float)( ob->rot[0]/(M_PI_2/9.0) );
- case OB_ROT_Y: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
- return (float)( ob->rot[1]/(M_PI_2/9.0) );
- case OB_ROT_Z: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
- return (float)( ob->rot[2]/(M_PI_2/9.0) );
- case OB_SIZE_X:
- return ob->size[0];
- case OB_SIZE_Y:
- return ob->size[1];
- case OB_SIZE_Z:
- return ob->size[2];
- }
- }
-
- /* use given pose-channel as driver */
- else { /* ID_AR */
- bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name);
-
- /* must have at least 1 bone to use */
- if (pchan && pchan->bone) {
- /* rotation difference is not a simple driver (i.e. value drives value), but the angle between 2 bones is driving stuff...
- * - the name of the second pchan is also stored in driver->name, but packed after the other one by DRIVER_NAME_OFFS chars
- */
- if (driver->adrcode == OB_ROT_DIFF) {
- bPoseChannel *pchan2= get_pose_channel(ob->pose, driver->name+DRIVER_NAME_OFFS);
-
- if (pchan2 && pchan2->bone) {
- float q1[4], q2[4], quat[4], angle;
-
- Mat4ToQuat(pchan->pose_mat, q1);
- Mat4ToQuat(pchan2->pose_mat, q2);
-
- QuatInv(q1);
- QuatMul(quat, q1, q2);
- angle = 2.0f * (saacos(quat[0]));
- angle= ABS(angle);
-
- return (angle > M_PI) ? (float)((2.0f * M_PI) - angle) : (float)(angle);
- }
- }
+ else {
+ /* 'standard' driver */
+ cdriver->type= DRIVER_TYPE_CHANNEL;
+ cdriver->id= (ID *)idriver->ob;
- /* standard driver */
- else {
- float loc[3], eul[3], size[3];
-
- /* retrieve local transforms to return
- * - we use eulers here NOT quats, so that Objects can be driven by bones easily
- * also, this way is more understandable for users
- */
- posechannel_get_local_transform(pchan, loc, eul, size);
-
- switch (driver->adrcode) {
- case OB_LOC_X:
- return loc[0];
+ switch (idriver->adrcode) {
+ case OB_LOC_X: /* x,y,z location are quite straightforward */
+ cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_X, idriver->name, NULL, &cdriver->array_index);
+ break;
case OB_LOC_Y:
- return loc[1];
+ cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_Y, idriver->name, NULL, &cdriver->array_index);
+ break;
case OB_LOC_Z:
- return loc[2];
- case OB_ROT_X: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
- return (float)( eul[0]/(M_PI_2/9.0) );
- case OB_ROT_Y: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
- return (float)( eul[1]/(M_PI_2/9.0) );
- case OB_ROT_Z: /* hack: euler rotations are divided by 10 deg to fit on same axes as other channels */
- return (float)( eul[2]/(M_PI_2/9.0) );
- case OB_SIZE_X:
- return size[0];
+ cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_Z, idriver->name, NULL, &cdriver->array_index);
+ break;
+
+ case OB_SIZE_X: /* x,y,z scaling are also quite straightforward */
+ cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_X, idriver->name, NULL, &cdriver->array_index);
+ break;
case OB_SIZE_Y:
- return size[1];
+ cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_Y, idriver->name, NULL, &cdriver->array_index);
+ break;
case OB_SIZE_Z:
- return size[2];
+ cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_Z, idriver->name, NULL, &cdriver->array_index);
+ break;
+
+ case OB_ROT_X: /* rotation - we need to be careful with this... XXX (another reason why we need eulers) */
+ case OB_ROT_Y:
+ case OB_ROT_Z:
+ {
+ // XXX this is not yet a 1:1 map, since we'd need euler rotations to make this work nicely (unless we make some hacks)
+ // XXX -1 here is a special hack...
+ cdriver->rna_path= get_rna_access(ID_PO, -1, idriver->name, NULL, NULL);
+ cdriver->array_index= idriver->adrcode - OB_ROT_X;
}
+ break;
}
}
}
- }
+ else {
+ /* ID_OB */
+ cdriver->type= DRIVER_TYPE_CHANNEL;
+ cdriver->id= (ID *)idriver->ob;
+ cdriver->rna_path= get_rna_access(ID_OB, idriver->adrcode, idriver->name, NULL, &cdriver->array_index);
+ }
+ }
- /* return 0.0f, as couldn't find relevant data to use */
- return 0.0f;
+ /* free old driver */
+ MEM_freeN(idriver);
+
+ /* return the new one */
+ return cdriver;
}
-/* evaluate and return the value of the given IPO-curve at the specified frame ("evaltime") */
-float eval_icu (IpoCurve *icu, float evaltime)
+/* Convert IPO-Curve to F-Curve (including Driver data), and free any of the old data that
+ * is not relevant, BUT do not free the IPO-Curve itself...
+ * actname: name of Action-Channel (if applicable) that IPO-Curve's IPO-block belonged to
+ * constname: name of Constraint-Channel (if applicable) that IPO-Curve's IPO-block belonged to
+ */
+static FCurve *icu_to_fcu (IpoCurve *icu, char *actname, char *constname)
{
- float cvalue = 0.0f;
+ FCurve *fcu;
+ int i= 0;
- /* if there is a driver, evaluate it to find value to use as "evaltime"
- * - this value will also be returned as the value of the 'curve', if there are no keyframes
- */
+ /* allocate memory for a new F-Curve */
+ fcu= MEM_callocN(sizeof(FCurve), "FCurve");
+
+ /* convert driver - will free the old one... */
if (icu->driver) {
- /* ipotime now serves as input for the curve */
- evaltime= cvalue= eval_driver(icu->driver, evaltime);
+ fcu->driver= idriver_to_cdriver(icu->driver);
+ icu->driver= NULL;
}
- /* there are keyframes (in the form of BezTriples) which can be interpolated between */
+ /* convert keyframes
+ * - beztriples and bpoints are mutually exclusive, so we won't have both at the same time
+ * - beztriples are more likely to be encountered as they are keyframes (the other type wasn't used yet)
+ */
+ // XXX we need to cope with the nasty old 'bitflag' curves... that will be a task for later
+ fcu->totvert= icu->totvert;
+
if (icu->bezt) {
- /* get pointers */
- BezTriple *bezt, *prevbezt, *lastbezt;
- float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
- float cycdx, cycdy, ofs, cycyofs= 0.0f;
- int a, b;
+ /* allocate new array for keyframes/beztriples */
+ fcu->bezt= MEM_callocN(sizeof(BezTriple)*fcu->totvert, "BezTriples");
- /* get pointers */
- a= icu->totvert-1;
- prevbezt= icu->bezt;
- bezt= prevbezt+1;
- lastbezt= prevbezt + a;
-
- /* extrapolation mode is 'cyclic' - find relative place within a cycle */
- if (icu->extrap & IPO_CYCL) {
- /* ofs is start frame of cycle */
- ofs= prevbezt->vec[1][0];
-
- /* calculate period and amplitude (total height) of a cycle */
- cycdx= lastbezt->vec[1][0] - prevbezt->vec[1][0];
- cycdy= lastbezt->vec[1][1] - prevbezt->vec[1][1];
+ /* check if we need to set interpolation settings (thus doing it the 'slow' way) */
+ if (icu->ipo != IPO_MIXED) {
+ BezTriple *dst, *src;
- /* cycle occurs over some period of time (cycdx should be positive all the time) */
- if (cycdx) {
- /* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle
- * - IPO_CYCLX = (IPO_CYCL + IPO_DIR)
- */
- if (icu->extrap & IPO_DIR) {
- cycyofs = (float)floor((evaltime - ofs) / cycdx);
- cycyofs *= cycdy;
- }
+ /* loop through copying all BezTriples, as we need to set interpolation settings too */
+ for (dst=fcu->bezt, src=icu->bezt; i < fcu->totvert; i++, dst++, src++) {
+ /* firstly, copy BezTriple data */
+ *dst= *src;
- /* calculate where in the cycle we are (overwrite evaltime to reflect this) */
- evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs);
- if (evaltime < ofs) evaltime += cycdx;
- }
- }
-
- /* evaluation time at or past endpoints? */
- if (prevbezt->vec[1][0] >= evaltime) {
- /* before or on first keyframe */
- if ((icu->extrap & IPO_DIR) && (prevbezt->ipo != IPO_CONST)) {
- /* linear or bezier interpolation */
- if (prevbezt->ipo==IPO_LIN) {
- /* Use the next center point instead of our own handle for
- * linear interpolated extrapolate
- */
- if (icu->totvert == 1)
- cvalue= prevbezt->vec[1][1];
- else {
- bezt = prevbezt+1;
- dx= prevbezt->vec[1][0] - evaltime;
- fac= bezt->vec[1][0] - prevbezt->vec[1][0];
-
- /* prevent division by zero */
- if (fac) {
- fac= (bezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
- cvalue= prevbezt->vec[1][1] - (fac * dx);
- }
- else
- cvalue= prevbezt->vec[1][1];
- }
- }
- else {
- /* Use the first handle (earlier) of first BezTriple to calculate the
- * gradient and thus the value of the curve at evaltime
- */
- dx= prevbezt->vec[1][0] - evaltime;
- fac= prevbezt->vec[1][0] - prevbezt->vec[0][0];
-
- /* prevent division by zero */
- if (fac) {
- fac= (prevbezt->vec[1][1] - prevbezt->vec[0][1]) / fac;
- cvalue= prevbezt->vec[1][1] - (fac * dx);
- }
- else
- cvalue= prevbezt->vec[1][1];
- }
- }
- else {
- /* constant (IPO_HORIZ) extrapolation or constant interpolation,
- * so just extend first keyframe's value
- */
- cvalue= prevbezt->vec[1][1];
- }
- }
- else if (lastbezt->vec[1][0] <= evaltime) {
- /* after or on last keyframe */
- if( (icu->extrap & IPO_DIR) && (lastbezt->ipo != IPO_CONST)) {
- /* linear or bezier interpolation */
- if (lastbezt->ipo==IPO_LIN) {
- /* Use the next center point instead of our own handle for
- * linear interpolated extrapolate
- */
- if (icu->totvert == 1)
- cvalue= lastbezt->vec[1][1];
- else {
- prevbezt = lastbezt - 1;
- dx= evaltime - lastbezt->vec[1][0];
- fac= lastbezt->vec[1][0] - prevbezt->vec[1][0];
-
- /* prevent division by zero */
- if (fac) {
- fac= (lastbezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
- cvalue= lastbezt->vec[1][1] + (fac * dx);
- }
- else
- cvalue= lastbezt->vec[1][1];
- }
- }
- else {
- /* Use the gradient of the second handle (later) of last BezTriple to calculate the
- * gradient and thus the value of the curve at evaltime
- */
- dx= evaltime - lastbezt->vec[1][0];
- fac= lastbezt->vec[2][0] - lastbezt->vec[1][0];
-
- /* prevent division by zero */
- if (fac) {
- fac= (lastbezt->vec[2][1] - lastbezt->vec[1][1]) / fac;
- cvalue= lastbezt->vec[1][1] + (fac * dx);
- }
- else
- cvalue= lastbezt->vec[1][1];
- }
- }
- else {
- /* constant (IPO_HORIZ) extrapolation or constant interpolation,
- * so just extend last keyframe's value
- */
- cvalue= lastbezt->vec[1][1];
+ /* now copy interpolation from curve */
+ dst->ipo= icu->ipo;
}
}
else {
- /* evaltime occurs somewhere in the middle of the curve */
- for (a=0; prevbezt && bezt && (a < icu->totvert-1); a++, prevbezt=bezt, bezt++) {
- /* evaltime occurs within the interval defined by these two keyframes */
- if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
- /* value depends on interpolation mode */
- if (prevbezt->ipo == IPO_CONST) {
- /* constant (evaltime not relevant, so no interpolation needed) */
- cvalue= prevbezt->vec[1][1];
- }
- else if (prevbezt->ipo == IPO_LIN) {
- /* linear - interpolate between values of the two keyframes */
- fac= bezt->vec[1][0] - prevbezt->vec[1][0];
-
- /* prevent division by zero */
- if (fac) {
- fac= (evaltime - prevbezt->vec[1][0]) / fac;
- cvalue= prevbezt->vec[1][1] + (fac * (bezt->vec[1][1] - prevbezt->vec[1][1]));
- }
- else
- cvalue= prevbezt->vec[1][1];
- }
- else {
- /* bezier interpolation */
- /* v1,v2 are the first keyframe and its 2nd handle */
- v1[0]= prevbezt->vec[1][0];
- v1[1]= prevbezt->vec[1][1];
- v2[0]= prevbezt->vec[2][0];
- v2[1]= prevbezt->vec[2][1];
- /* v3,v4 are the last keyframe's 1st handle + the last keyframe */
- v3[0]= bezt->vec[0][0];
- v3[1]= bezt->vec[0][1];
- v4[0]= bezt->vec[1][0];
- v4[1]= bezt->vec[1][1];
-
- /* adjust handles so that they don't overlap (forming a loop) */
- correct_bezpart(v1, v2, v3, v4);
-
- /* try to get a value for this position - if failure, try another set of points */
- b= findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
- if (b) {
- berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
- cvalue= opl[0];
- break;
- }
- }
- }
- }
+ /* interpolation already set (from AnimSys2 branch) */
+ memcpy(fcu->bezt, icu->bezt, sizeof(BezTriple)*fcu->totvert);
}
-
- /* apply y-offset (for 'cyclic extrapolation') to calculated value */
- cvalue += cycyofs;
}
-
- /* clamp evaluated value to lie within allowable value range for this channel */
- if (icu->ymin < icu->ymax) {
- CLAMP(cvalue, icu->ymin, icu->ymax);
+ else if (icu->bp) {
+ /* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */
+ //BPoint *bp;
+ //FPoint *fpt;
}
- /* return evaluated value */
- return cvalue;
-}
-
-/* ------------------- IPO-Block/Curve Calculation - General API ----------------------- */
-
-/* calculate the value of the given IPO-curve at the current frame, and set its curval */
-void calc_icu (IpoCurve *icu, float ctime)
-{
- /* calculate and set curval (evaluates driver too) */
- icu->curval= eval_icu(icu, ctime);
-}
-
-/* calculate for the current frame, all IPO-curves in IPO-block that can be evaluated
- * - icu->curval is set for all IPO-curves which are evaluated!
- */
-void calc_ipo (Ipo *ipo, float ctime)
-{
- IpoCurve *icu;
-
- /* if there is no IPO block to evaluate, or whole block is "muted" */
- if (ipo == NULL) return;
- if (ipo->muteipo) return;
-
- /* loop over all curves */
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- /* only evaluated curve if allowed to:
- * - Muted channels should not be evaluated as they shouldn't have any effect
- * --> user explictly turned them off!
- * - Drivers should be evaluated at all updates
- * --> TODO Note: drivers should be separated from standard channels
- * - IPO_LOCK is not set, as it is set by some internal mechanisms to prevent
- * IPO-curve from overwriting data (currently only used for IPO-Record).
- */
- if ((icu->driver) || (icu->flag & IPO_LOCK)==0) {
- if ((icu->flag & IPO_MUTE)==0)
- calc_icu(icu, ctime);
+ /* get rna-path
+ * - we will need to set the 'disabled' flag if no path is able to be made (for now)
+ */
+ fcu->rna_path= get_rna_access(icu->blocktype, icu->adrcode, actname, constname, &fcu->array_index);
+ if (fcu->rna_path == NULL)
+ fcu->flag |= FCURVE_DISABLED;
+
+ /* copy flags */
+ if (icu->flag & IPO_VISIBLE) fcu->flag |= FCURVE_VISIBLE;
+ if (icu->flag & IPO_SELECT) fcu->flag |= FCURVE_SELECTED;
+ if (icu->flag & IPO_ACTIVE) fcu->flag |= FCURVE_ACTIVE;
+ if (icu->flag & IPO_MUTE) fcu->flag |= FCURVE_MUTED;
+ if (icu->flag & IPO_PROTECT) fcu->flag |= FCURVE_PROTECTED;
+ if (icu->flag & IPO_AUTO_HORIZ) fcu->flag |= FCURVE_AUTO_HANDLES;
+
+ /* set extrapolation */
+ switch (icu->extrap) {
+ case IPO_HORIZ: /* constant extrapolation */
+ case IPO_DIR: /* linear extrapolation */
+ {
+ /* just copy, as the new defines match the old ones... */
+ fcu->extend= icu->extrap;
}
- }
-}
-
-/* ------------------- IPO-Block/Curve Calculation - Special Hacks ----------------------- */
-
-/* Calculate and return the value of the 'Time' Ipo-Curve from an Object,
- * OR return the current time if not found
- * - used in object.c -> bsystem_time()
- */
-float calc_ipo_time (Ipo *ipo, float ctime)
-{
- /* only Time IPO from Object IPO-blocks are relevant */
- if ((ipo) && (ipo->blocktype == ID_OB)) {
- IpoCurve *icu= find_ipocurve(ipo, OB_TIME);
-
- /* only calculate (and set icu->curval) for time curve */
- if (icu) {
- calc_icu(icu, ctime);
- return (10.0f * icu->curval);
+ break;
+
+ case IPO_CYCL: /* cyclic extrapolation */
+ case IPO_CYCLX: /* cyclic extrapolation + offset */
+ {
+ /* Add a new FModifier (Cyclic) instead of setting extend value
+ * as that's the new equivilant of that option.
+ */
+ FModifier *fcm= fcurve_add_modifier(fcu, FMODIFIER_TYPE_CYCLES);
+ FMod_Cycles *data= (FMod_Cycles *)fcm->data;
+
+ /* if 'offset' one is in use, set appropriate settings */
+ if (icu->extrap == IPO_CYCLX)
+ data->before_mode= data->after_mode= FCM_EXTRAPOLATE_CYCLIC_OFFSET;
+ else
+ data->before_mode= data->after_mode= FCM_EXTRAPOLATE_CYCLIC;
}
+ break;
}
- /* no appropriate time-curve found */
- return ctime;
+ /* return new F-Curve */
+ return fcu;
}
-/* Evaluate the specified channel in the given IPO block on the specified frame (ctime),
- * writing the value into that channel's icu->curval, but ALSO dumping it in ctime.
- * - Returns success and modifies ctime!
+/* Convert IPO-block (i.e. all its IpoCurves) for some ID to the new system
+ * This assumes that AnimData has been added already. Separation of drivers
+ * from animation data is accomplished here too...
*/
-short calc_ipo_spec (Ipo *ipo, int adrcode, float *ctime)
+static void ipo_to_animdata (ID *id, Ipo *ipo, char *actname, char *constname)
{
- IpoCurve *icu= find_ipocurve(ipo, adrcode);
+ AnimData *adt= BKE_animdata_from_id(id);
+ bAction *act= adt->action;
+ //bActionGroup *grp;
+ IpoCurve *icu, *icn;
+ FCurve *fcu;
+
+ /* sanity check */
+ if ELEM(NULL, id, ipo)
+ return;
+
+ printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s curves:%d \n",
+ id->name+2, ipo->id.name+2, (actname)?actname:"<None>", (constname)?constname:"<None>",
+ BLI_countlist(&ipo->curve));
+
+ /* validate actname and constname
+ * - clear actname if it was one of the generic <builtin> ones (i.e. 'Object', or 'Shapes')
+ * - actname can then be used to assign F-Curves in Action to Action Groups
+ * (i.e. thus keeping the benefits that used to be provided by Action Channels for grouping
+ * F-Curves for bones). This may be added later... for now let's just dump without them...
+ */
+ if (actname) {
+ if ((GS(id->name) == ID_OB) && (strcmp(actname, "Object") == 0))
+ actname= NULL;
+ if ((GS(id->name) == ID_OB) && (strcmp(actname, "Shape") == 0))
+ actname= NULL;
+ }
- /* only evaluate if found */
- if (icu) {
- /* only calculate if allowed to (not locked and not muted)
- * - drivers not taken into account, because this may be called when calculating a driver
+ /* loop over IPO-Curves, freeing as we progress */
+ for (icu= ipo->curve.first; icu; icu= icn) {
+ /* get link to next (for later) */
+ icn= icu->next;
+
+ /* convert IPO-Curve to F-Curve
+ * NOTE: this frees any of the old data stored in the IPO-Curve that isn't needed anymore...
*/
- if ((icu->flag & (IPO_LOCK|IPO_MUTE))==0)
- calc_icu(icu, *ctime);
+ // XXX we need to cope with the nasty old 'bitflag' curves... that will be a task for later
+ // we will need to create a few new curves when doing so, and will need to sift through the keyframes to add relevant data
+ fcu= icu_to_fcu(icu, actname, constname);
+
+ /* conversion path depends on whether it's a driver or not */
+ if (fcu->driver == NULL) {
+ /* try to get action */
+ if (adt->action == NULL)
+ act= adt->action= add_empty_action("ConvertedAction"); // XXX we need a better name for this...
+
+ /* add F-Curve to action */
+ BLI_addtail(&act->curves, fcu);
+ }
+ else {
+ /* add F-Curve to AnimData's drivers */
+ BLI_addtail(&adt->drivers, fcu);
+ }
- /* value resulting from calculations is written into ctime! */
- *ctime= icu->curval;
- return 1;
+ /* free this IpoCurve now that it's been converted */
+ BLI_freelinkN(&ipo->curve, icu);
}
-
- /* couldn't evaluate */
- return 0;
}
-/* ***************************** IPO - DataAPI ********************************* */
-
-/* --------------------- Flush/Execute IPO Values ----------------------------- */
-
-/* Flush IpoCurve->curvals to the data they affect (defined by ID)
- * - not for Actions or Constraints! (those have their own special handling)
+/* Convert Action-block to new system
+ * NOTE: we need to be careful here, as same data-structs are used for new system too!
*/
-void execute_ipo (ID *id, Ipo *ipo)
+static void action_to_animdata (ID *id, bAction *act)
{
- IpoCurve *icu;
- void *poin;
- int type;
+ AnimData *adt= BKE_animdata_from_id(id);
+ bActionChannel *achan, *achann;
+ bConstraintChannel *conchan, *conchann;
- /* don't do anything without an IPO block */
- if (ipo == NULL)
+ /* only continue if there are Action Channels (indicating unconverted data) */
+ if (ELEM(NULL, adt, act->chanbase.first))
return;
-
- /* loop over IPO Curves, getting pointer to var to affect, and write into that pointer */
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- poin= get_ipo_poin(id, icu, &type);
- if (poin) write_ipo_poin(poin, type, icu->curval);
+
+ /* get rid of all Action Groups */
+ // XXX this is risky if there's some old, some new data in the Action...
+ if (act->groups.first)
+ BLI_freelistN(&act->groups);
+
+ /* check if we need to set this Action as the AnimData's action */
+ if (adt->action == NULL) {
+ /* set this Action as AnimData's Action */
+ adt->action= act;
}
-}
-
-/* Flush Action-Channel IPO data to Pose Channel */
-void execute_action_ipo (bActionChannel *achan, bPoseChannel *pchan)
-{
- /* only do this if there's an Action Channel and Pose Channel to use */
- if (achan && achan->ipo && pchan) {
- IpoCurve *icu;
- /* loop over IPO-curves, getting a pointer to pchan var to write to */
- for (icu= achan->ipo->curve.first; icu; icu= icu->next) {
- void *poin= get_pchan_ipo_poin(pchan, icu->adrcode);
+ /* loop through Action-Channels, converting data, freeing as we go */
+ for (achan= act->chanbase.first; achan; achan= achann) {
+ /* get pointer to next Action Channel */
+ achann= achan->next;
+
+ /* convert Action Channel's IPO data */
+ if (achan->ipo) {
+ ipo_to_animdata(id, achan->ipo, achan->name, NULL);
+ achan->ipo->id.us--;
+ achan->ipo= NULL;
+ }
+
+ /* convert constraint channel IPO-data */
+ for (conchan= achan->constraintChannels.first; conchan; conchan= conchann) {
+ /* get pointer to next Constraint Channel */
+ conchann= conchan->next;
- if (poin) {
- /* only euler-rotations are of type float-degree, all others are 'float' only */
- if (ELEM3(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z))
- write_ipo_poin(poin, IPO_FLOAT_DEGR, icu->curval);
- else
- write_ipo_poin(poin, IPO_FLOAT, icu->curval);
+ /* convert Constraint Channel's IPO data */
+ if (conchan->ipo) {
+ ipo_to_animdata(id, conchan->ipo, achan->name, conchan->name);
+ conchan->ipo->id.us--;
+ conchan->ipo= NULL;
}
+
+ /* free Constraint Channel */
+ BLI_freelinkN(&achan->constraintChannels, conchan);
}
- }
-}
-
-
-/* --------------------- Force Calculation + Flush IPO Values ----------------------------- */
-
-/* Calculate values for given IPO block, then flush to all of block's users
- * - for general usage
- */
-void do_ipo (Scene *scene, Ipo *ipo)
-{
- if (ipo) {
- float ctime= frame_to_float(scene, scene->r.cfra);
- /* calculate values, then flush to all users of this IPO block */
- calc_ipo(ipo, ctime);
- do_ipo_nocalc(scene, ipo);
+ /* free Action Channel */
+ BLI_freelinkN(&act->chanbase, achan);
}
}
-/* Calculate values for given Material's IPO block, then flush to given Material only */
-void do_mat_ipo (Scene *scene, Material *ma)
-{
- float ctime;
-
- if (ELEM(NULL, ma, ma->ipo))
- return;
-
- ctime= frame_to_float(scene, scene->r.cfra);
- /* if(ob->ipoflag & OB_OFFS_OB) ctime-= ob->sf; */
-
- /* calculate values for current time, then flush values to given material only */
- calc_ipo(ma->ipo, ctime);
- execute_ipo((ID *)ma, ma->ipo);
-}
+/* *************************************************** */
+/* External API - Only Called from do_versions() */
-/* Calculate values for given Object's IPO block, then flush to given Object only
- * - there's also some funky stuff that looks like it's for scene layers
+/* Called from do_versions() in readfile.c to convert the old 'IPO/adrcode' system
+ * to the new 'Animato/RNA' system.
+ *
+ * The basic method used here, is to loop over datablocks which have IPO-data, and
+ * add those IPO's to new AnimData blocks as Actions.
+ * Action/NLA data only works well for Objects, so these only need to be checked for there.
+ *
+ * Data that has been converted should be freed immediately, which means that it is immediately
+ * clear which datablocks have yet to be converted, and also prevent freeing errors when we exit.
*/
-void do_ob_ipo (Scene *scene, Object *ob)
+// XXX currently done after all file reading...
+void do_versions_ipos_to_animato(Main *main)
{
- float ctime;
- unsigned int lay;
+ ID *id;
+ AnimData *adt;
- if (ob->ipo == NULL)
+ if (main == NULL) {
+ printf("Argh! Main is NULL in do_versions_ipos_to_animato() \n");
return;
-
- /* do not set ob->ctime here: for example when parent in invisible layer */
- ctime= bsystem_time(scene, ob, (float) scene->r.cfra, 0.0);
-
- /* calculate values of */
- calc_ipo(ob->ipo, ctime);
-
- /* Patch: remember localview */
- lay= ob->lay & 0xFF000000;
-
- /* flush IPO values to this object only */
- execute_ipo((ID *)ob, ob->ipo);
-
- /* hack: for layer animation??? - is this what this is? (Aligorith, 28Sep2008) */
- ob->lay |= lay;
- if ((ob->id.name[2]=='S') && (ob->id.name[3]=='C') && (ob->id.name[4]=='E')) {
- if (strcmp(scene->id.name+2, ob->id.name+6)==0) {
- scene->lay= ob->lay;
- //XXX copy_view3d_lock(0);
- /* no redraw here! creates too many calls */
- }
}
-}
-
-/* Only execute those IPO-Curves with drivers, on the current frame, for the given Object
- * - TODO: Drivers should really be made separate from standard anim channels
- */
-void do_ob_ipodrivers (Object *ob, Ipo *ipo, float ctime)
-{
- IpoCurve *icu;
- void *poin;
- int type;
-
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- if (icu->driver) {
- icu->curval= eval_icu(icu, ctime);
-
- poin= get_ipo_poin((ID *)ob, icu, &type);
- if (poin) write_ipo_poin(poin, type, icu->curval);
- }
+
+ /* only convert if version is right */
+ // XXX???
+ if (main->versionfile >= 250) {
+ printf("WARNING: Animation data too new to convert (Version %d) \n", main->versionfile);
+ return;
}
-}
-
-/* Special variation to calculate IPO values for Sequence + perform other stuff */
-void do_seq_ipo (Scene *scene, Sequence *seq, int cfra)
-{
- float ctime, div;
+ else
+ printf("INFO: Converting to Animato... \n"); // xxx debug
+
- /* seq_ipo has an exception: calc both fields immediately */
- if (seq->ipo) {
- if ((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
- ctime = frame_to_float(scene, cfra);
- div = 1.0;
- }
- else {
- ctime= frame_to_float(scene, cfra - seq->startdisp);
- div= (seq->enddisp - seq->startdisp) / 100.0f;
- if (div == 0.0) return;
- }
+ /* objects */
+ for (id= main->object.first; id; id= id->next) {
+ Object *ob= (Object *)id;
+ bPoseChannel *pchan;
+ bConstraint *con;
+ bConstraintChannel *conchan, *conchann;
- /* 2nd field */
- calc_ipo(seq->ipo, (ctime+0.5f)/div);
- execute_ipo((ID *)seq, seq->ipo);
- seq->facf1= seq->facf0;
+ printf("\tconverting ob %s \n", id->name+2);
- /* 1st field */
- calc_ipo(seq->ipo, ctime/div);
- execute_ipo((ID *)seq, seq->ipo);
- }
- else
- seq->facf1= seq->facf0= 1.0f;
-}
-
-/* --------- */
-
-
-/* exception: it does calc for objects...
- * now find out why this routine was used anyway!
- */
-void do_ipo_nocalc (struct Scene *scene, Ipo *ipo)
-{
- Object *ob;
- Material *ma;
- Tex *tex;
- World *wo;
- Lamp *la;
- Camera *ca;
- bSound *snd;
-
- if (ipo == NULL)
- return;
-
- /* only flush IPO values (without calculating first/again) on
- * to the datablocks that use the given IPO block
- */
- switch (ipo->blocktype) {
- case ID_OB:
- for (ob= G.main->object.first; ob; ob= ob->id.next) {
- if (ob->ipo == ipo) do_ob_ipo(scene, ob);
- }
- break;
- case ID_MA:
- for (ma= G.main->mat.first; ma; ma= ma->id.next) {
- if (ma->ipo == ipo) execute_ipo((ID *)ma, ipo);
- }
- break;
- case ID_TE:
- for (tex= G.main->tex.first; tex; tex= tex->id.next) {
- if (tex->ipo == ipo) execute_ipo((ID *)tex, ipo);
- }
- break;
- case ID_WO:
- for (wo= G.main->world.first; wo; wo= wo->id.next) {
- if (wo->ipo == ipo) execute_ipo((ID *)wo, ipo);
- }
- break;
- case ID_LA:
- for (la= G.main->lamp.first; la; la= la->id.next) {
- if (la->ipo == ipo) execute_ipo((ID *)la, ipo);
- }
- break;
- case ID_CA:
- for (ca= G.main->camera.first; ca; ca= ca->id.next) {
- if (ca->ipo == ipo) execute_ipo((ID *)ca, ipo);
- }
- break;
- case ID_SO:
- for (snd= G.main->sound.first; snd; snd= snd->id.next) {
- if (snd->ipo == ipo) execute_ipo((ID *)snd, ipo);
+ /* check if object has any animation data */
+ if ((ob->ipo) || (ob->action) || (ob->nlastrips.first)) {
+ /* Add AnimData block */
+ adt= BKE_id_add_animdata(id);
+
+ /* IPO first */
+ if (ob->ipo) {
+ ipo_to_animdata(id, ob->ipo, NULL, NULL);
+ ob->ipo->id.us--;
+ ob->ipo= NULL;
+ }
+
+ /* now Action */
+ if (ob->action) {
+ action_to_animdata(id, ob->action);
+
+ /* only decrease usercount if this Action isn't now being used by AnimData */
+ if (ob->action != adt->action) {
+ ob->action->id.us--;
+ ob->action= NULL;
+ }
+ }
+
+ /* finally NLA */
+ // XXX todo... for now, new NLA code not hooked up yet, so keep old stuff (but not for too long!)
}
- break;
- }
-}
-
-/* Executes IPO's for whole database on frame change, in a specified order,
- * with datablocks being calculated in alphabetical order
- * - called on scene_update_for_newframe() only
- */
-void do_all_data_ipos (Scene *scene)
-{
- Material *ma;
- Tex *tex;
- World *wo;
- Ipo *ipo;
- Lamp *la;
- Key *key;
- Camera *ca;
- bSound *snd;
- Sequence *seq;
- Editing *ed;
- Base *base;
- float ctime;
-
- ctime= frame_to_float(scene, scene->r.cfra);
-
- /* this exception cannot be depgraphed yet... what todo with objects in other layers?... */
- for (base= scene->base.first; base; base= base->next) {
- Object *ob= base->object;
- /* only update layer when an ipo */
- if (has_ipo_code(ob->ipo, OB_LAY)) {
- do_ob_ipo(scene, ob);
- base->lay= ob->lay;
+ /* check PoseChannels for constraints with local data */
+ if (ob->pose) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for (con= pchan->constraints.first; con; con= con->next) {
+ /* if constraint has own IPO, convert add these to Object
+ * (NOTE: they're most likely to be drivers too)
+ */
+
+ /* check for Action Constraint */
+ // XXX do we really want to do this here?
+ }
+ }
}
- }
-
- /* layers for the set...*/
- if (scene->set) {
- for (base= scene->set->base.first; base; base= base->next) {
- Object *ob= base->object;
+
+ /* check constraint channels - we need to remove them anyway... */
+ for (conchan= ob->constraintChannels.first; conchan; conchan= conchann) {
+ /* get pointer to next Constraint Channel */
+ conchann= conchan->next;
- if (has_ipo_code(ob->ipo, OB_LAY)) {
- do_ob_ipo(scene, ob);
- base->lay= ob->lay;
+ /* convert Constraint Channel's IPO data */
+ if (conchan->ipo) {
+ ipo_to_animdata(id, conchan->ipo, NULL, conchan->name);
+ conchan->ipo->id.us--;
+ conchan->ipo= NULL;
}
+
+ /* free Constraint Channel */
+ BLI_freelinkN(&ob->constraintChannels, conchan);
}
}
- /* Calculate all IPO blocks in use, execept those for Objects */
- for (ipo= G.main->ipo.first; ipo; ipo= ipo->id.next) {
- if ((ipo->id.us) && (ipo->blocktype != ID_OB)) {
- calc_ipo(ipo, ctime);
+ /* shapekeys */
+ for (id= main->key.first; id; id= id->next) {
+ Key *key= (Key *)id;
+
+ printf("\tconverting key %s \n", id->name+2);
+
+ /* we're only interested in the IPO
+ * NOTE: for later, it might be good to port these over to Object instead, as many of these
+ * are likely to be drivers, but it's hard to trace that from here, so move this to Ob loop?
+ */
+ if (key->ipo) {
+ /* Add AnimData block */
+ adt= BKE_id_add_animdata(id);
+
+ /* Convert Shapekey data... */
+ ipo_to_animdata(id, key->ipo, NULL, NULL);
+ key->ipo->id.us--;
+ key->ipo= NULL;
}
}
-
- /* Texture Blocks */
- for (tex= G.main->tex.first; tex; tex= tex->id.next) {
- if (tex->ipo) execute_ipo((ID *)tex, tex->ipo);
- }
-
- /* Material Blocks */
- for (ma= G.main->mat.first; ma; ma= ma->id.next) {
- if (ma->ipo) execute_ipo((ID *)ma, ma->ipo);
- }
- /* World Blocks */
- for (wo= G.main->world.first; wo; wo= wo->id.next) {
- if (wo->ipo) execute_ipo((ID *)wo, wo->ipo);
- }
-
- /* ShapeKey Blocks */
- for (key= G.main->key.first; key; key= key->id.next) {
- if (key->ipo) execute_ipo((ID *)key, key->ipo);
- }
+ // XXX add other types too...
- /* Lamp Blocks */
- for (la= G.main->lamp.first; la; la= la->id.next) {
- if (la->ipo) execute_ipo((ID *)la, la->ipo);
- }
-
- /* Camera Blocks */
- for (ca= G.main->camera.first; ca; ca= ca->id.next) {
- if (ca->ipo) execute_ipo((ID *)ca, ca->ipo);
- }
-
- /* Sound Blocks (Old + Unused) */
- for (snd= G.main->sound.first; snd; snd= snd->id.next) {
- if (snd->ipo) execute_ipo((ID *)snd, snd->ipo);
- }
-
- /* Sequencer: process FAC Ipos used as volume envelopes */
- ed= scene->ed;
- if (ed) {
- for (seq= ed->seqbasep->first; seq; seq= seq->next) {
- if ( ((seq->type == SEQ_RAM_SOUND) || (seq->type == SEQ_HD_SOUND)) &&
- (seq->startdisp <= scene->r.cfra+2) &&
- (seq->enddisp>scene->r.cfra) &&
- (seq->ipo) )
- {
- do_seq_ipo(scene, seq, scene->r.cfra);
- }
- }
- }
+ printf("INFO: animato convert done \n"); // xxx debug
}
-/* --------------------- Assorted ----------------------------- */
-/* clear delta-transforms on all Objects which use the given IPO block */
-void clear_delta_obipo(Ipo *ipo)
-{
- Object *ob;
-
- /* only search if there's an IPO */
- if (ipo == NULL)
- return;
-
- /* search through all objects in database */
- for (ob= G.main->object.first; ob; ob= ob->id.next) {
- /* can only update if not a library */
- if (ob->id.lib == NULL) {
- if (ob->ipo == ipo) {
- memset(&ob->dloc, 0, 12);
- memset(&ob->drot, 0, 12);
- memset(&ob->dsize, 0, 12);
- }
- }
- }
-}
+#if 0 // XXX old animation system
/* ***************************** IPO - DataAPI ********************************* */
@@ -1824,77 +823,6 @@ void clear_delta_obipo(Ipo *ipo)
/* --------------------- Get Pointer API ----------------------------- */
-/* get pointer to pose-channel's channel, but set appropriate flags first */
-// TODO: most channels (except euler rots, which are float-degr) are floats, so do we need type arg?
-void *get_pchan_ipo_poin (bPoseChannel *pchan, int adrcode)
-{
- void *poin= NULL;
-
- switch (adrcode) {
- case AC_QUAT_W:
- poin= &(pchan->quat[0]);
- pchan->flag |= POSE_ROT;
- break;
- case AC_QUAT_X:
- poin= &(pchan->quat[1]);
- pchan->flag |= POSE_ROT;
- break;
- case AC_QUAT_Y:
- poin= &(pchan->quat[2]);
- pchan->flag |= POSE_ROT;
- break;
- case AC_QUAT_Z:
- poin= &(pchan->quat[3]);
- pchan->flag |= POSE_ROT;
- break;
-
- case AC_EUL_X:
- poin= &(pchan->eul[0]);
- pchan->flag |= POSE_ROT;
- //type= IPO_FLOAT_DEGR;
- break;
- case AC_EUL_Y:
- poin= &(pchan->eul[1]);
- pchan->flag |= POSE_ROT;
- //type= IPO_FLOAT_DEGR;
- break;
- case AC_EUL_Z:
- poin= &(pchan->eul[2]);
- pchan->flag |= POSE_ROT;
- //type= IPO_FLOAT_DEGR;
- break;
-
- case AC_LOC_X:
- poin= &(pchan->loc[0]);
- pchan->flag |= POSE_LOC;
- break;
- case AC_LOC_Y:
- poin= &(pchan->loc[1]);
- pchan->flag |= POSE_LOC;
- break;
- case AC_LOC_Z:
- poin= &(pchan->loc[2]);
- pchan->flag |= POSE_LOC;
- break;
-
- case AC_SIZE_X:
- poin= &(pchan->size[0]);
- pchan->flag |= POSE_SIZE;
- break;
- case AC_SIZE_Y:
- poin= &(pchan->size[1]);
- pchan->flag |= POSE_SIZE;
- break;
- case AC_SIZE_Z:
- poin= &(pchan->size[2]);
- pchan->flag |= POSE_SIZE;
- break;
- }
-
- /* return pointer */
- return poin;
-}
-
/* get texture channel */
static void *give_tex_poin (Tex *tex, int adrcode, int *type )
{
@@ -2024,83 +952,6 @@ void *get_ipo_poin (ID *id, IpoCurve *icu, int *type)
/* data is divided into 'blocktypes' based on ID-codes */
switch (GS(id->name)) {
- case ID_OB: /* object channels ----------------------------- */
- {
- Object *ob= (Object *)id;
-
- switch (icu->adrcode) {
- case OB_LOC_X:
- poin= &(ob->loc[0]); break;
- case OB_LOC_Y:
- poin= &(ob->loc[1]); break;
- case OB_LOC_Z:
- poin= &(ob->loc[2]); break;
- case OB_DLOC_X:
- poin= &(ob->dloc[0]); break;
- case OB_DLOC_Y:
- poin= &(ob->dloc[1]); break;
- case OB_DLOC_Z:
- poin= &(ob->dloc[2]); break;
-
- case OB_ROT_X:
- poin= &(ob->rot[0]); *type= IPO_FLOAT_DEGR; break;
- case OB_ROT_Y:
- poin= &(ob->rot[1]); *type= IPO_FLOAT_DEGR; break;
- case OB_ROT_Z:
- poin= &(ob->rot[2]); *type= IPO_FLOAT_DEGR; break;
- case OB_DROT_X:
- poin= &(ob->drot[0]); *type= IPO_FLOAT_DEGR; break;
- case OB_DROT_Y:
- poin= &(ob->drot[1]); *type= IPO_FLOAT_DEGR; break;
- case OB_DROT_Z:
- poin= &(ob->drot[2]); *type= IPO_FLOAT_DEGR; break;
-
- case OB_SIZE_X:
- poin= &(ob->size[0]); break;
- case OB_SIZE_Y:
- poin= &(ob->size[1]); break;
- case OB_SIZE_Z:
- poin= &(ob->size[2]); break;
- case OB_DSIZE_X:
- poin= &(ob->dsize[0]); break;
- case OB_DSIZE_Y:
- poin= &(ob->dsize[1]); break;
- case OB_DSIZE_Z:
- poin= &(ob->dsize[2]); break;
-
- case OB_LAY:
- poin= &(ob->lay); *type= IPO_INT_BIT; break;
-
- case OB_COL_R:
- poin= &(ob->col[0]); break;
- case OB_COL_G:
- poin= &(ob->col[1]); break;
- case OB_COL_B:
- poin= &(ob->col[2]); break;
- case OB_COL_A:
- poin= &(ob->col[3]); break;
-
- case OB_PD_FSTR:
- if (ob->pd) poin= &(ob->pd->f_strength);
- break;
- case OB_PD_FFALL:
- if (ob->pd) poin= &(ob->pd->f_power);
- break;
- case OB_PD_SDAMP:
- if (ob->pd) poin= &(ob->pd->pdef_damp);
- break;
- case OB_PD_RDAMP:
- if (ob->pd) poin= &(ob->pd->pdef_rdamp);
- break;
- case OB_PD_PERM:
- if (ob->pd) poin= &(ob->pd->pdef_perm);
- break;
- case OB_PD_FMAXD:
- if (ob->pd) poin= &(ob->pd->maxdist);
- break;
- }
- }
- break;
case ID_MA: /* material channels ----------------------------- */
{
Material *ma= (Material *)id;
@@ -2193,35 +1044,6 @@ void *get_ipo_poin (ID *id, IpoCurve *icu, int *type)
poin= give_tex_poin(tex, icu->adrcode, type);
}
break;
- case ID_SEQ: /* sequence channels ----------------------------- */
- {
- Sequence *seq= (Sequence *)id;
-
- switch (icu->adrcode) {
- case SEQ_FAC1:
- poin= &(seq->facf0); break;
- }
- }
- break;
- case ID_CU: /* curve channels ----------------------------- */
- {
- poin= &(icu->curval);
- }
- break;
- case ID_KE: /* shapekey channels ----------------------------- */
- {
- Key *key= (Key *)id;
- KeyBlock *kb;
-
- for(kb= key->block.first; kb; kb= kb->next) {
- if (kb->adrcode == icu->adrcode)
- break;
- }
-
- if (kb)
- poin= &(kb->curval);
- }
- break;
case ID_WO: /* world channels ----------------------------- */
{
World *wo= (World *)id;
@@ -2455,482 +1277,5 @@ void *get_ipo_poin (ID *id, IpoCurve *icu, int *type)
return poin;
}
-/* --------------------- IPO-Curve Limits ----------------------------- */
-
-/* set limits for IPO-curve
- * Note: must be synced with UI and PyAPI
- */
-void set_icu_vars (IpoCurve *icu)
-{
- /* defaults. 0.0 for y-extents makes these ignored */
- icu->ymin= icu->ymax= 0.0;
- icu->ipo= IPO_BEZ;
-
- switch (icu->blocktype) {
- case ID_OB: /* object channels ----------------------------- */
- {
- if (icu->adrcode == OB_LAY) {
- icu->ipo= IPO_CONST;
- icu->vartype= IPO_BITS;
- }
- }
- break;
- case ID_MA: /* material channels ----------------------------- */
- {
- if (icu->adrcode < MA_MAP1) {
- switch (icu->adrcode) {
- case MA_HASIZE:
- icu->ymax= 10000.0; break;
- case MA_HARD:
- icu->ymax= 511.0; break;
- case MA_SPEC:
- icu->ymax= 2.0; break;
- case MA_MODE:
- icu->ipo= IPO_CONST;
- icu->vartype= IPO_BITS; break;
- case MA_RAYM:
- icu->ymax= 1.0; break;
- case MA_TRANSLU:
- icu->ymax= 1.0; break;
- case MA_IOR:
- icu->ymin= 1.0;
- icu->ymax= 3.0; break;
- case MA_FRESMIR:
- icu->ymax= 5.0; break;
- case MA_FRESMIRI:
- icu->ymin= 1.0;
- icu->ymax= 5.0; break;
- case MA_FRESTRA:
- icu->ymax= 5.0; break;
- case MA_FRESTRAI:
- icu->ymin= 1.0;
- icu->ymax= 5.0; break;
- case MA_ADD:
- icu->ymax= 1.0; break;
- case MA_EMIT:
- icu->ymax= 2.0; break;
- default:
- icu->ymax= 1.0; break;
- }
- }
- else {
- switch (icu->adrcode & (MA_MAP1-1)) {
- case MAP_OFS_X:
- case MAP_OFS_Y:
- case MAP_OFS_Z:
- case MAP_SIZE_X:
- case MAP_SIZE_Y:
- case MAP_SIZE_Z:
- icu->ymax= 1000.0;
- icu->ymin= -1000.0;
- break;
- case MAP_R:
- case MAP_G:
- case MAP_B:
- case MAP_DVAR:
- case MAP_COLF:
- case MAP_VARF:
- case MAP_DISP:
- icu->ymax= 1.0;
- break;
- case MAP_NORF:
- icu->ymax= 25.0;
- break;
- }
- }
- }
- break;
- case ID_TE: /* texture channels ----------------------------- */
- {
- switch (icu->adrcode & (MA_MAP1-1)) {
- case TE_NSIZE:
- icu->ymin= 0.0001f;
- icu->ymax= 2.0f;
- break;
- case TE_NDEPTH:
- icu->vartype= IPO_SHORT;
- icu->ipo= IPO_CONST;
- icu->ymax= 6.0f;
- break;
- case TE_NTYPE:
- icu->vartype= IPO_SHORT;
- icu->ipo= IPO_CONST;
- icu->ymax= 1.0f;
- break;
- case TE_TURB:
- icu->ymax= 200.0f;
- break;
- case TE_VNW1:
- case TE_VNW2:
- case TE_VNW3:
- case TE_VNW4:
- icu->ymax= 2.0f;
- icu->ymin= -2.0f;
- break;
- case TE_VNMEXP:
- icu->ymax= 10.0f;
- icu->ymin= 0.01f;
- break;
- case TE_VN_DISTM:
- icu->vartype= IPO_SHORT;
- icu->ipo= IPO_CONST;
- icu->ymax= 6.0f;
- break;
- case TE_VN_COLT:
- icu->vartype= IPO_SHORT;
- icu->ipo= IPO_CONST;
- icu->ymax= 3.0f;
- break;
- case TE_ISCA:
- icu->ymax= 10.0f;
- icu->ymin= 0.01f;
- break;
- case TE_DISTA:
- icu->ymax= 10.0f;
- break;
- case TE_MG_TYP:
- icu->vartype= IPO_SHORT;
- icu->ipo= IPO_CONST;
- icu->ymax= 6.0f;
- break;
- case TE_MGH:
- icu->ymin= 0.0001f;
- icu->ymax= 2.0f;
- break;
- case TE_MG_LAC:
- case TE_MG_OFF:
- case TE_MG_GAIN:
- icu->ymax= 6.0f; break;
- case TE_MG_OCT:
- icu->ymax= 8.0f; break;
- case TE_N_BAS1:
- case TE_N_BAS2:
- icu->vartype= IPO_SHORT;
- icu->ipo= IPO_CONST;
- icu->ymax= 8.0f;
- break;
- case TE_COL_R:
- icu->ymax= 0.0f; break;
- case TE_COL_G:
- icu->ymax= 2.0f; break;
- case TE_COL_B:
- icu->ymax= 2.0f; break;
- case TE_BRIGHT:
- icu->ymax= 2.0f; break;
- case TE_CONTRA:
- icu->ymax= 5.0f; break;
- }
- }
- break;
- case ID_SEQ: /* sequence channels ----------------------------- */
- {
- icu->ymax= 1.0f;
- }
- break;
- case ID_CU: /* curve channels ----------------------------- */
- {
- icu->ymax= 1.0f;
- }
- break;
- case ID_WO: /* world channels ----------------------------- */
- {
- if (icu->adrcode < MA_MAP1) {
- switch (icu->adrcode) {
- case WO_EXPOS:
- icu->ymax= 5.0f; break;
-
- case WO_MISTDI:
- case WO_MISTSTA:
- case WO_MISTHI:
- case WO_STARDIST:
- case WO_STARSIZE:
- break;
-
- default:
- icu->ymax= 1.0f;
- break;
- }
- }
- else {
- switch (icu->adrcode & (MA_MAP1-1)) {
- case MAP_OFS_X:
- case MAP_OFS_Y:
- case MAP_OFS_Z:
- case MAP_SIZE_X:
- case MAP_SIZE_Y:
- case MAP_SIZE_Z:
- icu->ymax= 100.0f;
- icu->ymin= -100.0f;
- break;
- case MAP_R:
- case MAP_G:
- case MAP_B:
- case MAP_DVAR:
- case MAP_COLF:
- case MAP_NORF:
- case MAP_VARF:
- case MAP_DISP:
- icu->ymax= 1.0f;
- }
- }
- }
- break;
- case ID_LA: /* lamp channels ----------------------------- */
- {
- if (icu->adrcode < MA_MAP1) {
- switch (icu->adrcode) {
- case LA_ENERGY:
- case LA_DIST:
- break;
-
- case LA_COL_R:
- case LA_COL_G:
- case LA_COL_B:
- case LA_SPOTBL:
- case LA_QUAD1:
- case LA_QUAD2:
- icu->ymax= 1.0f; break;
-
- case LA_SPOTSI:
- icu->ymax= 180.0f; break;
-
- case LA_HALOINT:
- icu->ymax= 5.0f; break;
- }
- }
- else {
- switch (icu->adrcode & (MA_MAP1-1)) {
- case MAP_OFS_X:
- case MAP_OFS_Y:
- case MAP_OFS_Z:
- case MAP_SIZE_X:
- case MAP_SIZE_Y:
- case MAP_SIZE_Z:
- icu->ymax= 100.0f;
- icu->ymin= -100.0f;
- break;
- case MAP_R:
- case MAP_G:
- case MAP_B:
- case MAP_DVAR:
- case MAP_COLF:
- case MAP_NORF:
- case MAP_VARF:
- case MAP_DISP:
- icu->ymax= 1.0f;
- }
- }
- }
- break;
- case ID_CA: /* camera channels ----------------------------- */
- {
- switch (icu->adrcode) {
- case CAM_LENS:
- icu->ymin= 1.0f;
- icu->ymax= 1000.0f;
- break;
- case CAM_STA:
- icu->ymin= 0.001f;
- break;
- case CAM_END:
- icu->ymin= 0.1f;
- break;
-
- case CAM_YF_APERT:
- icu->ymin = 0.0f;
- icu->ymax = 2.0f;
- break;
- case CAM_YF_FDIST:
- icu->ymin = 0.0f;
- icu->ymax = 5000.0f;
- break;
-
- case CAM_SHIFT_X:
- case CAM_SHIFT_Y:
- icu->ymin= -2.0f;
- icu->ymax= 2.0f;
- break;
- }
- }
- break;
- case ID_SO: /* sound channels ----------------------------- */
- {
- switch (icu->adrcode) {
- case SND_VOLUME:
- icu->ymin= 0.0f;
- icu->ymax= 1.0f;
- break;
- case SND_PITCH:
- icu->ymin= -12.0f;
- icu->ymin= 12.0f;
- break;
- case SND_PANNING:
- icu->ymin= 0.0f;
- icu->ymax= 1.0f;
- break;
- case SND_ATTEN:
- icu->ymin= 0.0f;
- icu->ymin= 1.0f;
- break;
- }
- }
- break;
- case ID_PA: /* particle channels ----------------------------- */
- {
- switch (icu->adrcode) {
- case PART_EMIT_LIFE:
- case PART_SIZE:
- case PART_KINK_FREQ:
- case PART_EMIT_VEL:
- case PART_EMIT_AVE:
- case PART_EMIT_SIZE:
- icu->ymin= 0.0f;
- break;
- case PART_CLUMP:
- icu->ymin= -1.0f;
- icu->ymax= 1.0f;
- break;
- case PART_DRAG:
- case PART_DAMP:
- case PART_LENGTH:
- icu->ymin= 0.0f;
- icu->ymax= 1.0f;
- break;
- case PART_KINK_SHAPE:
- icu->ymin= -0.999f;
- icu->ymax= 0.999f;
- break;
- }
- }
- break;
- case ID_CO: /* constraint channels ----------------------------- */
- {
- icu->ymin= 0.0f;
- icu->ymax= 1.0f;
- }
- break;
- }
-
- /* by default, slider limits will be icu->ymin and icu->ymax */
- icu->slide_min= icu->ymin;
- icu->slide_max= icu->ymax;
-}
-
-/* --------------------- Pointer I/O API ----------------------------- */
-
-/* write the given value directly into the given pointer */
-void write_ipo_poin (void *poin, int type, float val)
-{
- /* Note: we only support a limited number of types, with the value
- * to set needing to be cast to the appropriate type first
- * -> (float to integer conversions could be slow)
- */
- switch(type) {
- case IPO_FLOAT:
- *((float *)poin)= val;
- break;
-
- case IPO_FLOAT_DEGR: /* special hack for rotation so that it fits on same axis as other transforms */
- *((float *)poin)= (float)(val * M_PI_2 / 9.0);
- break;
-
- case IPO_INT:
- case IPO_INT_BIT: // fixme... directly revealing bitflag combinations is evil!
- case IPO_LONG:
- *((int *)poin)= (int)val;
- break;
-
- case IPO_SHORT:
- case IPO_SHORT_BIT: // fixme... directly revealing bitflag combinations is evil!
- *((short *)poin)= (short)val;
- break;
-
- case IPO_CHAR:
- case IPO_CHAR_BIT: // fixme... directly revealing bitflag combinations is evil!
- *((char *)poin)= (char)val;
- break;
- }
-}
-
-/* read the value from the pointer that was obtained */
-float read_ipo_poin (void *poin, int type)
-{
- float val = 0.0;
-
- /* Note: we only support a limited number of types, with the value
- * to set needing to be cast to the appropriate type first
- * -> (int to float conversions may loose accuracy in rare cases)
- */
- switch (type) {
- case IPO_FLOAT:
- val= *((float *)poin);
- break;
-
- case IPO_FLOAT_DEGR: /* special hack for rotation so that it fits on same axis as other transforms */
- val= *( (float *)poin);
- val = (float)(val / (M_PI_2/9.0));
- break;
-
- case IPO_INT:
- case IPO_INT_BIT: // fixme... directly revealing bitflag combinations is evil!
- case IPO_LONG:
- val= (float)( *((int *)poin) );
- break;
-
- case IPO_SHORT:
- case IPO_SHORT_BIT: // fixme... directly revealing bitflag combinations is evil!
- val= *((short *)poin);
- break;
-
- case IPO_CHAR:
- case IPO_CHAR_BIT: // fixme... directly revealing bitflag combinations is evil
- val= *((char *)poin);
- break;
- }
-
- /* return value */
- return val;
-}
-
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!! FIXME - BAD CRUFT WARNING !!!!!!!!!!!!!!!!!!!!!!!
-
-
-/* ***************************** IPO <--> GameEngine Interface ********************************* */
-
-/* channels is max 32 items, allocated by calling function */
-short IPO_GetChannels (Ipo *ipo, IPO_Channel *channels)
-{
- IpoCurve *icu;
- int total = 0;
-
- /* don't do anything with no IPO-block */
- if (ipo == NULL)
- return 0;
-
- /* store the IPO-curve's adrcode in the relevant channel slot */
- for (icu=ipo->curve.first; (icu) && (total < 31); icu=icu->next, total++)
- channels[total]= icu->adrcode;
-
- /* return the number of channels stored */
- return total;
-}
-
-/* Get the float value for channel 'channel' at time 'ctime' */
-float IPO_GetFloatValue (Ipo *ipo, IPO_Channel channel, float ctime)
-{
- /* don't evaluate if no IPO to use */
- if (ipo == NULL)
- return 0;
-
- /* only calculate the specified channel */
- calc_ipo_spec(ipo, channel, &ctime);
-
- /* unapply rotation hack, as gameengine doesn't use it */
- if ((OB_ROT_X <= channel) && (channel <= OB_DROT_Z))
- ctime *= (float)(M_PI_2/9.0);
-
- /* return the value of this channel */
- return ctime;
-}
#endif // XXX old animation system
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 718ddf2dc96..8c5bac3019e 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -35,6 +35,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_anim_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
@@ -1367,6 +1368,10 @@ int do_ob_key(Scene *scene, Object *ob)
execute_ipo((ID *)key, key->ipo);
}
#endif // XXX old animation system
+ /* do shapekey local drivers */
+ float ctime= (float)scene->r.cfra; // XXX this needs to be checked
+ printf("ob %s - do shapekey drivers \n", ob->id.name+2);
+ BKE_animsys_evaluate_animdata(&key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
if(ob->type==OB_MESH) return do_mesh_key(scene, ob, ob->data);
else if(ob->type==OB_CURVE) return do_curve_key(scene, ob->data);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index ecd6e22c3ef..b74406f3d3f 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -232,6 +232,7 @@ int set_listbasepointers(Main *main, ListBase **lb)
/* BACKWARDS! also watch order of free-ing! (mesh<->mat) */
lb[a++]= &(main->ipo);
+ lb[a++]= &(main->action); // xxx moved here to avoid problems when freeing with animato (aligorith)
lb[a++]= &(main->key);
lb[a++]= &(main->nodetree);
lb[a++]= &(main->image);
@@ -244,7 +245,6 @@ int set_listbasepointers(Main *main, ListBase **lb)
*/
lb[a++]= &(main->armature);
- lb[a++]= &(main->action);
lb[a++]= &(main->mesh);
lb[a++]= &(main->curve);
@@ -490,7 +490,7 @@ void free_libblock(ListBase *lb, void *idv)
free_camera((Camera*) id);
break;
case ID_IP:
- /*free_ipo((Ipo *)id);*/
+ free_ipo((Ipo *)id);
break;
case ID_KE:
free_key((Key *)id);
@@ -682,52 +682,6 @@ static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, shor
}
}
- /* Silly routine, the only difference between the one
- * above is that it only adds items with a matching
- * blocktype... this should be unified somehow... - zr
- */
-static void IPOnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int blocktype)
-{
- ID *id;
- int i, nids;
-
- for (id= lb->first, nids= 0; id; id= id->next) {
- Ipo *ipo= (Ipo*) id;
-
- if (ipo->blocktype==blocktype)
- nids++;
- }
-
- if (nids>MAX_IDPUP) {
- BLI_dynstr_append(pupds, "DataBrowse %x-2");
- } else {
- for (i=0, id= lb->first; id; id= id->next) {
- Ipo *ipo= (Ipo*) id;
-
- if (ipo->blocktype==blocktype) {
- char buf[32];
-
- if (id==link)
- *nr= i+1;
-
- if (U.uiflag & USER_HIDE_DOT && id->name[2]=='.')
- continue;
-
- get_flags_for_id(id, buf);
-
- BLI_dynstr_append(pupds, buf);
- BLI_dynstr_append(pupds, id->name+2);
- sprintf(buf, "%%x%d", i+1);
- BLI_dynstr_append(pupds, buf);
-
- if(id->next)
- BLI_dynstr_append(pupds, "|");
-
- i++;
- }
- }
- }
-}
/* used by headerbuttons.c buttons.c editobject.c editseq.c */
/* if nr==NULL no MAX_IDPUP, this for non-header browsing */
@@ -775,28 +729,6 @@ void IMAnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb
}
-/* only used by headerbuttons.c */
-void IPOnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr, int blocktype)
-{
- DynStr *pupds= BLI_dynstr_new();
-
- if (title) {
- BLI_dynstr_append(pupds, title);
- BLI_dynstr_append(pupds, "%t|");
- }
-
- if (extraops) {
- BLI_dynstr_append(pupds, extraops);
- if (BLI_dynstr_get_len(pupds))
- BLI_dynstr_append(pupds, "|");
- }
-
- IPOnames_to_dyn_pupstring(pupds, lb, link, nr, blocktype);
-
- *str= BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-}
-
/* used by buttons.c library.c mball.c */
void splitIDname(char *name, char *left, int *nr)
{
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 2718981e398..15fde4420f0 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2274,7 +2274,7 @@ void object_handle_update(Scene *scene, Object *ob)
if(ob->recalc & OB_RECALC_OB) {
- // printf("recalcob %s\n", ob->id.name+2);
+ printf("recalcob %s\n", ob->id.name+2);
/* handle proxy copy for target */
if(ob->id.lib && ob->proxy_from) {
@@ -2296,7 +2296,7 @@ void object_handle_update(Scene *scene, Object *ob)
if(ob->recalc & OB_RECALC_DATA) {
- // printf("recalcdata %s\n", ob->id.name+2);
+ printf("recalcdata %s\n", ob->id.name+2);
/* includes all keys and modifiers */
if(ob->type==OB_MESH) {
@@ -2312,29 +2312,20 @@ void object_handle_update(Scene *scene, Object *ob)
else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
makeDispListCurveTypes(scene, ob, 0);
}
- else if(ob->type==OB_LATTICE) {
- lattice_calc_modifiers(scene, ob);
- }
- else if(ob->type==OB_CAMERA) {
- //Camera *cam = (Camera *)ob->data;
-
- // xxx old animation code here
- //calc_ipo(cam->ipo, frame_to_float(scene, scene->r.cfra));
- //execute_ipo(&cam->id, cam->ipo);
+ else if(ELEM(ob->type, OB_CAMERA, OB_LAMP)) {
+ ID *data_id= (ID *)ob->data;
+ AnimData *adt= BKE_animdata_from_id(data_id);
+ float ctime= (float)scene->r.cfra; // XXX this is bad...
- // in new system, this has already been done! - aligorith
+ /* evaluate drivers */
+ BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS);
}
- else if(ob->type==OB_LAMP) {
- //Lamp *la = (Lamp *)ob->data;
-
- // xxx old animation code here
- //calc_ipo(la->ipo, frame_to_float(scene, scene->r.cfra));
- //execute_ipo(&la->id, la->ipo);
-
- // in new system, this has already been done! - aligorith
+ else if(ob->type==OB_LATTICE) {
+ lattice_calc_modifiers(scene, ob);
}
else if(ob->type==OB_ARMATURE) {
/* this happens for reading old files and to match library armatures with poses */
+ // XXX this won't screw up the pose set already...
if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
armature_rebuild_pose(ob, ob->data);
@@ -2343,7 +2334,6 @@ void object_handle_update(Scene *scene, Object *ob)
// printf("pose proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name);
}
else {
- //do_all_pose_actions(scene, ob); // xxx old animation system
where_is_pose(scene, ob);
}
}
diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript
index 5a445ad0cfc..1aeb6bd9b83 100644
--- a/source/blender/blenloader/SConscript
+++ b/source/blender/blenloader/SConscript
@@ -11,4 +11,4 @@ incs += ' ' + env['BF_ZLIB_INC']
defs = []
-env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [165, 30] )
+env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [135, 30] )
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index b1ce482cbc5..23f22523e19 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -122,6 +122,7 @@
#include "BKE_global.h" // for G
#include "BKE_group.h"
#include "BKE_image.h"
+#include "BKE_ipo.h"
#include "BKE_key.h" //void set_four_ipo
#include "BKE_lattice.h"
#include "BKE_library.h" // for wich_libbase
@@ -1823,6 +1824,7 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
}
}
+/* NOTE: this assumes that link_list has already been called on the list */
static void direct_link_fcurves(FileData *fd, ListBase *list)
{
FCurve *fcu;
@@ -1904,8 +1906,8 @@ static void direct_link_action(FileData *fd, bAction *act)
bActionChannel *achan; // XXX depreceated - old animation system
bActionGroup *agrp;
- link_list(fd, &act->curves); // xxx - do we need to patch the data for this?
- link_list(fd, &act->chanbase);
+ link_list(fd, &act->curves);
+ link_list(fd, &act->chanbase); // XXX depreceated - old animation system
link_list(fd, &act->groups);
link_list(fd, &act->markers);
@@ -1951,6 +1953,7 @@ static void direct_link_animdata(FileData *fd, AnimData *adt)
return;
/* link drivers */
+ link_list(fd, &adt->drivers);
direct_link_fcurves(fd, &adt->drivers);
/* link overrides */
@@ -8665,14 +8668,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 3)) {
bScreen *sc;
- Ipo *ipo;
- IpoCurve *icu;
-
- /* fix IPO-curves to work with new interpolation options */
- //for (ipo=main->ipo.first; ipo; ipo= ipo->id.next) {
- // for (icu= ipo->curve.first; icu; icu= icu->next)
- // set_interpolation_ipocurve(icu, icu->ipo); // function removed (XXX add it here)
- //}
/* adjust default settings for Animation Editors */
for (sc= main->screen.first; sc; sc= sc->id.next) {
@@ -8719,10 +8714,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for(screen= main->screen.first; screen; screen= screen->id.next)
do_versions_windowmanager_2_50(screen);
+ /* old Animation System (using IPO's) needs to be converted to the new Animato system
+ * (NOTE: conversion code in blenkernel/intern/ipo.c for now)
+ */
+ //do_versions_ipos_to_animato(main);
+
/* struct audio data moved to renderdata */
for(scene= main->scene.first; scene; scene= scene->id.next) {
scene->r.audio = scene->audio;
-
+
if(!scene->toolsettings->uv_selectmode)
scene->toolsettings->uv_selectmode= UV_SELECT_VERTEX;
}
@@ -8836,7 +8836,7 @@ static void lib_link_all(FileData *fd, Main *main)
lib_link_material(fd, main);
lib_link_texture(fd, main);
lib_link_image(fd, main);
- lib_link_ipo(fd, main);
+ lib_link_ipo(fd, main); // XXX depreceated... still needs to be maintained for version patches still
lib_link_key(fd, main);
lib_link_world(fd, main);
lib_link_lamp(fd, main);
@@ -9136,7 +9136,6 @@ static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
/* own action */
expand_doit(fd, mainvar, adt->action);
- expand_action(fd, mainvar, adt->action); // XXX this call is only used for patching old animation system
/* drivers - assume that these F-Curves have driver data to be in this list... */
for (fcd= adt->drivers.first; fcd; fcd= fcd->next) {
@@ -9167,6 +9166,9 @@ static void expand_group(FileData *fd, Main *mainvar, Group *group)
static void expand_key(FileData *fd, Main *mainvar, Key *key)
{
expand_doit(fd, mainvar, key->ipo); // XXX depreceated - old animation system
+
+ if(key->adt)
+ expand_animdata(fd, mainvar, key->adt);
}
static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 39a477f30fb..48b3bbb918c 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -1058,6 +1058,8 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
}
break;
+ case ANIMTYPE_FILLACTD:
+ case ANIMTYPE_FILLMATD:
case ANIMTYPE_DSSKEY:
{
if (sel) glColor4ub(col2b[0], col2b[1], col2b[2], 0x45);
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index c54ceba67f8..8b89c41775c 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -255,32 +255,15 @@ static float actcopy_firstframe= 999999999.0f;
// XXX find some header to put this in!
void free_actcopybuf ()
{
-#if 0 // XXX old animation system
- bActionChannel *achan, *anext;
- bConstraintChannel *conchan, *cnext;
+ FCurve *fcu, *fcn;
- for (achan= actcopybuf.first; achan; achan= anext) {
- anext= achan->next;
-
- if (achan->ipo) {
- free_ipo(achan->ipo);
- MEM_freeN(achan->ipo);
- }
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=cnext) {
- cnext= conchan->next;
-
- if (conchan->ipo) {
- free_ipo(conchan->ipo);
- MEM_freeN(conchan->ipo);
- }
-
- BLI_freelinkN(&achan->constraintChannels, conchan);
- }
-
- BLI_freelinkN(&actcopybuf, achan);
+ /* free_fcurve() frees F-Curve memory too, but we don't need to do remlink first, as we're freeing all
+ * channels anyway, and the freeing func only cares about the data it's given
+ */
+ for (fcu= actcopybuf.first; fcu; fcu= fcn) {
+ fcn= fcu->next;
+ free_fcurve(fcu);
}
-#endif // XXX old animation system
actcopybuf.first= actcopybuf.last= NULL;
actcopy_firstframe= 999999999.0f;
@@ -292,7 +275,7 @@ void free_actcopybuf ()
* Only the selected action channels gets their selected keyframes copied.
*/
static short copy_action_keys (bAnimContext *ac)
-{
+{
#if 0 // XXX old animation system
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index b1258e05f56..3731efb294c 100755
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -124,7 +124,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_ui_text(prop, "Location", "");
- prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_VECTOR);
+ prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_ui_text(prop, "Scale", "");