Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/constraint.c
| Show First 20 Lines • Show All 584 Lines • ▼ Show 20 Lines | if (pchan) { | ||||
| */ | */ | ||||
| bool is_bbone = (pchan->bone) && (pchan->bone->segments > 1) && (flag & CONSTRAINT_BBONE_SHAPE); | bool is_bbone = (pchan->bone) && (pchan->bone->segments > 1) && (flag & CONSTRAINT_BBONE_SHAPE); | ||||
| bool full_bbone = (flag & CONSTRAINT_BBONE_SHAPE_FULL) != 0; | bool full_bbone = (flag & CONSTRAINT_BBONE_SHAPE_FULL) != 0; | ||||
| if (headtail < 0.000001f && !(is_bbone && full_bbone)) { | if (headtail < 0.000001f && !(is_bbone && full_bbone)) { | ||||
| /* skip length interpolation if set to head */ | /* skip length interpolation if set to head */ | ||||
| mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat); | mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat); | ||||
| } | } | ||||
| else if (is_bbone) { | else if (is_bbone && pchan->bone->segments == pchan->runtime.bbone_segments) { | ||||
| /* use point along bbone */ | /* use point along bbone */ | ||||
| Mat4 bbone[MAX_BBONE_SUBDIV]; | Mat4 *bbone = pchan->runtime.bbone_pose_mats; | ||||
| float tempmat[4][4]; | float tempmat[4][4]; | ||||
| float loc[3], fac; | float loc[3], fac; | ||||
| /* get bbone segments */ | |||||
| b_bone_spline_setup(pchan, false, bbone); | |||||
| /* figure out which segment(s) the headtail value falls in */ | /* figure out which segment(s) the headtail value falls in */ | ||||
| fac = (float)pchan->bone->segments * headtail; | fac = (float)pchan->bone->segments * headtail; | ||||
| if (fac >= pchan->bone->segments - 1) { | if (fac >= pchan->bone->segments - 1) { | ||||
| /* special case: end segment doesn't get created properly... */ | /* special case: end segment doesn't get created properly... */ | ||||
| float pt[3], sfac; | float pt[3], sfac; | ||||
| int index; | int index; | ||||
| ▲ Show 20 Lines • Show All 1,549 Lines • ▼ Show 20 Lines | if (ct != NULL) { | ||||
| unit_m4(ct->matrix); | unit_m4(ct->matrix); | ||||
| } | } | ||||
| } | } | ||||
| /* Compute and accumulate transformation for a single target bone. */ | /* Compute and accumulate transformation for a single target bone. */ | ||||
| static void armdef_accumulate_bone(bConstraintTarget *ct, bPoseChannel *pchan, const float wco[3], bool force_envelope, float *r_totweight, float r_sum_mat[4][4], DualQuat *r_sum_dq) | static void armdef_accumulate_bone(bConstraintTarget *ct, bPoseChannel *pchan, const float wco[3], bool force_envelope, float *r_totweight, float r_sum_mat[4][4], DualQuat *r_sum_dq) | ||||
| { | { | ||||
| float mat[4][4], iobmat[4][4], iamat[4][4], basemat[4][4], co[3]; | float mat[4][4], iobmat[4][4], basemat[4][4], co[3]; | ||||
| Bone *bone = pchan->bone; | Bone *bone = pchan->bone; | ||||
| float weight = ct->weight; | float weight = ct->weight; | ||||
| /* Our object's location in target pose space. */ | /* Our object's location in target pose space. */ | ||||
| invert_m4_m4(iobmat, ct->tar->obmat); | invert_m4_m4(iobmat, ct->tar->obmat); | ||||
| mul_v3_m4v3(co, iobmat, wco); | mul_v3_m4v3(co, iobmat, wco); | ||||
| /* Inverted rest pose matrix: bone->chan_mat may not be final yet. */ | |||||
| invert_m4_m4(iamat, bone->arm_mat); | |||||
| /* Multiply by the envelope weight when appropriate. */ | /* Multiply by the envelope weight when appropriate. */ | ||||
| if (force_envelope || (bone->flag & BONE_MULT_VG_ENV)) { | if (force_envelope || (bone->flag & BONE_MULT_VG_ENV)) { | ||||
| weight *= distfactor_to_bone(co, bone->arm_head, bone->arm_tail, | weight *= distfactor_to_bone(co, bone->arm_head, bone->arm_tail, | ||||
| bone->rad_head, bone->rad_tail, bone->dist); | bone->rad_head, bone->rad_tail, bone->dist); | ||||
| } | } | ||||
| /* Find the correct bone transform matrix in world space. */ | /* Find the correct bone transform matrix in world space. */ | ||||
| if (bone->segments > 1) { | if (bone->segments > 1 && bone->segments == pchan->runtime.bbone_segments) { | ||||
| Mat4 *b_bone_mats = pchan->runtime.bbone_deform_mats; | |||||
| float (*iamat)[4] = b_bone_mats[0].mat; | |||||
| /* The target is a B-Bone: | /* The target is a B-Bone: | ||||
| * FIRST: find the segment (see b_bone_deform in armature.c) | * FIRST: find the segment (see b_bone_deform in armature.c) | ||||
| * Need to transform co back to bonespace, only need y. */ | * Need to transform co back to bonespace, only need y. */ | ||||
| float y = iamat[0][1] * co[0] + iamat[1][1] * co[1] + iamat[2][1] * co[2] + iamat[3][1]; | float y = iamat[0][1] * co[0] + iamat[1][1] * co[1] + iamat[2][1] * co[2] + iamat[3][1]; | ||||
| float segment = bone->length / ((float)bone->segments); | float segment = bone->length / ((float)bone->segments); | ||||
| int a = (int)(y / segment); | int a = (int)(y / segment); | ||||
| CLAMP(a, 0, bone->segments - 1); | CLAMP(a, 0, bone->segments - 1); | ||||
| /* SECOND: compute the matrix (see pchan_b_bone_defmats in armature.c) */ | /* Convert the selected matrix into object space. */ | ||||
| Mat4 b_bone[MAX_BBONE_SUBDIV], b_bone_rest[MAX_BBONE_SUBDIV]; | mul_m4_series(mat, ct->tar->obmat, b_bone_mats[a + 1].mat, iobmat); | ||||
| float irmat[4][4]; | |||||
| b_bone_spline_setup(pchan, false, b_bone); | |||||
| b_bone_spline_setup(pchan, true, b_bone_rest); | |||||
| invert_m4_m4(irmat, b_bone_rest[a].mat); | |||||
| mul_m4_series(mat, ct->matrix, b_bone[a].mat, irmat, iamat, iobmat); | |||||
| } | } | ||||
| else { | else { | ||||
| /* Simple bone. */ | /* Simple bone. This requires DEG_OPCODE_BONE_DONE dependency due to chan_mat. */ | ||||
| mul_m4_series(mat, ct->matrix, iamat, iobmat); | mul_m4_series(mat, ct->tar->obmat, pchan->chan_mat, iobmat); | ||||
| } | } | ||||
| /* Accumulate the transformation. */ | /* Accumulate the transformation. */ | ||||
| *r_totweight += weight; | *r_totweight += weight; | ||||
| if (r_sum_dq != NULL) { | if (r_sum_dq != NULL) { | ||||
| DualQuat tmpdq; | DualQuat tmpdq; | ||||
| ▲ Show 20 Lines • Show All 3,158 Lines • Show Last 20 Lines | |||||