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_armature.h20
-rw-r--r--source/blender/blenkernel/intern/armature_update.c58
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc62
-rw-r--r--source/blender/makesdna/DNA_action_types.h7
6 files changed, 106 insertions, 44 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 60fb79d75d5..f6de39c897e 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -169,41 +169,39 @@ void BKE_splineik_execute_tree(struct Scene *scene, struct Object *ob, struct bP
void BKE_pose_eval_init(struct EvaluationContext *eval_ctx,
struct Scene *scene,
- struct Object *ob,
- struct bPose *pose);
+ struct Object *ob);
void BKE_pose_eval_init_ik(struct EvaluationContext *eval_ctx,
struct Scene *scene,
- struct Object *ob,
- struct bPose *pose);
+ struct Object *ob);
void BKE_pose_eval_bone(struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
- struct bPoseChannel *pchan);
+ int pchan_index);
void BKE_pose_constraints_evaluate(struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
- struct bPoseChannel *pchan);
+ int pchan_index);
void BKE_pose_bone_done(struct EvaluationContext *eval_ctx,
- struct bPoseChannel *pchan);
+ struct Object *ob,
+ int pchan_index);
void BKE_pose_iktree_evaluate(struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
- struct bPoseChannel *rootchan);
+ int rootchan_index);
void BKE_pose_splineik_evaluate(struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
- struct bPoseChannel *rootchan);
+ int rootchan_index);
void BKE_pose_eval_flush(struct EvaluationContext *eval_ctx,
struct Scene *scene,
- struct Object *ob,
- struct bPose *pose);
+ struct Object *ob);
void BKE_pose_eval_proxy_copy(struct EvaluationContext *eval_ctx,
struct Object *ob);
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 56e9cce1825..95a26814e37 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -553,10 +553,10 @@ void BKE_splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_roo
void BKE_pose_eval_init(EvaluationContext *UNUSED(eval_ctx),
Scene *UNUSED(scene),
- Object *ob,
- bPose *pose)
+ Object *ob)
{
- bPoseChannel *pchan;
+ bPose *pose = ob->pose;
+ BLI_assert(pose != NULL);
DEG_debug_print_eval(__func__, ob->id.name, ob);
@@ -569,16 +569,21 @@ void BKE_pose_eval_init(EvaluationContext *UNUSED(eval_ctx),
/* imat is needed for solvers. */
invert_m4_m4(ob->imat, ob->obmat);
- /* 1. clear flags */
- for (pchan = pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
+ const int num_channels = BLI_listbase_count(&pose->chanbase);
+ pose->chan_array = MEM_malloc_arrayN(
+ num_channels, sizeof(bPoseChannel*), "pose->chan_array");
+
+ /* clear flags */
+ int pchan_index = 0;
+ for (bPoseChannel *pchan = pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
pchan->flag &= ~(POSE_DONE | POSE_CHAIN | POSE_IKTREE | POSE_IKSPLINE);
+ pose->chan_array[pchan_index++] = pchan;
}
}
void BKE_pose_eval_init_ik(EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
- Object *ob,
- bPose *UNUSED(pose))
+ Object *ob)
{
DEG_debug_print_eval(__func__, ob->id.name, ob);
BLI_assert(ob->type == OB_ARMATURE);
@@ -587,11 +592,11 @@ void BKE_pose_eval_init_ik(EvaluationContext *UNUSED(eval_ctx),
if (arm->flag & ARM_RESTPOS) {
return;
}
- /* 2a. construct the IK tree (standard IK) */
+ /* construct the IK tree (standard IK) */
BIK_initialize_tree(scene, ob, ctime);
- /* 2b. construct the Spline IK trees
+ /* construct the Spline IK trees
* - this is not integrated as an IK plugin, since it should be able
- * to function in conjunction with standard IK
+ * to function in conjunction with standard IK
*/
BKE_pose_splineik_init_tree(scene, ob, ctime);
}
@@ -599,8 +604,10 @@ void BKE_pose_eval_init_ik(EvaluationContext *UNUSED(eval_ctx),
void BKE_pose_eval_bone(EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
- bPoseChannel *pchan)
+ int pchan_index)
{
+ BLI_assert(ob->pose != NULL);
+ bPoseChannel *pchan = ob->pose->chan_array[pchan_index];
DEG_debug_print_eval_subdata(
__func__, ob->id.name, ob, "pchan", pchan->name, pchan);
BLI_assert(ob->type == OB_ARMATURE);
@@ -635,8 +642,10 @@ void BKE_pose_eval_bone(EvaluationContext *UNUSED(eval_ctx),
void BKE_pose_constraints_evaluate(EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
- bPoseChannel *pchan)
+ int pchan_index)
{
+ BLI_assert(ob->pose != NULL);
+ bPoseChannel *pchan = ob->pose->chan_array[pchan_index];
DEG_debug_print_eval_subdata(
__func__, ob->id.name, ob, "pchan", pchan->name, pchan);
bArmature *arm = (bArmature *)ob->data;
@@ -655,8 +664,11 @@ void BKE_pose_constraints_evaluate(EvaluationContext *UNUSED(eval_ctx),
}
void BKE_pose_bone_done(EvaluationContext *UNUSED(eval_ctx),
- bPoseChannel *pchan)
+ struct Object *ob,
+ int pchan_index)
{
+ BLI_assert(ob->pose != NULL);
+ bPoseChannel *pchan = ob->pose->chan_array[pchan_index];
float imat[4][4];
DEG_debug_print_eval(__func__, pchan->name, pchan);
if (pchan->bone) {
@@ -668,8 +680,10 @@ void BKE_pose_bone_done(EvaluationContext *UNUSED(eval_ctx),
void BKE_pose_iktree_evaluate(EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
- bPoseChannel *rootchan)
+ int rootchan_index)
{
+ BLI_assert(ob->pose != NULL);
+ bPoseChannel *rootchan = ob->pose->chan_array[rootchan_index];
DEG_debug_print_eval_subdata(
__func__, ob->id.name, ob, "rootchan", rootchan->name, rootchan);
BLI_assert(ob->type == OB_ARMATURE);
@@ -684,9 +698,11 @@ void BKE_pose_iktree_evaluate(EvaluationContext *UNUSED(eval_ctx),
void BKE_pose_splineik_evaluate(EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
- bPoseChannel *rootchan)
+ int rootchan_index)
{
+ BLI_assert(ob->pose != NULL);
+ bPoseChannel *rootchan = ob->pose->chan_array[rootchan_index];
DEG_debug_print_eval_subdata(
__func__, ob->id.name, ob, "rootchan", rootchan->name, rootchan);
BLI_assert(ob->type == OB_ARMATURE);
@@ -700,17 +716,23 @@ void BKE_pose_splineik_evaluate(EvaluationContext *UNUSED(eval_ctx),
void BKE_pose_eval_flush(EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
- Object *ob,
- bPose *UNUSED(pose))
+ Object *ob)
{
+ bPose *pose = ob->pose;
+ BLI_assert(pose != NULL);
+
float ctime = BKE_scene_frame_get(scene); /* not accurate... */
DEG_debug_print_eval(__func__, ob->id.name, ob);
BLI_assert(ob->type == OB_ARMATURE);
- /* 6. release the IK tree */
+ /* release the IK tree */
BIK_release_tree(scene, ob, ctime);
ob->recalc &= ~OB_RECALC_ALL;
+
+ BLI_assert(pose->chan_array != NULL);
+ MEM_freeN(pose->chan_array);
+ pose->chan_array = NULL;
}
void BKE_pose_eval_proxy_copy(EvaluationContext *UNUSED(eval_ctx), Object *ob)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 7b51ddcce92..c35e49b801f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5076,6 +5076,7 @@ static void direct_link_pose(FileData *fd, bPose *pose)
link_list(fd, &pose->agroups);
pose->chanhash = NULL;
+ pose->chan_array = NULL;
for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
pchan->bone = NULL;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 9d47dc6bced..17d2a4ad558 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -132,7 +132,7 @@ struct DepsgraphNodeBuilder {
void build_object_data(Object *object);
void build_object_transform(Object *object);
void build_object_constraints(Object *object);
- void build_pose_constraints(Object *object, bPoseChannel *pchan);
+ void build_pose_constraints(Object *object, bPoseChannel *pchan, int pchan_index);
void build_rigidbody(Scene *scene);
void build_particles(Object *object);
void build_cloth(Object *object);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index 73bbbcfa0b3..0c7c3d13d93 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -64,16 +64,24 @@ extern "C" {
namespace DEG {
-void DepsgraphNodeBuilder::build_pose_constraints(Object *object, bPoseChannel *pchan)
+void DepsgraphNodeBuilder::build_pose_constraints(Object *object,
+ bPoseChannel *pchan,
+ int pchan_index)
{
/* create node for constraint stack */
add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
- function_bind(BKE_pose_constraints_evaluate, _1, scene_, object, pchan),
+ function_bind(BKE_pose_constraints_evaluate,
+ _1,
+ scene_,
+ object,
+ pchan_index),
DEG_OPCODE_BONE_CONSTRAINTS);
}
/* IK Solver Eval Steps */
-void DepsgraphNodeBuilder::build_ik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
+void DepsgraphNodeBuilder::build_ik_pose(Object *object,
+ bPoseChannel *pchan,
+ bConstraint *con)
{
bKinematicConstraint *data = (bKinematicConstraint *)con->data;
@@ -89,14 +97,21 @@ void DepsgraphNodeBuilder::build_ik_pose(Object *object, bPoseChannel *pchan, bC
return;
}
+ int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
/* Operation node for evaluating/running IK Solver. */
add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
- function_bind(BKE_pose_iktree_evaluate, _1, scene_, object, rootchan),
+ function_bind(BKE_pose_iktree_evaluate,
+ _1,
+ scene_,
+ object,
+ rootchan_index),
DEG_OPCODE_POSE_IK_SOLVER);
}
/* Spline IK Eval Steps */
-void DepsgraphNodeBuilder::build_splineik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
+void DepsgraphNodeBuilder::build_splineik_pose(Object *object,
+ bPoseChannel *pchan,
+ bConstraint *con)
{
bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
@@ -106,8 +121,13 @@ void DepsgraphNodeBuilder::build_splineik_pose(Object *object, bPoseChannel *pch
/* Operation node for evaluating/running Spline IK Solver.
* Store the "root bone" of this chain in the solver, so it knows where to start.
*/
+ int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
- function_bind(BKE_pose_splineik_evaluate, _1, scene_, object, rootchan),
+ function_bind(BKE_pose_splineik_evaluate,
+ _1,
+ scene_,
+ object,
+ rootchan_index),
DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
}
@@ -178,22 +198,32 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
/* pose eval context */
op_node = add_operation_node(&object->id,
DEG_NODE_TYPE_EVAL_POSE,
- function_bind(BKE_pose_eval_init, _1, scene_, object, object->pose),
+ function_bind(BKE_pose_eval_init,
+ _1,
+ scene_,
+ object),
DEG_OPCODE_POSE_INIT);
op_node->set_as_entry();
op_node = add_operation_node(&object->id,
DEG_NODE_TYPE_EVAL_POSE,
- function_bind(BKE_pose_eval_init_ik, _1, scene_, object, object->pose),
+ function_bind(BKE_pose_eval_init_ik,
+ _1,
+ scene_,
+ object),
DEG_OPCODE_POSE_INIT_IK);
op_node = add_operation_node(&object->id,
DEG_NODE_TYPE_EVAL_POSE,
- function_bind(BKE_pose_eval_flush, _1, scene_, object, object->pose),
+ function_bind(BKE_pose_eval_flush,
+ _1,
+ scene_,
+ object),
DEG_OPCODE_POSE_DONE);
op_node->set_as_exit();
/* bones */
+ int pchan_index = 0;
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
/* Node for bone evaluation. */
op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name, NULL,
@@ -201,7 +231,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
op_node->set_as_entry();
add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
- function_bind(BKE_pose_eval_bone, _1, scene_, object, pchan),
+ function_bind(BKE_pose_eval_bone, _1, scene_, object, pchan_index),
DEG_OPCODE_BONE_POSE_PARENT);
add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
@@ -209,7 +239,10 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
DEG_OPCODE_BONE_READY);
op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
- function_bind(BKE_pose_bone_done, _1, pchan),
+ function_bind(BKE_pose_bone_done,
+ _1,
+ object,
+ pchan_index),
DEG_OPCODE_BONE_DONE);
op_node->set_as_exit();
/* Custom properties. */
@@ -222,7 +255,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
}
/* Constraints. */
if (pchan->constraints.first != NULL) {
- build_pose_constraints(object, pchan);
+ build_pose_constraints(object, pchan, pchan_index);
}
/**
* IK Solvers.
@@ -232,7 +265,8 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
* base transforms of a bunch of bones is done)
*
* Unsolved Issues:
- * - Care is needed to ensure that multi-headed trees work out the same as in ik-tree building
+ * - Care is needed to ensure that multi-headed trees work out the same
+ * as in ik-tree building.
* - Animated chain-lengths are a problem...
*/
LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
@@ -249,6 +283,8 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
break;
}
}
+
+ pchan_index++;
}
}
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index a7f3d27e9d2..1691038e13c 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -377,7 +377,12 @@ typedef enum eRotationModes {
typedef struct bPose {
ListBase chanbase; /* list of pose channels, PoseBones in RNA */
struct GHash *chanhash; /* ghash for quicker string lookups */
-
+
+ /* Flat array of pose channels. It references pointers from
+ * chanbase. Used for quick pose channel lookup from an index.
+ */
+ bPoseChannel **chan_array;
+
short flag, pad;
unsigned int proxy_layer; /* proxy layer: copy from armature, gets synced */
int pad1;