From f721ce13fb529f4fde4668c989c786e4c7d7d708 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 22 Oct 2007 02:43:07 +0000 Subject: == Action Constraint == Now the Action Constraint can be applied to Objects as well as Bones! --- source/blender/blenkernel/BKE_action.h | 8 +++- source/blender/blenkernel/BKE_armature.h | 2 +- source/blender/blenkernel/BKE_object.h | 2 + source/blender/blenkernel/intern/action.c | 42 ++++++++++++++++++++- source/blender/blenkernel/intern/constraint.c | 53 ++++++++++++++------------- source/blender/blenkernel/intern/object.c | 3 +- source/blender/src/buttons_object.c | 8 ++-- source/blender/src/editconstraint.c | 8 ++-- 8 files changed, 86 insertions(+), 40 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 68a6be04735..cbec4cf04fb 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -119,8 +119,12 @@ void calc_action_range(const struct bAction *act, float *start, float *end, int /** * Set the pose channels from the given action. */ -void extract_pose_from_action(struct bPose *pose, struct bAction *act, - float ctime); +void extract_pose_from_action(struct bPose *pose, struct bAction *act, float ctime); + +/** + * Get the effects of the given action using a workob + */ +void what_does_obaction(struct Object *ob, struct bAction *act, float cframe); /** * Iterate through the action channels of the action diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 0e3857603b6..fb527051a0d 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -80,7 +80,7 @@ void make_local_armature(struct bArmature *arm); struct bArmature *copy_armature(struct bArmature *arm); void bone_flip_name (char *name, int strip_number); -struct bArmature* get_armature (struct Object* ob); +struct bArmature *get_armature (struct Object *ob); struct Bone *get_named_bone (struct bArmature *arm, const char *name); float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index b834116f11d..6e363515f41 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -45,6 +45,7 @@ struct BoundBox; struct View3D; struct SoftBody; struct Group; +struct bAction; void clear_workob(void); void copy_baseflags(void); @@ -98,6 +99,7 @@ void where_is_object(struct Object *ob); void where_is_object_simul(struct Object *ob); void what_does_parent(struct Object *ob); + struct BoundBox *unit_boundbox(void); void boundbox_set_from_min_max(struct BoundBox *bb, float min[3], float max[3]); struct BoundBox *object_get_boundbox(struct Object *ob); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 22e621a27e2..b04e0240873 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -1061,6 +1061,46 @@ static Object *get_parent_path(Object *ob) /* ************** do the action ************ */ +/* For the calculation of the effects of an action at the given frame on an object + * This is currently only used for the action constraint + */ +void what_does_obaction (Object *ob, bAction *act, float cframe) +{ + ListBase tchanbase= {NULL, NULL}; + + clear_workob(); + Mat4CpyMat4(workob.obmat, ob->obmat); + Mat4CpyMat4(workob.parentinv, ob->parentinv); + Mat4CpyMat4(workob.constinv, ob->constinv); + workob.parent= ob->parent; + workob.track= ob->track; + + workob.trackflag= ob->trackflag; + workob.upflag= ob->upflag; + + workob.partype= ob->partype; + workob.par1= ob->par1; + workob.par2= ob->par2; + workob.par3= ob->par3; + + workob.constraints.first = ob->constraints.first; + workob.constraints.last = ob->constraints.last; + + strcpy(workob.parsubstr, ob->parsubstr); + + /* extract_ipochannels_from_action needs id's! */ + workob.action= act; + + extract_ipochannels_from_action(&tchanbase, &ob->id, act, "Object", bsystem_time(&workob, cframe, 0.0)); + + if (tchanbase.first) { + execute_ipochannels(&tchanbase); + BLI_freelistN(&tchanbase); + } +} + +/* ----- nla, etc. --------- */ + static void do_nla(Object *ob, int blocktype) { bPose *tpose= NULL; @@ -1331,5 +1371,3 @@ void do_all_object_actions(Object *ob) do_nla(ob, ID_OB); } } - - diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index b46504b0e6d..c9fb21d4333 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1951,8 +1951,6 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint bActionConstraint *data = con->data; if (VALID_CONS_TARGET(ct)) { - bPose *pose; - bPoseChannel *pchan, *tchan; float tempmat[4][4], vec[3]; float s, t; short axis; @@ -1960,13 +1958,6 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint /* initialise return matrix */ Mat4One(ct->matrix); - /* currently, only pose-channels are supported owners for action constraints, as - * the method for extracting the pose from the actions is currently hardcoded for - * poses... this may change in the future - */ - if (cob->type != CONSTRAINT_OBTYPE_BONE) - return; - /* get the transform matrix of the target */ constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space); @@ -2001,22 +1992,34 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint t = ( s * (data->end-data->start)) + data->start; /* Get the appropriate information from the action */ - /* a temporary pose is made for this... - * TODO: extend this to objects too - */ - pose = MEM_callocN(sizeof(bPose), "pose"); - - pchan = cob->pchan; - tchan= verify_pose_channel(pose, pchan->name); - extract_pose_from_action(pose, data->act, t); - - chan_calc_mat(tchan); - - Mat4CpyMat4(ct->matrix, tchan->chan_mat); - - /* Clean up */ - free_pose_channels(pose); - MEM_freeN(pose); + if (cob->type == CONSTRAINT_OBTYPE_BONE) { + bPose *pose; + bPoseChannel *pchan, *tchan; + + /* make a temporary pose and evaluate using that */ + pose = MEM_callocN(sizeof(bPose), "pose"); + + pchan = cob->pchan; + tchan= verify_pose_channel(pose, pchan->name); + extract_pose_from_action(pose, data->act, t); + + chan_calc_mat(tchan); + + Mat4CpyMat4(ct->matrix, tchan->chan_mat); + + /* Clean up */ + free_pose_channels(pose); + MEM_freeN(pose); + } + else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) { + /* evaluate using workob */ + what_does_obaction(cob->ob, data->act, t); + object_to_mat4(&workob, ct->matrix); + } + else { + /* behaviour undefined... */ + puts("Error: unknown owner type for Action Constraint"); + } } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 9f4c8f1607b..f016e4e47a0 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1838,7 +1838,6 @@ for a lamp that is the child of another object */ /* for calculation of the inverse parent transform, only used for editor */ void what_does_parent(Object *ob) { - clear_workob(); Mat4One(workob.obmat); Mat4One(workob.parentinv); @@ -1857,7 +1856,7 @@ void what_does_parent(Object *ob) workob.constraints.first = ob->constraints.first; workob.constraints.last = ob->constraints.last; - strcpy (workob.parsubstr, ob->parsubstr); + strcpy(workob.parsubstr, ob->parsubstr); where_is_object(&workob); } diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 906160d66c9..8bed4888d48 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1595,13 +1595,13 @@ static uiBlock *add_constraintmenu(void *arg_unused) uiDefBut(block, BUTM, B_CONSTRAINT_ADD_RIGIDBODYJOINT, "Rigid Body Joint", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");//rcruiz + uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + if (ob->flag & OB_POSEMODE) { - uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, BUTM, B_CONSTRAINT_ADD_KINEMATIC, "IK Solver", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); - uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION, "Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); - } + uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION, "Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_PYTHON, "Script", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c index c0bc964c07a..270296fda9d 100644 --- a/source/blender/src/editconstraint.c +++ b/source/blender/src/editconstraint.c @@ -740,15 +740,15 @@ void add_constraint(int only_IK) else if(obsel) nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18"); else - nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Script%x18"); + nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18"); } else { if(obsel && obsel->type==OB_CURVE) - nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Script%x18"); + nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18"); else if(obsel) - nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Script%x18"); + nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18"); else - nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Script%x18"); + nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18"); } } -- cgit v1.2.3