diff options
30 files changed, 899 insertions, 1034 deletions
diff --git a/release/scripts/ui/buttons_data_bone.py b/release/scripts/ui/buttons_data_bone.py index 50ece679e27..5971e4492ce 100644 --- a/release/scripts/ui/buttons_data_bone.py +++ b/release/scripts/ui/buttons_data_bone.py @@ -57,20 +57,16 @@ class BONE_PT_transform(BoneButtonsPanel): col = row.column() if pchan.rotation_mode == 'QUATERNION': - col.itemR(pchan, "rotation", text="Rotation") + col.itemR(pchan, "rotation_quaternion", text="Rotation") elif pchan.rotation_mode == 'AXIS_ANGLE': - col.itemL(text="Rotation") - col.itemR(pchan, "rotation_angle", text="Angle") - col.itemR(pchan, "rotation_axis", text="Axis") + #col.itemL(text="Rotation") + #col.itemR(pchan, "rotation_angle", text="Angle") + #col.itemR(pchan, "rotation_axis", text="Axis") + col.itemR(pchan, "rotation_axis_angle", text="Rotation") else: - col.itemR(pchan, "euler_rotation", text="Rotation") + col.itemR(pchan, "rotation_euler", text="Rotation") row.column().itemR(pchan, "scale") - - if pchan.rotation_mode == 'QUATERNION': - col = layout.column(align=True) - col.itemL(text="Euler:") - col.row().itemR(pchan, "euler_rotation", text="") class BONE_PT_transform_locks(BoneButtonsPanel): __label__ = "Transform Locks" diff --git a/release/scripts/ui/buttons_object.py b/release/scripts/ui/buttons_object.py index 9e043cfeaf3..c069572aa28 100644 --- a/release/scripts/ui/buttons_object.py +++ b/release/scripts/ui/buttons_object.py @@ -25,11 +25,48 @@ class OBJECT_PT_transform(ObjectButtonsPanel): layout = self.layout ob = context.object + + layout.itemR(ob, "rotation_mode") row = layout.row() + row.column().itemR(ob, "location") - row.column().itemR(ob, "rotation") + if ob.rotation_mode == 'QUATERNION': + row.column().itemR(ob, "rotation_quaternion", text="Rotation") + elif ob.rotation_mode == 'AXIS_ANGLE': + #row.column().itemL(text="Rotation") + #row.column().itemR(pchan, "rotation_angle", text="Angle") + #row.column().itemR(pchan, "rotation_axis", text="Axis") + row.column().itemR(ob, "rotation_axis_angle", text="Rotation") + else: + row.column().itemR(ob, "rotation_euler", text="Rotation") + row.column().itemR(ob, "scale") + +class OBJECT_PT_transform_locks(ObjectButtonsPanel): + __label__ = "Transform Locks" + __default_closed__ = True + + def draw(self, context): + layout = self.layout + + ob = context.object + + row = layout.row() + + col = row.column() + col.itemR(ob, "lock_location") + + col = row.column() + if ob.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'): + col.itemR(ob, "lock_rotations_4d", text="Lock Rotation") + if ob.lock_rotations_4d: + col.itemR(ob, "lock_rotation_w", text="W") + col.itemR(ob, "lock_rotation", text="") + else: + col.itemR(ob, "lock_rotation", text="Rotation") + + row.column().itemR(ob, "lock_scale") class OBJECT_PT_relations(ObjectButtonsPanel): __label__ = "Relations" @@ -178,6 +215,7 @@ class OBJECT_PT_animation(ObjectButtonsPanel): bpy.types.register(OBJECT_PT_context_object) bpy.types.register(OBJECT_PT_transform) +bpy.types.register(OBJECT_PT_transform_locks) bpy.types.register(OBJECT_PT_relations) bpy.types.register(OBJECT_PT_groups) bpy.types.register(OBJECT_PT_display) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 8dbd2721fb9..e5d0c4274b3 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -103,6 +103,9 @@ void armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], flo void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *outloc); void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]); +/* Rotation Mode Conversions - Used for PoseChannels + Objects... */ +void BKE_rotMode_change_values(float quat[4], float eul[3], short oldMode, short newMode); + /* B-Bone support */ typedef struct Mat4 { float mat[4][4]; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b2368451414..6220835a620 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1279,6 +1279,65 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float Mat4MulMat4(delta_mat, pose_mat, imat); } +/* **************** Rotation Mode Conversions ****************************** */ +/* Used for Objects and Pose Channels, since both can have multiple rotation representations */ + +/* Called from RNA when rotation mode changes + * - the result should be that the rotations given in the provided pointers have had conversions + * applied (as appropriate), such that the rotation of the element hasn't 'visually' changed + * + * - as in SDNA data, quat is used to store quaternions AND axis-angle rotations... + */ +void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, short newMode) +{ + /* check if any change - if so, need to convert data */ + if (newMode > 0) { /* to euler */ + if (oldMode == ROT_MODE_AXISANGLE) { + /* axis-angle to euler */ + AxisAngleToEulO(&quat[1], quat[0], eul, newMode); + } + else if (oldMode == ROT_MODE_QUAT) { + /* quat to euler */ + QuatToEulO(quat, eul, newMode); + } + /* else { no conversion needed } */ + } + else if (newMode == ROT_MODE_QUAT) { /* to quat */ + if (oldMode == ROT_MODE_AXISANGLE) { + /* axis angle to quat */ + float q[4]; + + /* copy to temp var first, since quats and axis-angle are stored in same place */ + QuatCopy(q, quat); + AxisAngleToQuat(q, &quat[1], quat[0]); + } + else if (oldMode > 0) { + /* euler to quat */ + EulOToQuat(eul, oldMode, quat); + } + /* else { no conversion needed } */ + } + else { /* to axis-angle */ + if (oldMode > 0) { + /* euler to axis angle */ + EulOToAxisAngle(eul, oldMode, &quat[1], &quat[0]); + } + else if (oldMode == ROT_MODE_QUAT) { + /* quat to axis angle */ + float q[4]; + + /* copy to temp var first, since quats and axis-angle are stored in same place */ + QuatCopy(q, quat); + QuatToAxisAngle(q, &quat[1], &quat[0]); + } + + /* when converting to axis-angle, we need a special exception for the case when there is no axis */ + if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) { + /* for now, rotate around y-axis then (so that it simply becomes the roll) */ + quat[2]= 1.0f; + } + } +} /* **************** The new & simple (but OK!) armature evaluation ********* */ @@ -1591,7 +1650,7 @@ void chan_calc_mat(bPoseChannel *chan) /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */ EulOToMat3(chan->eul, chan->rotmode, rmat); } - else if (chan->rotmode == PCHAN_ROT_AXISANGLE) { + else if (chan->rotmode == ROT_MODE_AXISANGLE) { /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */ AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat); } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 4de6b53d26a..8846fe77809 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -692,9 +692,11 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain }\ else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \ ct->type = CONSTRAINT_OBTYPE_VERT; \ + ct->rotOrder = EULER_ORDER_DEFAULT; \ } \ else {\ ct->type = CONSTRAINT_OBTYPE_OBJECT; \ + ct->rotOrder= ct->tar->rotmode; \ } \ } \ \ diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index dd7904b4782..811a2658ae3 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -213,17 +213,17 @@ static char *ob_adrcodes_to_paths (int adrcode, int *array_index) *array_index= 2; return "delta_location"; case OB_ROT_X: - *array_index= 0; return "rotation"; + *array_index= 0; return "rotation_euler"; case OB_ROT_Y: - *array_index= 1; return "rotation"; + *array_index= 1; return "rotation_euler"; case OB_ROT_Z: - *array_index= 2; return "rotation"; + *array_index= 2; return "rotation_euler"; case OB_DROT_X: - *array_index= 0; return "delta_rotation"; + *array_index= 0; return "delta_rotation_euler"; case OB_DROT_Y: - *array_index= 1; return "delta_rotation"; + *array_index= 1; return "delta_rotation_euler"; case OB_DROT_Z: - *array_index= 2; return "delta_rotation"; + *array_index= 2; return "delta_rotation_euler"; case OB_SIZE_X: *array_index= 0; return "scale"; @@ -281,23 +281,23 @@ static char *pchan_adrcodes_to_paths (int adrcode, int *array_index) /* result depends on adrcode */ switch (adrcode) { case AC_QUAT_W: - *array_index= 0; return "rotation"; + *array_index= 0; return "rotation_quaternion"; case AC_QUAT_X: - *array_index= 1; return "rotation"; + *array_index= 1; return "rotation_quaternion"; case AC_QUAT_Y: - *array_index= 2; return "rotation"; + *array_index= 2; return "rotation_quaternion"; case AC_QUAT_Z: - *array_index= 3; return "rotation"; + *array_index= 3; return "rotation_quaternion"; case AC_EUL_X: - *array_index= 0; return "euler_rotation"; + *array_index= 0; return "rotation_euler"; case AC_EUL_Y: - *array_index= 1; return "euler_rotation"; + *array_index= 1; return "rotation_euler"; case AC_EUL_Z: - *array_index= 2; return "euler_rotation"; + *array_index= 2; return "rotation_euler"; case -1: /* special case for euler-rotations used by old drivers */ - *array_index= 0; return "euler_rotation"; + *array_index= 0; return "rotation_euler"; case AC_LOC_X: *array_index= 0; return "location"; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index c98e2d5970b..7e2ec106062 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -127,8 +127,8 @@ void clear_workob(Object *workob) { memset(workob, 0, sizeof(Object)); - workob->size[0]= workob->size[1]= workob->size[2]= 1.0; - + workob->size[0]= workob->size[1]= workob->size[2]= 1.0f; + workob->rotmode= ROT_MODE_EUL; } void copy_baseflags(struct Scene *scene) @@ -1038,6 +1038,11 @@ Object *add_object(struct Scene *scene, int type) ob->data= add_obdata_from_type(type); ob->lay= scene->lay; + + /* objects should default to having Euler XYZ rotations, + * but rotations default to quaternions + */ + ob->rotmode= ROT_MODE_EUL; base= scene_add_base(scene, ob); scene_select_base(scene, base); @@ -1582,12 +1587,34 @@ void object_scale_to_mat3(Object *ob, float mat[][3]) // TODO: this should take rotation orders into account later... void object_rot_to_mat3(Object *ob, float mat[][3]) { - float vec[3]; + float rmat[3][3], dmat[3][3]; + + /* initialise the delta-rotation matrix, which will get (pre)multiplied + * with the rotation matrix to yield the appropriate rotation + */ + Mat3One(dmat); + + /* rotations may either be quats, eulers (with various rotation orders), or axis-angle */ + if (ob->rotmode > 0) { + /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */ + EulOToMat3(ob->rot, ob->rotmode, rmat); + EulOToMat3(ob->drot, ob->rotmode, dmat); + } + else if (ob->rotmode == ROT_MODE_AXISANGLE) { + /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */ + AxisAngleToMat3(&ob->quat[1], ob->quat[0], rmat); + AxisAngleToMat3(&ob->dquat[1], ob->dquat[0], dmat); + } + else { + /* quats are normalised before use to eliminate scaling issues */ + NormalQuat(ob->quat); + QuatToMat3(ob->quat, rmat); + QuatToMat3(ob->dquat, dmat); + } - vec[0]= ob->rot[0]+ob->drot[0]; - vec[1]= ob->rot[1]+ob->drot[1]; - vec[2]= ob->rot[2]+ob->drot[2]; - EulToMat3(vec, mat); + /* combine these rotations */ + // XXX is this correct? if errors, change the order of multiplication... + Mat3MulMat3(mat, dmat, rmat); } void object_to_mat3(Object *ob, float mat[][3]) /* no parent */ @@ -1600,14 +1627,7 @@ void object_to_mat3(Object *ob, float mat[][3]) /* no parent */ object_scale_to_mat3(ob, smat); /* rot */ - /* Quats arnt used yet */ - /*if(ob->transflag & OB_QUAT) { - QuatMul(q1, ob->quat, ob->dquat); - QuatToMat3(q1, rmat); - } - else {*/ - object_rot_to_mat3(ob, rmat); - /*}*/ + object_rot_to_mat3(ob, rmat); Mat3MulMat3(mat, rmat, smat); } diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 793dab12b83..1d275e70a17 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -178,7 +178,7 @@ float power_of_2(float val); */ /* Defines for rotation orders - * WARNING: must match the ePchan_RotMode in DNA_action_types.h + * WARNING: must match the eRotationModes in DNA_action_types.h * order matters - types are saved to file! */ typedef enum eEulerRotationOrders { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 204176f64c3..114ec9095b1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9709,8 +9709,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sce->unit.scale_length= 1.0f; for(ob = main->object.first; ob; ob = ob->id.next) { + /* fluid-sim stuff */ FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); if (fluidmd) fluidmd->fss->fmd = fluidmd; + + /* rotation modes were added, but old objects would now default to being 'quaternion based' */ + ob->rotmode= ROT_MODE_EUL; } for(sce= main->scene.first; sce; sce= sce->id.next) diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index e3e72a532e2..10d45d53761 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -643,14 +643,14 @@ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_ else if (pchan->bone->parent == NULL) return tmat[3][array_index]; } - else if (strstr(identifier, "euler_rotation")) { + else if (strstr(identifier, "rotation_euler")) { float eul[3]; /* euler-rotation test before standard rotation, as standard rotation does quats */ Mat4ToEulO(tmat, eul, pchan->rotmode); return eul[array_index]; } - else if (strstr(identifier, "rotation")) { + else if (strstr(identifier, "rotation_quaternion")) { float trimat[3][3], quat[4]; Mat3CpyMat4(trimat, tmat); @@ -658,6 +658,7 @@ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_ return quat[array_index]; } + // TODO: axis-angle... } /* as the function hasn't returned yet, read value from system in the default way */ diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 60efcce4e73..81259ae7ced 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -770,7 +770,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] = /* Keying Set - "Rotation" ---------- */ BI_KS_DEFINE_BEGIN("Rotation", 0) BI_KS_PATHS_BEGIN(1) - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) BI_KS_PATHS_END BI_KS_DEFINE_END, @@ -786,7 +786,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] = BI_KS_DEFINE_BEGIN("LocRot", 0) BI_KS_PATHS_BEGIN(2) BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) BI_KS_PATHS_END BI_KS_DEFINE_END, @@ -794,7 +794,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] = BI_KS_DEFINE_BEGIN("LocRotScale", 0) BI_KS_PATHS_BEGIN(3) BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "scale", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) BI_KS_PATHS_END BI_KS_DEFINE_END, @@ -810,7 +810,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] = /* Keying Set - "Rotation" ---------- */ BI_KS_DEFINE_BEGIN("VisualRot", INSERTKEY_MATRIX) BI_KS_PATHS_BEGIN(1) - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) BI_KS_PATHS_END BI_KS_DEFINE_END, @@ -818,7 +818,7 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] = BI_KS_DEFINE_BEGIN("VisualLocRot", INSERTKEY_MATRIX) BI_KS_PATHS_BEGIN(2) BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) BI_KS_PATHS_END BI_KS_DEFINE_END }; @@ -1145,7 +1145,12 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet * int arraylen, i; /* set initial group name */ - groupname= (cks->id) ? cks->id->name+2 : NULL; + if (cks->id == NULL) { + printf("ERROR: Skipping 'Common-Key' Source. No valid ID present.\n"); + continue; + } + else + groupname= cks->id->name+2; /* construct the path */ // FIXME: this currently only works with a few hardcoded cases @@ -1173,14 +1178,24 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet * BLI_dynstr_append(pathds, "."); /* apply some further templates? */ - if ((ksp->templates & KSP_TEMPLATE_PCHAN_ROT) && (cks->pchan)) { - /* if this path is exactly "rotation", and the rotation mode is set to eulers, - * use "euler_rotation" instead so that rotations will be keyed correctly + if (ksp->templates & KSP_TEMPLATE_ROT) { + /* for builtin Keying Sets, this template makes the best fitting path for the + * current rotation mode of the Object / PoseChannel to be used */ - if (strcmp(ksp->rna_path, "rotation")==0 && (cks->pchan->rotmode > 0)) - BLI_dynstr_append(pathds, "euler_rotation"); - else - BLI_dynstr_append(pathds, ksp->rna_path); + if (strcmp(ksp->rna_path, "rotation")==0) { + /* get rotation mode */ + short rotmode= (cks->pchan)? (cks->pchan->rotmode) : + (GS(cks->id->name)==ID_OB)? ( ((Object *)cks->id)->rotmode ) : + (0); + + /* determine path to build */ + if (rotmode == ROT_MODE_QUAT) + BLI_dynstr_append(pathds, "rotation_quaternion"); + else if (rotmode == ROT_MODE_AXISANGLE) + BLI_dynstr_append(pathds, "rotation_axis_angle"); + else + BLI_dynstr_append(pathds, "rotation_euler"); + } } else { /* just directly use the path */ diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 5f8c503e854..402715dbb02 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4862,7 +4862,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) if (pchan->protectflag & OB_LOCK_ROT4D) { /* perform clamping on a component by component basis */ if ((pchan->protectflag & OB_LOCK_ROTW) == 0) - pchan->quat[0]= (pchan->rotmode == PCHAN_ROT_AXISANGLE) ? 0.0f : 1.0f; + pchan->quat[0]= (pchan->rotmode == ROT_MODE_AXISANGLE) ? 0.0f : 1.0f; if ((pchan->protectflag & OB_LOCK_ROTX) == 0) pchan->quat[1]= 0.0f; if ((pchan->protectflag & OB_LOCK_ROTY) == 0) @@ -4874,11 +4874,11 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) /* perform clamping using euler form (3-components) */ float eul[3], oldeul[3], quat1[4]; - if (pchan->rotmode == PCHAN_ROT_QUAT) { + if (pchan->rotmode == ROT_MODE_QUAT) { QUATCOPY(quat1, pchan->quat); QuatToEul(pchan->quat, oldeul); } - else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + else if (pchan->rotmode == ROT_MODE_AXISANGLE) { AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT); } else { @@ -4894,14 +4894,14 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) if (pchan->protectflag & OB_LOCK_ROTZ) eul[2]= oldeul[2]; - if (pchan->rotmode == PCHAN_ROT_QUAT) { + if (pchan->rotmode == ROT_MODE_QUAT) { EulToQuat(eul, pchan->quat); /* quaternions flip w sign to accumulate rotations correctly */ if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) { QuatMulf(pchan->quat, -1.0f); } } - else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + else if (pchan->rotmode == ROT_MODE_AXISANGLE) { AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT); } else { @@ -4910,11 +4910,11 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) } } else { - if (pchan->rotmode == PCHAN_ROT_QUAT) { + if (pchan->rotmode == ROT_MODE_QUAT) { pchan->quat[1]=pchan->quat[2]=pchan->quat[3]= 0.0f; pchan->quat[0]= 1.0f; } - else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + else if (pchan->rotmode == ROT_MODE_AXISANGLE) { /* by default, make rotation of 0 radians around y-axis (roll) */ pchan->quat[0]=pchan->quat[1]=pchan->quat[3]= 0.0f; pchan->quat[2]= 1.0f; diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index 7c63954767f..c73208c54c2 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -523,9 +523,9 @@ static void pose_slide_apply (bContext *C, wmOperator *op, tPoseSlideOp *pso) /* everything depends on the rotation mode */ if (pchan->rotmode > 0) { /* eulers - so calculate these for the 'eul' vector, and use euler_rotation curves */ - pose_slide_apply_vec3(pso, pfl, pchan->eul, "euler_rotation"); + pose_slide_apply_vec3(pso, pfl, pchan->eul, "rotation_euler"); } - else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + else if (pchan->rotmode == ROT_MODE_AXISANGLE) { // TODO: need to figure out how to do this! } else { diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index f40476f6f59..d4b7aa149df 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -814,14 +814,14 @@ void pose_copy_menu(Scene *scene) armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat); - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + if (pchan->rotmode == ROT_MODE_AXISANGLE) { float tmp_quat[4]; /* need to convert to quat first (in temp var)... */ Mat4ToQuat(delta_mat, tmp_quat); QuatToAxisAngle(tmp_quat, &pchan->quat[1], &pchan->quat[0]); } - else if (pchan->rotmode == PCHAN_ROT_QUAT) + else if (pchan->rotmode == ROT_MODE_QUAT) Mat4ToQuat(delta_mat, pchan->quat); else Mat4ToEulO(delta_mat, pchan->eul, pchan->rotmode); @@ -1023,12 +1023,12 @@ static int pose_paste_exec (bContext *C, wmOperator *op) } else if (pchan->rotmode > 0) { /* quat/axis-angle to euler */ - if (chan->rotmode == PCHAN_ROT_AXISANGLE) + if (chan->rotmode == ROT_MODE_AXISANGLE) AxisAngleToEulO(&chan->quat[1], chan->quat[0], pchan->eul, pchan->rotmode); else QuatToEulO(chan->quat, pchan->eul, pchan->rotmode); } - else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + else if (pchan->rotmode == ROT_MODE_AXISANGLE) { /* quat/euler to axis angle */ if (chan->rotmode > 0) EulOToAxisAngle(chan->eul, chan->rotmode, &pchan->quat[1], &pchan->quat[0]); @@ -1052,7 +1052,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) pchan->eul[1] *= -1; pchan->eul[2] *= -1; } - else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + else if (pchan->rotmode == ROT_MODE_AXISANGLE) { float eul[3]; AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], eul, EULER_ORDER_DEFAULT); diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 2b207f2f27c..cd0d97eed44 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -27,6 +27,7 @@ #include <stdlib.h> +#include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_curve_types.h" #include "DNA_key_types.h" @@ -115,13 +116,72 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { - /* eulers can only get cleared if they are not protected */ - if((ob->protectflag & OB_LOCK_ROTX)==0) - ob->rot[0]= ob->drot[0]= 0.0f; - if((ob->protectflag & OB_LOCK_ROTY)==0) - ob->rot[1]= ob->drot[1]= 0.0f; - if((ob->protectflag & OB_LOCK_ROTZ)==0) - ob->rot[2]= ob->drot[2]= 0.0f; + if (ob->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) { + /* check if convert to eulers for locking... */ + if (ob->protectflag & OB_LOCK_ROT4D) { + /* perform clamping on a component by component basis */ + if ((ob->protectflag & OB_LOCK_ROTW) == 0) + ob->quat[0]= (ob->rotmode == ROT_MODE_AXISANGLE) ? 0.0f : 1.0f; + if ((ob->protectflag & OB_LOCK_ROTX) == 0) + ob->quat[1]= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTY) == 0) + ob->quat[2]= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTZ) == 0) + ob->quat[3]= 0.0f; + } + else { + /* perform clamping using euler form (3-components) */ + float eul[3], oldeul[3], quat1[4]; + + if (ob->rotmode == ROT_MODE_QUAT) { + QUATCOPY(quat1, ob->quat); + QuatToEul(ob->quat, oldeul); + } + else if (ob->rotmode == ROT_MODE_AXISANGLE) { + AxisAngleToEulO(&ob->quat[1], ob->quat[0], oldeul, EULER_ORDER_DEFAULT); + } + else { + VECCOPY(oldeul, ob->rot); + } + + eul[0]= eul[1]= eul[2]= 0.0f; + + if (ob->protectflag & OB_LOCK_ROTX) + eul[0]= oldeul[0]; + if (ob->protectflag & OB_LOCK_ROTY) + eul[1]= oldeul[1]; + if (ob->protectflag & OB_LOCK_ROTZ) + eul[2]= oldeul[2]; + + if (ob->rotmode == ROT_MODE_QUAT) { + EulToQuat(eul, ob->quat); + /* quaternions flip w sign to accumulate rotations correctly */ + if ((quat1[0]<0.0f && ob->quat[0]>0.0f) || (quat1[0]>0.0f && ob->quat[0]<0.0f)) { + QuatMulf(ob->quat, -1.0f); + } + } + else if (ob->rotmode == ROT_MODE_AXISANGLE) { + AxisAngleToEulO(&ob->quat[1], ob->quat[0], oldeul, EULER_ORDER_DEFAULT); + } + else { + VECCOPY(ob->rot, eul); + } + } + } + else { + if (ob->rotmode == ROT_MODE_QUAT) { + ob->quat[1]=ob->quat[2]=ob->quat[3]= 0.0f; + ob->quat[0]= 1.0f; + } + else if (ob->rotmode == ROT_MODE_AXISANGLE) { + /* by default, make rotation of 0 radians around y-axis (roll) */ + ob->quat[0]=ob->quat[1]=ob->quat[3]= 0.0f; + ob->quat[2]= 1.0f; + } + else { + ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0f; + } + } } ob->recalc |= OB_RECALC_OB; } diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 8c739d68cea..3e0f9760773 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1335,7 +1335,7 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op) if (ELEM(0, fcu->rna_path, strstr(fcu->rna_path, "rotation"))) continue; if (strstr(fcu->rna_path, "pose.pose_channels")) { - if (strstr(fcu->rna_path, "euler_rotation") == 0) + if (strstr(fcu->rna_path, "rotation_euler") == 0) continue; } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 89d07fbbfea..496db8c00f8 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -517,13 +517,13 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float return; } - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + if (pchan->rotmode == ROT_MODE_AXISANGLE) { float quat[4]; /* convert to euler, passing through quats... */ AxisAngleToQuat(quat, &pchan->quat[1], pchan->quat[0]); QuatToEul(quat, tfp->ob_eul); } - else if (pchan->rotmode == PCHAN_ROT_QUAT) + else if (pchan->rotmode == ROT_MODE_QUAT) QuatToEul(pchan->quat, tfp->ob_eul); else VecCopyf(tfp->ob_eul, pchan->eul); @@ -866,13 +866,13 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) eul[1]= M_PI*tfp->ob_eul[1]/180.0; eul[2]= M_PI*tfp->ob_eul[2]/180.0; - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + if (pchan->rotmode == ROT_MODE_AXISANGLE) { float quat[4]; /* convert to axis-angle, passing through quats */ EulToQuat(eul, quat); QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]); } - else if (pchan->rotmode == PCHAN_ROT_QUAT) + else if (pchan->rotmode == ROT_MODE_QUAT) EulToQuat(eul, pchan->quat); else VecCopyf(pchan->eul, eul); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index bc529486085..84e42294946 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1716,38 +1716,30 @@ static void constraintTransLim(TransInfo *t, TransData *td) bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT); bConstraintOb cob; bConstraint *con; - + /* Make a temporary bConstraintOb for using these limit constraints * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ memset(&cob, 0, sizeof(bConstraintOb)); Mat4One(cob.matrix); - if (td->tdi) { - TransDataIpokey *tdi= td->tdi; - cob.matrix[3][0]= tdi->locx[0]; - cob.matrix[3][1]= tdi->locy[0]; - cob.matrix[3][2]= tdi->locz[0]; - } - else { - VECCOPY(cob.matrix[3], td->loc); - } - + VECCOPY(cob.matrix[3], td->loc); + /* Evaluate valid constraints */ for (con= td->con; con; con= con->next) { float tmat[4][4]; - + /* only consider constraint if enabled */ if (con->flag & CONSTRAINT_DISABLE) continue; if (con->enforce == 0.0f) continue; - + /* only use it if it's tagged for this purpose (and the right type) */ if (con->type == CONSTRAINT_TYPE_LOCLIMIT) { bLocLimitConstraint *data= con->data; - + if ((data->flag2 & LIMIT_TRANSFORM)==0) continue; - + /* do space conversions */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1758,10 +1750,10 @@ static void constraintTransLim(TransInfo *t, TransData *td) /* skip... incompatable spacetype */ continue; } - + /* do constraint */ cti->evaluate_constraint(con, &cob, NULL); - + /* convert spaces again */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1770,17 +1762,9 @@ static void constraintTransLim(TransInfo *t, TransData *td) } } } - + /* copy results from cob->matrix */ - if (td->tdi) { - TransDataIpokey *tdi= td->tdi; - tdi->locx[0]= cob.matrix[3][0]; - tdi->locy[0]= cob.matrix[3][1]; - tdi->locz[0]= cob.matrix[3][2]; - } - else { - VECCOPY(td->loc, cob.matrix[3]); - } + VECCOPY(td->loc, cob.matrix[3]); } } @@ -1796,25 +1780,14 @@ static void constraintRotLim(TransInfo *t, TransData *td) * - current space should be local */ memset(&cob, 0, sizeof(bConstraintOb)); - if (td->flag & TD_USEQUAT) { + if (td->rotOrder == ROT_MODE_QUAT) { /* quats */ if (td->ext) QuatToMat4(td->ext->quat, cob.matrix); else return; } - else if (td->tdi) { // XXX depreceated - /* ipo-keys eulers */ - TransDataIpokey *tdi= td->tdi; - float eul[3]; - - eul[0]= tdi->rotx[0]; - eul[1]= tdi->roty[0]; - eul[2]= tdi->rotz[0]; - - EulOToMat4(eul, td->rotOrder, cob.matrix); - } - else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + else if (td->rotOrder == ROT_MODE_AXISANGLE) { /* axis angle */ if (td->ext) AxisAngleToMat4(&td->ext->quat[1], td->ext->quat[0], cob.matrix); @@ -1868,22 +1841,11 @@ static void constraintRotLim(TransInfo *t, TransData *td) } /* copy results from cob->matrix */ - if (td->flag & TD_USEQUAT) { + if (td->rotOrder == ROT_MODE_QUAT) { /* quats */ Mat4ToQuat(cob.matrix, td->ext->quat); } - else if (td->tdi) { - /* ipo-keys eulers */ - TransDataIpokey *tdi= td->tdi; - float eul[3]; - - Mat4ToEulO(cob.matrix, eul, td->rotOrder); - - tdi->rotx[0]= eul[0]; - tdi->roty[0]= eul[1]; - tdi->rotz[0]= eul[2]; - } - else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + else if (td->rotOrder == ROT_MODE_AXISANGLE) { /* axis angle */ Mat4ToAxisAngle(cob.matrix, &td->ext->quat[1], &td->ext->quat[0]); } @@ -1900,22 +1862,13 @@ static void constraintSizeLim(TransInfo *t, TransData *td) bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT); bConstraintOb cob; bConstraint *con; - + /* Make a temporary bConstraintOb for using these limit constraints * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ memset(&cob, 0, sizeof(bConstraintOb)); - if (td->tdi) { - TransDataIpokey *tdi= td->tdi; - float size[3]; - - size[0]= tdi->sizex[0]; - size[1]= tdi->sizey[0]; - size[2]= tdi->sizez[0]; - SizeToMat4(size, cob.matrix); - } - else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { + if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { /* scale val and reset size */ return; // TODO: fix this case } @@ -1923,25 +1876,25 @@ static void constraintSizeLim(TransInfo *t, TransData *td) /* Reset val if SINGLESIZE but using a constraint */ if (td->flag & TD_SINGLESIZE) return; - + SizeToMat4(td->ext->size, cob.matrix); } - + /* Evaluate valid constraints */ for (con= td->con; con; con= con->next) { /* only consider constraint if enabled */ if (con->flag & CONSTRAINT_DISABLE) continue; if (con->enforce == 0.0f) continue; - + /* we're only interested in Limit-Scale constraints */ if (con->type == CONSTRAINT_TYPE_SIZELIMIT) { bSizeLimitConstraint *data= con->data; float tmat[4][4]; - + /* only use it if it's tagged for this purpose */ if ((data->flag2 & LIMIT_TRANSFORM)==0) continue; - + /* do space conversions */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1952,10 +1905,10 @@ static void constraintSizeLim(TransInfo *t, TransData *td) /* skip... incompatable spacetype */ continue; } - + /* do constraint */ cti->evaluate_constraint(con, &cob, NULL); - + /* convert spaces again */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1964,19 +1917,9 @@ static void constraintSizeLim(TransInfo *t, TransData *td) } } } - + /* copy results from cob->matrix */ - if (td->tdi) { - TransDataIpokey *tdi= td->tdi; - float size[3]; - - Mat4ToSize(cob.matrix, size); - - tdi->sizex[0]= size[0]; - tdi->sizey[0]= size[1]; - tdi->sizez[0]= size[2]; - } - else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { + if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { /* scale val and reset size */ return; // TODO: fix this case } @@ -1984,7 +1927,7 @@ static void constraintSizeLim(TransInfo *t, TransData *td) /* Reset val if SINGLESIZE but using a constraint */ if (td->flag & TD_SINGLESIZE) return; - + Mat4ToSize(cob.matrix, td->ext->size); } } @@ -1996,21 +1939,21 @@ void initWarp(TransInfo *t) { float max[3], min[3]; int i; - + t->mode = TFM_WARP; t->transform = Warp; t->handleEvent = handleEventWarp; - + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 5.0f; t->snap[2] = 1.0f; - + t->flag |= T_NO_CONSTRAINT; - + /* we need min/max in view space */ for(i = 0; i < t->total; i++) { float center[3]; @@ -2025,7 +1968,7 @@ void initWarp(TransInfo *t) VECCOPY(min, center); } } - + t->center[0]= (min[0]+max[0])/2.0f; t->center[1]= (min[1]+max[1])/2.0f; t->center[2]= (min[2]+max[2])/2.0f; @@ -2037,7 +1980,7 @@ void initWarp(TransInfo *t) int handleEventWarp(TransInfo *t, wmEvent *event) { int status = 0; - + if (event->type == MIDDLEMOUSE && event->val==KM_PRESS) { // Use customData pointer to signal warp direction @@ -2045,10 +1988,10 @@ int handleEventWarp(TransInfo *t, wmEvent *event) t->customData = (void*)1; else t->customData = 0; - + status = 1; } - + return status; } @@ -2058,7 +2001,7 @@ int Warp(TransInfo *t, short mval[2]) float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3]; int i; char str[50]; - + curs= give_cursor(t->scene, t->view); /* * gcursor is the one used for helpline. @@ -2079,73 +2022,73 @@ int Warp(TransInfo *t, short mval[2]) } Mat4MulVecfl(t->viewmat, cursor); VecSubf(cursor, cursor, t->viewmat[3]); - + /* amount of degrees for warp */ circumfac = 360.0f * t->values[0]; - + if (t->customData) /* non-null value indicates reversed input */ { circumfac *= -1; } - + snapGrid(t, &circumfac); applyNumInput(&t->num, &circumfac); - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); - + sprintf(str, "Warp: %s", c); } else { /* default header print */ sprintf(str, "Warp: %.3f", circumfac); } - + circumfac*= (float)(-M_PI/360.0); - + for(i = 0; i < t->total; i++, td++) { float loc[3]; if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + /* translate point to center, rotate in such a way that outline==distance */ VECCOPY(vec, td->iloc); Mat3MulVecfl(td->mtx, vec); Mat4MulVecfl(t->viewmat, vec); VecSubf(vec, vec, t->viewmat[3]); - + dist= vec[0]-cursor[0]; - + /* t->val is X dimension projected boundbox */ phi0= (circumfac*dist/t->val); - + vec[1]= (vec[1]-cursor[1]); - + co= (float)cos(phi0); si= (float)sin(phi0); loc[0]= -si*vec[1]+cursor[0]; loc[1]= co*vec[1]+cursor[1]; loc[2]= vec[2]; - + Mat4MulVecfl(t->viewinv, loc); VecSubf(loc, loc, t->viewinv[3]); Mat3MulVecfl(td->smtx, loc); - + VecSubf(loc, loc, td->iloc); VecMulf(loc, td->factor); VecAddf(td->loc, td->iloc, loc); } - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -2156,22 +2099,22 @@ void initShear(TransInfo *t) t->mode = TFM_SHEAR; t->transform = Shear; t->handleEvent = handleEventShear; - + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->flag |= T_NO_CONSTRAINT; } int handleEventShear(TransInfo *t, wmEvent *event) { int status = 0; - + if (event->type == MIDDLEMOUSE && event->val==KM_PRESS) { // Use customData pointer to signal Shear direction @@ -2185,10 +2128,10 @@ int handleEventShear(TransInfo *t, wmEvent *event) initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); t->customData = 0; } - + status = 1; } - + return status; } @@ -2201,47 +2144,47 @@ int Shear(TransInfo *t, short mval[2]) float value; int i; char str[50]; - + Mat3CpyMat4(persmat, t->viewmat); Mat3Inv(persinv, persmat); - + value = 0.05f * t->values[0]; - + snapGrid(t, &value); - + applyNumInput(&t->num, &value); - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); - + sprintf(str, "Shear: %s %s", c, t->proptext); } else { /* default header print */ sprintf(str, "Shear: %.3f %s", value, t->proptext); } - + Mat3One(smat); - + // Custom data signals shear direction if (t->customData == 0) smat[1][0] = value; else smat[0][1] = value; - + Mat3MulMat3(tmat, smat, persmat); Mat3MulMat3(totmat, persinv, tmat); - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + if (t->obedit) { float mat3[3][3]; Mat3MulMat3(mat3, totmat, td->mtx); @@ -2251,19 +2194,19 @@ int Shear(TransInfo *t, short mval[2]) Mat3CpyMat3(tmat, totmat); } VecSubf(vec, td->center, t->center); - + Mat3MulVecfl(tmat, vec); - + VecAddf(vec, vec, t->center); VecSubf(vec, vec, td->center); - + VecMulf(vec, td->factor); - + VecAddf(td->loc, td->iloc, vec); } - + recalcData(t); - + ED_area_headerprint(t->sa, str); return 1; @@ -2275,9 +2218,9 @@ void initResize(TransInfo *t) { t->mode = TFM_RESIZE; t->transform = Resize; - + initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP); - + t->flag |= T_NULL_ONE; t->num.flag |= NUM_NULL_ONE; t->num.flag |= NUM_AFFECT_ALL; @@ -2285,7 +2228,7 @@ void initResize(TransInfo *t) t->flag |= T_NO_ZERO; t->num.flag |= NUM_NO_ZERO; } - + t->idx_max = 2; t->num.idx_max = 2; t->snap[0] = 0.0f; @@ -2303,7 +2246,7 @@ static void headerResize(TransInfo *t, float vec[3], char *str) { sprintf(&tvec[20], "%.4f", vec[1]); sprintf(&tvec[40], "%.4f", vec[2]); } - + if (t->con.mode & CON_APPLY) { switch(t->num.idx_max) { case 0: @@ -2331,14 +2274,14 @@ static void headerResize(TransInfo *t, float vec[3], char *str) { static void TransMat3ToSize( float mat[][3], float smat[][3], float *size) { float vec[3]; - + VecCopyf(vec, mat[0]); size[0]= Normalize(vec); VecCopyf(vec, mat[1]); size[1]= Normalize(vec); VecCopyf(vec, mat[2]); size[2]= Normalize(vec); - + /* first tried with dotproduct... but the sign flip is crucial */ if( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0]; if( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1]; @@ -2349,7 +2292,7 @@ static void TransMat3ToSize( float mat[][3], float smat[][3], float *size) static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { float tmat[3][3], smat[3][3], center[3]; float vec[3]; - + if (t->flag & T_EDIT) { Mat3MulMat3(smat, mat, td->mtx); Mat3MulMat3(tmat, td->smtx, smat); @@ -2357,18 +2300,18 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { else { Mat3CpyMat3(tmat, mat); } - + if (t->con.applySize) { t->con.applySize(t, td, tmat); } - + /* local constraint shouldn't alter center */ if (t->around == V3D_LOCAL) { if (t->flag & T_OBJECT) { VECCOPY(center, td->center); } else if (t->flag & T_EDIT) { - + if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { VECCOPY(center, td->center); } @@ -2383,10 +2326,10 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { else { VECCOPY(center, t->center); } - + if (td->ext) { float fsize[3]; - + if (t->flag & (T_OBJECT|T_TEXTURE|T_POSE)) { float obsizemat[3][3]; // Reorient the size mat to fit the oriented object. @@ -2398,28 +2341,14 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { else { Mat3ToSize(tmat, fsize); } - + protectedSizeBits(td->protectflag, fsize); - + if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't resize objects itself - /* handle ipokeys? */ - if(td->tdi) { - TransDataIpokey *tdi= td->tdi; - /* calculate delta size (equal for size and dsize) */ - - vec[0]= (tdi->oldsize[0])*(fsize[0] -1.0f) * td->factor; - vec[1]= (tdi->oldsize[1])*(fsize[1] -1.0f) * td->factor; - vec[2]= (tdi->oldsize[2])*(fsize[2] -1.0f) * td->factor; - - add_tdi_poin(tdi->sizex, tdi->oldsize, vec[0]); - add_tdi_poin(tdi->sizey, tdi->oldsize+1, vec[1]); - add_tdi_poin(tdi->sizez, tdi->oldsize+2, vec[2]); - - } - else if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){ + if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){ /* scale val and reset size */ *td->val = td->ival * fsize[0] * td->factor; - + td->ext->size[0] = td->ext->isize[0]; td->ext->size[1] = td->ext->isize[1]; td->ext->size[2] = td->ext->isize[2]; @@ -2428,46 +2357,39 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { /* Reset val if SINGLESIZE but using a constraint */ if (td->flag & TD_SINGLESIZE) *td->val = td->ival; - + td->ext->size[0] = td->ext->isize[0] * (fsize[0]) * td->factor; td->ext->size[1] = td->ext->isize[1] * (fsize[1]) * td->factor; td->ext->size[2] = td->ext->isize[2] * (fsize[2]) * td->factor; } } - + constraintSizeLim(t, td); } - + /* For individual element center, Editmode need to use iloc */ if (t->flag & T_POINTS) VecSubf(vec, td->iloc, center); else VecSubf(vec, td->center, center); - + Mat3MulVecfl(tmat, vec); - + VecAddf(vec, vec, center); if (t->flag & T_POINTS) VecSubf(vec, vec, td->iloc); else VecSubf(vec, vec, td->center); - + VecMulf(vec, td->factor); - + if (t->flag & (T_OBJECT|T_POSE)) { Mat3MulVecfl(td->smtx, vec); } - + protectedTransBits(td->protectflag, vec); - - if(td->tdi) { - TransDataIpokey *tdi= td->tdi; - add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]); - add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]); - add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]); - } - else VecAddf(td->loc, td->iloc, vec); - + VecAddf(td->loc, td->iloc, vec); + constraintTransLim(t, td); } @@ -2478,7 +2400,7 @@ int Resize(TransInfo *t, short mval[2]) float ratio; int i; char str[200]; - + /* for manipulator, center handle, the scaling can't be done relative to center */ if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) { @@ -2488,60 +2410,60 @@ int Resize(TransInfo *t, short mval[2]) { ratio = t->values[0]; } - + size[0] = size[1] = size[2] = ratio; - + snapGrid(t, size); - + if (hasNumInput(&t->num)) { applyNumInput(&t->num, size); constraintNumInput(t, size); } - + applySnapping(t, size); - + if (t->flag & T_AUTOVALUES) { VECCOPY(size, t->auto_values); } - + VECCOPY(t->values, size); - + SizeToMat3(size, mat); - + if (t->con.applySize) { t->con.applySize(t, NULL, mat); } - + Mat3CpyMat3(t->mat, mat); // used in manipulator - + headerResize(t, size, str); - + for(i = 0, td=t->data; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + ElementResize(t, td, mat); } - + /* evil hack - redo resize if cliping needed */ if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) { SizeToMat3(size, mat); - + if (t->con.applySize) t->con.applySize(t, NULL, mat); - + for(i = 0, td=t->data; i < t->total; i++, td++) ElementResize(t, td, mat); } - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -2551,26 +2473,26 @@ void initToSphere(TransInfo *t) { TransData *td = t->data; int i; - + t->mode = TFM_TOSPHERE; t->transform = ToSphere; - + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->num.flag |= NUM_NULL_ONE | NUM_NO_NEGATIVE; t->flag |= T_NO_CONSTRAINT; - + // Calculate average radius for(i = 0 ; i < t->total; i++, td++) { t->val += VecLenf(t->center, td->iloc); } - + t->val /= (float)t->total; } @@ -2581,56 +2503,56 @@ int ToSphere(TransInfo *t, short mval[2]) int i; char str[64]; TransData *td = t->data; - + ratio = t->values[0]; - + snapGrid(t, &ratio); - + applyNumInput(&t->num, &ratio); - + if (ratio < 0) ratio = 0.0f; else if (ratio > 1) ratio = 1.0f; - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); - + sprintf(str, "To Sphere: %s %s", c, t->proptext); } else { /* default header print */ sprintf(str, "To Sphere: %.4f %s", ratio, t->proptext); } - - + + for(i = 0 ; i < t->total; i++, td++) { float tratio; if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + VecSubf(vec, td->iloc, t->center); - + radius = Normalize(vec); - + tratio = ratio * td->factor; - + VecMulf(vec, radius * (1.0f - tratio) + t->val * tratio); - + VecAddf(td->loc, t->center, vec); } - - + + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -2641,19 +2563,19 @@ void initRotation(TransInfo *t) { t->mode = TFM_ROTATION; t->transform = Rotation; - + initMouseInputMode(t, &t->mouse, INPUT_ANGLE); - + t->ndof.axis = 16; /* Scale down and flip input for rotation */ t->ndof.factor[0] = -0.2f; - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = (float)((5.0/180)*M_PI); t->snap[2] = t->snap[1] * 0.2f; - + if (t->flag & T_2D_EDIT) t->flag |= T_NO_CONSTRAINT; } @@ -2662,7 +2584,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short float vec[3], totmat[3][3], smat[3][3]; float eul[3], fmat[3][3], quat[4]; float *center = t->center; - + /* local constraint shouldn't alter center */ if (around == V3D_LOCAL) { if (t->flag & (T_OBJECT|T_POSE)) { @@ -2675,27 +2597,28 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short } } } - + if (t->flag & T_POINTS) { Mat3MulMat3(totmat, mat, td->mtx); Mat3MulMat3(smat, td->smtx, totmat); - + VecSubf(vec, td->iloc, center); Mat3MulVecfl(smat, vec); - + VecAddf(td->loc, vec, center); - + VecSubf(vec,td->loc,td->iloc); protectedTransBits(td->protectflag, vec); VecAddf(td->loc, td->iloc, vec); - + + if(td->flag & TD_USEQUAT) { Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); Mat3ToQuat(fmat, quat); // Actual transform - + if(td->ext->quat){ QuatMul(td->ext->quat, quat, td->ext->iquat); - + /* is there a reason not to have this here? -jahka */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } @@ -2715,48 +2638,48 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short */ else if (t->flag & T_POSE) { float pmtx[3][3], imtx[3][3]; - + // Extract and invert armature object matrix Mat3CpyMat4(pmtx, t->poseobj->obmat); Mat3Inv(imtx, pmtx); - + if ((td->flag & TD_NO_LOC) == 0) { VecSubf(vec, td->center, center); - + Mat3MulVecfl(pmtx, vec); // To Global space Mat3MulVecfl(mat, vec); // Applying rotation Mat3MulVecfl(imtx, vec); // To Local space - + VecAddf(vec, vec, center); /* vec now is the location where the object has to be */ - + VecSubf(vec, vec, td->center); // Translation needed from the initial location - + Mat3MulVecfl(pmtx, vec); // To Global space Mat3MulVecfl(td->smtx, vec);// To Pose space - + protectedTransBits(td->protectflag, vec); - + VecAddf(td->loc, td->iloc, vec); - + constraintTransLim(t, td); } - + /* rotation */ if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself /* euler or quaternion/axis-angle? */ - if (td->flag & TD_USEQUAT) { + if (td->rotOrder == ROT_MODE_QUAT) { Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); - + Mat3ToQuat(fmat, quat); // Actual transform - + QuatMul(td->ext->quat, quat, td->ext->iquat); /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } - else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + else if (td->rotOrder == ROT_MODE_AXISANGLE) { /* calculate effect based on quats */ float iquat[4]; @@ -2808,93 +2731,67 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* vec now is the location where the object has to be */ VecSubf(vec, vec, td->center); Mat3MulVecfl(td->smtx, vec); - + protectedTransBits(td->protectflag, vec); - - if(td->tdi) { - TransDataIpokey *tdi= td->tdi; - add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]); - add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]); - add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]); - } - else VecAddf(td->loc, td->iloc, vec); + + VecAddf(td->loc, td->iloc, vec); } - - + + constraintTransLim(t, td); - + /* rotation */ if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself /* euler or quaternion? */ - if (td->flag & TD_USEQUAT) { + if ((td->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) { Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); Mat3ToQuat(fmat, quat); // Actual transform - + QuatMul(td->ext->quat, quat, td->ext->iquat); /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } + else if (td->rotOrder == ROT_MODE_AXISANGLE) { + /* calculate effect based on quats */ + float iquat[4]; + + /* td->ext->(i)quat is in axis-angle form, not quats! */ + AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]); + + Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); + Mat3ToQuat(fmat, quat); // Actual transform + + QuatMul(td->ext->quat, quat, iquat); + + /* make temp copy (since stored in same place) */ + QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro + QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); + + /* this function works on end result */ + protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat); + } else { float obmat[3][3]; - - /* are there ipo keys? */ - if(td->tdi) { - TransDataIpokey *tdi= td->tdi; - float current_rot[3]; - float rot[3]; - - /* current IPO value for compatible euler */ - current_rot[0] = (tdi->rotx) ? tdi->rotx[0] : 0.0f; - current_rot[1] = (tdi->roty) ? tdi->roty[0] : 0.0f; - current_rot[2] = (tdi->rotz) ? tdi->rotz[0] : 0.0f; - VecMulf(current_rot, (float)(M_PI_2 / 9.0)); - - /* calculate the total rotatation in eulers */ - VecAddf(eul, td->ext->irot, td->ext->drot); - EulToMat3(eul, obmat); - /* mat = transform, obmat = object rotation */ - Mat3MulMat3(fmat, mat, obmat); - - Mat3ToCompatibleEul(fmat, eul, current_rot); - - /* correct back for delta rot */ - if(tdi->flag & TOB_IPODROT) { - VecSubf(rot, eul, td->ext->irot); - } - else { - VecSubf(rot, eul, td->ext->drot); - } - - VecMulf(rot, (float)(9.0/M_PI_2)); - VecSubf(rot, rot, tdi->oldrot); - - protectedRotateBits(td->protectflag, rot, tdi->oldrot); - - add_tdi_poin(tdi->rotx, tdi->oldrot, rot[0]); - add_tdi_poin(tdi->roty, tdi->oldrot+1, rot[1]); - add_tdi_poin(tdi->rotz, tdi->oldrot+2, rot[2]); - } - else { - Mat3MulMat3(totmat, mat, td->mtx); - Mat3MulMat3(smat, td->smtx, totmat); - - /* calculate the total rotatation in eulers */ - VecAddf(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */ - EulToMat3(eul, obmat); - /* mat = transform, obmat = object rotation */ - Mat3MulMat3(fmat, smat, obmat); - - Mat3ToCompatibleEul(fmat, eul, td->ext->rot); - - /* correct back for delta rot */ - VecSubf(eul, eul, td->ext->drot); - - /* and apply */ - protectedRotateBits(td->protectflag, eul, td->ext->irot); - VECCOPY(td->ext->rot, eul); - } + + Mat3MulMat3(totmat, mat, td->mtx); + Mat3MulMat3(smat, td->smtx, totmat); + + /* calculate the total rotatation in eulers */ + VecAddf(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */ + EulOToMat3(eul, td->rotOrder, obmat); + /* mat = transform, obmat = object rotation */ + Mat3MulMat3(fmat, smat, obmat); + + Mat3ToCompatibleEulO(fmat, eul, td->ext->rot, td->rotOrder); + + /* correct back for delta rot */ + VecSubf(eul, eul, td->ext->drot); + + /* and apply */ + protectedRotateBits(td->protectflag, eul, td->ext->irot); + VECCOPY(td->ext->rot, eul); } - + constraintRotLim(t, td); } } @@ -2905,17 +2802,17 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) TransData *td = t->data; float mat[3][3]; int i; - + VecRotToMat3(axis, angle, mat); - + for(i = 0 ; i < t->total; i++, td++) { - + if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + if (t->con.applyRot) { t->con.applyRot(t, td, axis, NULL); VecRotToMat3(axis, angle * td->factor, mat); @@ -2923,7 +2820,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) else if (t->flag & T_PROP_EDIT) { VecRotToMat3(axis, angle * td->factor, mat); } - + ElementRotation(t, td, mat, t->around); } } @@ -2931,62 +2828,62 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) int Rotation(TransInfo *t, short mval[2]) { char str[64]; - + float final; - + float axis[3]; float mat[3][3]; - + VECCOPY(axis, t->viewinv[2]); VecMulf(axis, -1.0f); Normalize(axis); - + final = t->values[0]; - + applyNDofInput(&t->ndof, &final); - + snapGrid(t, &final); - + if (t->con.applyRot) { t->con.applyRot(t, NULL, axis, &final); } - + applySnapping(t, &final); - + if (hasNumInput(&t->num)) { char c[20]; - + applyNumInput(&t->num, &final); - + outputNumInput(&(t->num), c); - + sprintf(str, "Rot: %s %s %s", &c[0], t->con.text, t->proptext); - + /* Clamp between -180 and 180 */ while (final >= 180.0) final -= 360.0; - + while (final <= -180.0) final += 360.0; - + final *= (float)(M_PI / 180.0); } else { sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext); } - + VecRotToMat3(axis, final, mat); - + // TRANSFORM_FIX_ME // t->values[0] = final; // used in manipulator // Mat3CpyMat3(t->mat, mat); // used in manipulator - + applyRotation(t, final, axis); - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -3204,10 +3101,10 @@ static void applyTranslation(TransInfo *t, float vec[3]) { for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + /* handle snapping rotation before doing the translation */ if (usingSnappingNormal(t)) { @@ -3218,26 +3115,26 @@ static void applyTranslation(TransInfo *t, float vec[3]) { float quat[4]; float mat[3][3]; float angle; - + Crossf(axis, original_normal, t->tsnap.snapNormal); angle = saacos(Inpf(original_normal, t->tsnap.snapNormal)); - + AxisAngleToQuat(quat, axis, angle); - + QuatToMat3(quat, mat); - + ElementRotation(t, td, mat, V3D_LOCAL); } else { float mat[3][3]; - + Mat3One(mat); - + ElementRotation(t, td, mat, V3D_LOCAL); } } - + if (t->con.applyVec) { float pvec[3]; t->con.applyVec(t, td, vec, tvec, pvec); @@ -3245,21 +3142,14 @@ static void applyTranslation(TransInfo *t, float vec[3]) { else { VECCOPY(tvec, vec); } - + Mat3MulVecfl(td->smtx, tvec); VecMulf(tvec, td->factor); - + protectedTransBits(td->protectflag, tvec); - - /* transdata ipokey */ - if(td->tdi) { - TransDataIpokey *tdi= td->tdi; - add_tdi_poin(tdi->locx, tdi->oldloc, tvec[0]); - add_tdi_poin(tdi->locy, tdi->oldloc+1, tvec[1]); - add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]); - } - else VecAddf(td->loc, td->iloc, tvec); - + + VecAddf(td->loc, td->iloc, tvec); + constraintTransLim(t, td); } } @@ -3926,7 +3816,7 @@ int BoneSize(TransInfo *t, short mval[2]) float ratio; int i; char str[60]; - + // TRANSFORM_FIX_ME MOVE TO MOUSE INPUT /* for manipulator, center handle, the scaling can't be done relative to center */ if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) @@ -3937,40 +3827,40 @@ int BoneSize(TransInfo *t, short mval[2]) { ratio = t->values[0]; } - + size[0] = size[1] = size[2] = ratio; - + snapGrid(t, size); - + if (hasNumInput(&t->num)) { applyNumInput(&t->num, size); constraintNumInput(t, size); } - + SizeToMat3(size, mat); - + if (t->con.applySize) { t->con.applySize(t, NULL, mat); } - + Mat3CpyMat3(t->mat, mat); // used in manipulator - + headerBoneSize(t, size, str); - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + ElementBoneSize(t, td, mat); } - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -3981,15 +3871,15 @@ void initBoneEnvelope(TransInfo *t) { t->mode = TFM_BONE_ENVELOPE; t->transform = BoneEnvelope; - + initMouseInputMode(t, &t->mouse, INPUT_SPRING); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->flag |= T_NO_CONSTRAINT; } @@ -3999,31 +3889,31 @@ int BoneEnvelope(TransInfo *t, short mval[2]) float ratio; int i; char str[50]; - + ratio = t->values[0]; - + snapGrid(t, &ratio); - + applyNumInput(&t->num, &ratio); - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); sprintf(str, "Envelope: %s", c); } else { sprintf(str, "Envelope: %3f", ratio); } - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + if (td->val) { /* if the old/original value was 0.0f, then just use ratio */ if (td->ival) @@ -4032,11 +3922,11 @@ int BoneEnvelope(TransInfo *t, short mval[2]) *td->val= ratio; } } - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 66d5ecd4d66..abe73a755dc 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -120,20 +120,9 @@ typedef struct TransCon { /* Apply function pointer for rotation transformation */ } TransCon; -typedef struct TransDataIpokey { - int flag; /* which keys */ - float *locx, *locy, *locz; /* channel pointers */ - float *rotx, *roty, *rotz; - float *quatx, *quaty, *quatz, *quatw; - float *sizex, *sizey, *sizez; - float oldloc[9]; /* storage old values */ - float oldrot[9]; - float oldsize[9]; - float oldquat[12]; -} TransDataIpokey; - typedef struct TransDataExtension { float drot[3]; /* Initial object drot */ + float dquat[4]; /* Initial object dquat */ float dsize[3]; /* Initial object dsize */ float *rot; /* Rotation of the data to transform (Faculative) */ float irot[3]; /* Initial rotation */ @@ -221,7 +210,6 @@ typedef struct TransData { struct Object *ob; struct bConstraint *con; /* for objects/bones, the first constraint in its constraint stack */ TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */ - TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */ TransDataCurveHandleFlags *hdata; /* for curves, stores handle flags for modification/cancel */ void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */ short flag; /* Various flags */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 543bbf13fcc..a49950f15f1 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -379,7 +379,6 @@ static void createTransEdge(bContext *C, TransInfo *t) { Mat3CpyMat3(td->mtx, mtx); td->ext = NULL; - td->tdi = NULL; if (t->mode == TFM_BWEIGHT) { td->val = &(eed->bweight); td->ival = eed->bweight; @@ -509,7 +508,7 @@ static short apply_targetless_ik(Object *ob) /* rotation */ if (parchan->rotmode > 0) Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode); - else if (parchan->rotmode == PCHAN_ROT_AXISANGLE) + else if (parchan->rotmode == ROT_MODE_AXISANGLE) Mat3ToAxisAngle(rmat3, &parchan->quat[1], &parchan->quat[0]); else Mat3ToQuat(rmat3, parchan->quat); @@ -519,7 +518,7 @@ static short apply_targetless_ik(Object *ob) if (data->flag & CONSTRAINT_IK_STRETCH) { if (parchan->rotmode > 0) EulOToMat3(parchan->eul, parchan->rotmode, qrmat); - else if (parchan->rotmode == PCHAN_ROT_AXISANGLE) + else if (parchan->rotmode == ROT_MODE_AXISANGLE) AxisAngleToMat3(&parchan->quat[1], parchan->quat[0], qrmat); else QuatToMat3(parchan->quat, qrmat); @@ -556,10 +555,6 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ob = ob; td->flag = TD_SELECTED; - if (pchan->rotmode == PCHAN_ROT_QUAT) - { - td->flag |= TD_USEQUAT; - } if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) { td->flag |= TD_NOCENTER; @@ -584,15 +579,14 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ext->quat= NULL; VECCOPY(td->ext->irot, pchan->eul); - td->rotOrder= pchan->rotmode; } else { td->ext->rot= NULL; td->ext->quat= pchan->quat; QUATCOPY(td->ext->iquat, pchan->quat); - td->rotOrder= pchan->rotmode; } + td->rotOrder= pchan->rotmode; /* proper way to get parent transform + own transform + constraints transform */ @@ -1016,7 +1010,6 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob) tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt"); for(i=0; i<t->total; i++, td++, tdx++) { td->ext= tdx; - td->tdi = NULL; td->val = NULL; } @@ -1100,7 +1093,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->loc = NULL; td->ext = NULL; - td->tdi = NULL; td++; } @@ -1116,7 +1108,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->loc = NULL; td->ext = NULL; - td->tdi = NULL; td++; } @@ -1151,7 +1142,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) Mat3Ortho(td->axismtx); td->ext = NULL; - td->tdi = NULL; td++; } @@ -1168,7 +1158,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->flag= TD_SELECTED; td->ext = NULL; - td->tdi = NULL; td++; } @@ -1196,7 +1185,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) } td->ext = NULL; - td->tdi = NULL; td->val = NULL; td++; @@ -1219,7 +1207,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->extra = ebo; /* to fix roll */ td->ext = NULL; - td->tdi = NULL; td->val = NULL; td++; @@ -1272,7 +1259,6 @@ static void createTransMBallVerts(bContext *C, TransInfo *t) Mat3CpyMat3(td->mtx, mtx); td->ext = tx; - td->tdi = NULL; /* Radius of MetaElem (mass of MetaElem influence) */ if(ml->flag & MB_SCALE_RAD){ @@ -1437,7 +1423,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) else td->flag= 0; } td->ext = NULL; - td->tdi = NULL; td->val = NULL; hdata = initTransDataCurveHandes(td, bezt); @@ -1458,7 +1443,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) if(bezt->f2 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; td->ext = NULL; - td->tdi = NULL; if (t->mode==TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */ td->val = &(bezt->radius); @@ -1498,7 +1482,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) else td->flag= 0; } td->ext = NULL; - td->tdi = NULL; td->val = NULL; if (hdata==NULL) { /* if the handle was not saved by the previous handle */ @@ -1538,7 +1521,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) if(bp->f1 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; td->ext = NULL; - td->tdi = NULL; if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) { td->val = &(bp->radius); @@ -1614,7 +1596,6 @@ static void createTransLatticeVerts(bContext *C, TransInfo *t) Mat3CpyMat3(td->mtx, mtx); td->ext = NULL; - td->tdi = NULL; td->val = NULL; td++; @@ -1725,7 +1706,6 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) td->ob = ob; td->ext = tx; - td->tdi = NULL; if(t->mode == TFM_BAKE_TIME) { td->val = key->time; td->ival = *(key->time); @@ -1949,7 +1929,6 @@ static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert td->axismtx[1][2] = 0.0f; td->ext = NULL; - td->tdi = NULL; td->val = NULL; td->extra = NULL; if (t->mode == TFM_BWEIGHT) { @@ -2429,7 +2408,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; if(selected) { td->flag |= TD_SELECTED; @@ -2729,7 +2708,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; td->flag |= TD_SELECTED; td->dist= 0.0f; @@ -2760,7 +2739,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; td->flag |= TD_SELECTED; td->dist= 0.0f; @@ -3311,7 +3290,7 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; /* store AnimData info in td->extra, for applying mapping when flushing */ td->extra= adt; @@ -3744,98 +3723,6 @@ void flushTransGraphData(TransInfo *t) } } -/* **************** IpoKey stuff, for Object TransData ********** */ - -/* while transforming */ -void add_tdi_poin(float *poin, float *old, float delta) -{ - if(poin) { - poin[0]= old[0]+delta; - poin[-3]= old[3]+delta; - poin[3]= old[6]+delta; - } -} - -#if 0 // TRANSFORM_FIX_ME -/* storage of bezier triple. thats why -3 and +3! */ -static void set_tdi_old(float *old, float *poin) -{ - old[0]= *(poin); - old[3]= *(poin-3); - old[6]= *(poin+3); -} - -/* fill ipokey transdata with old vals and pointers */ -static void ipokey_to_transdata(IpoKey *ik, TransData *td) -{ - extern int ob_ar[]; // blenkernel ipo.c - TransDataIpokey *tdi= td->tdi; - BezTriple *bezt; - int a, delta= 0; - - td->val= NULL; // is read on ESC - - for(a=0; a<OB_TOTIPO; a++) { - if(ik->data[a]) { - bezt= ik->data[a]; - - switch( ob_ar[a] ) { - case OB_LOC_X: - case OB_DLOC_X: - tdi->locx= &(bezt->vec[1][1]); break; - case OB_LOC_Y: - case OB_DLOC_Y: - tdi->locy= &(bezt->vec[1][1]); break; - case OB_LOC_Z: - case OB_DLOC_Z: - tdi->locz= &(bezt->vec[1][1]); break; - - case OB_DROT_X: - delta= 1; - case OB_ROT_X: - tdi->rotx= &(bezt->vec[1][1]); break; - case OB_DROT_Y: - delta= 1; - case OB_ROT_Y: - tdi->roty= &(bezt->vec[1][1]); break; - case OB_DROT_Z: - delta= 1; - case OB_ROT_Z: - tdi->rotz= &(bezt->vec[1][1]); break; - - case OB_SIZE_X: - case OB_DSIZE_X: - tdi->sizex= &(bezt->vec[1][1]); break; - case OB_SIZE_Y: - case OB_DSIZE_Y: - tdi->sizey= &(bezt->vec[1][1]); break; - case OB_SIZE_Z: - case OB_DSIZE_Z: - tdi->sizez= &(bezt->vec[1][1]); break; - } - } - } - - /* oldvals for e.g. undo */ - if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx); - if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy); - if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz); - - /* remember, for mapping curves ('1'=10 degrees) */ - if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx); - if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty); - if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz); - - /* this is not allowed to be dsize! */ - if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex); - if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey); - if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez); - - tdi->flag= TOB_IPO; - if(delta) tdi->flag |= TOB_IPODROT; -} -#endif - /* *************************** Object Transform data ******************* */ /* Little helper function for ObjectToTransData used to give certain @@ -4053,7 +3940,7 @@ static TransData *SeqToTransData(TransInfo *t, TransData *td, TransData2D *td2d, memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; td->flag |= TD_SELECTED; td->dist= 0.0; @@ -4194,20 +4081,20 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * if (skip_invert == 0 && (ob->track || constinv==0)) { track= ob->track; ob->track= NULL; - + if (constinv == 0) { fakecons.first = ob->constraints.first; fakecons.last = ob->constraints.last; ob->constraints.first = ob->constraints.last = NULL; } - + where_is_object(t->scene, ob); - + if (constinv == 0) { ob->constraints.first = fakecons.first; ob->constraints.last = fakecons.last; } - + ob->track= track; } else @@ -4221,6 +4108,10 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * td->ext->rot = ob->rot; VECCOPY(td->ext->irot, ob->rot); VECCOPY(td->ext->drot, ob->drot); + + td->ext->quat = ob->quat; + QUATCOPY(td->ext->iquat, ob->quat); + QUATCOPY(td->ext->dquat, ob->dquat); td->ext->size = ob->size; VECCOPY(td->ext->isize, ob->size); @@ -4516,15 +4407,16 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); } if (doRot) { - if (pchan->rotmode == PCHAN_ROT_QUAT) { - sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name); + // FIXME: better to just use the keyingsets for this instead... + if (pchan->rotmode == ROT_MODE_QUAT) { + sprintf(buf, "pose.pose_channels[\"%s\"].rotation_quaternion", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag); } else { - sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name); + sprintf(buf, "pose.pose_channels[\"%s\"].rotation_euler", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); @@ -4544,7 +4436,8 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - if (pchan->rotmode == PCHAN_ROT_QUAT) { + // FIXME: better to just use the keyingsets for this instead... + if (pchan->rotmode == ROT_MODE_QUAT) { sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); @@ -4552,7 +4445,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag); } else { - sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name); + sprintf(buf, "pose.pose_channels[\"%s\"].rotation_euler", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); @@ -5001,30 +4894,7 @@ static void createTransObject(bContext *C, TransInfo *t) set_trans_object_base_flags(C, t); /* count */ -#if 0 // TRANSFORM_FIX_ME - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) - { - /* store ipo keys? */ - if ((ob->id.lib == 0) && (ob->ipo) && (ob->ipo->showkey) && (ob->ipoflag & OB_DRAWKEY)) { - elems.first= elems.last= NULL; - make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */ - - pushdata(&elems, sizeof(ListBase)); - - for(ik= elems.first; ik; ik= ik->next) - t->total++; - - if(elems.first==NULL) - t->total++; - } -// else { - t->total++; -// } - } - CTX_DATA_END; -#else t->total= CTX_DATA_COUNT(C, selected_objects); -#endif if(!t->total) { /* clear here, main transform function escapes too */ @@ -5038,92 +4908,27 @@ static void createTransObject(bContext *C, TransInfo *t) CTX_DATA_BEGIN(C, Base*, base, selected_bases) { Object *ob= base->object; - + td->flag = TD_SELECTED; td->protectflag= ob->protectflag; td->ext = tx; - + td->rotOrder= ob->rotmode; + if (base->flag & BA_TRANSFORM_CHILD) { td->flag |= TD_NOCENTER; td->flag |= TD_NO_LOC; } - + /* select linked objects, but skip them later */ if (ob->id.lib != 0) { td->flag |= TD_SKIP; } - - /* store ipo keys? */ - // TRANSFORM_FIX_ME -#if 0 - if((ob->id.lib == 0) && (ob->ipo) && (ob->ipo->showkey) && (ob->ipoflag & OB_DRAWKEY)) { - - popfirst(&elems); // bring back pushed listbase - - if(elems.first) { - int cfraont; - int ipoflag; - - base->flag |= BA_DO_IPO+BA_WAS_SEL; - base->flag &= ~SELECT; - - cfraont= CFRA; - set_no_parent_ipo(1); - ipoflag= ob->ipoflag; - ob->ipoflag &= ~OB_OFFS_OB; - - /* - * This is really EVIL code that pushes down Object values - * (loc, dloc, orig, size, dsize, rot, drot) - * */ - - pushdata((void*)ob->loc, 7 * 3 * sizeof(float)); // tsk! tsk! - - for(ik= elems.first; ik; ik= ik->next) { - - /* weak... this doesn't correct for floating values, giving small errors */ - CFRA= (int)(ik->val/t->scene->r.framelen); - - do_ob_ipo(ob); - ObjectToTransData(C, t, td, ob); // does where_is_object() - - td->flag= TD_SELECTED; - - td->tdi= MEM_callocN(sizeof(TransDataIpokey), "TransDataIpokey"); - /* also does tdi->flag and oldvals, needs to be after ob_to_transob()! */ - ipokey_to_transdata(ik, td); - - td++; - tx++; - if(ik->next) td->ext= tx; // prevent corrupting mem! - } - free_ipokey(&elems); - - poplast(ob->loc); - set_no_parent_ipo(0); - - CFRA= cfraont; - ob->ipoflag= ipoflag; - - where_is_object(t->scene, ob); // restore - } - else { - ObjectToTransData(C, t, td, ob); - td->tdi = NULL; - td->val = NULL; - td++; - tx++; - } - } -#endif -// else { - ObjectToTransData(C, t, td, ob); - td->tdi = NULL; - td->val = NULL; - td++; - tx++; -// } + + ObjectToTransData(C, t, td, ob); + td->val = NULL; + td++; + tx++; } CTX_DATA_END; } @@ -5145,7 +4950,7 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; td->flag |= TD_SELECTED; td->dist= 0.0; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index ea5653dc130..88469794e5d 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -125,19 +125,19 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3]) if (t->persp != V3D_ORTHO) { float p1[4], p2[4]; - + VECCOPY(p1, coord); p1[3] = 1.0f; VECCOPY(p2, p1); p2[3] = 1.0f; Mat4MulVec4fl(t->viewmat, p2); - + p2[0] = 2.0f * p2[0]; p2[1] = 2.0f * p2[1]; p2[2] = 2.0f * p2[2]; - + Mat4MulVec4fl(t->viewinv, p2); - + VecSubf(vec, p1, p2); } else { @@ -153,11 +153,11 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) ModifierData *md= ob->modifiers.first; float tolerance[3] = {0.0f, 0.0f, 0.0f}; int axis = 0; - + for (; md; md=md->next) { if (md->type==eModifierType_Mirror) { MirrorModifierData *mmd = (MirrorModifierData*) md; - + if(mmd->flag & MOD_MIR_CLIPPING) { axis = 0; if(mmd->flag & MOD_MIR_AXIS_X) { @@ -176,35 +176,35 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) float mtx[4][4], imtx[4][4]; int i; TransData *td = t->data; - + if (mmd->mirror_ob) { float obinv[4][4]; - + Mat4Invert(obinv, mmd->mirror_ob->obmat); Mat4MulMat4(mtx, ob->obmat, obinv); Mat4Invert(imtx, mtx); } - + for(i = 0 ; i < t->total; i++, td++) { int clip; float loc[3], iloc[3]; - + if (td->flag & TD_NOACTION) break; if (td->loc==NULL) break; - + if (td->flag & TD_SKIP) continue; - + VecCopyf(loc, td->loc); VecCopyf(iloc, td->iloc); - + if (mmd->mirror_ob) { VecMat4MulVecfl(loc, mtx, loc); VecMat4MulVecfl(iloc, mtx, iloc); } - + clip = 0; if(axis & 1) { if(fabs(iloc[0])<=tolerance[0] || @@ -213,7 +213,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) clip = 1; } } - + if(axis & 2) { if(fabs(iloc[1])<=tolerance[1] || loc[1]*iloc[1]<0.0f) { @@ -236,7 +236,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) } } } - + } } } @@ -248,7 +248,7 @@ static void editmesh_apply_to_mirror(TransInfo *t) TransData *td = t->data; EditVert *eve; int i; - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -256,7 +256,7 @@ static void editmesh_apply_to_mirror(TransInfo *t) break; if (td->flag & TD_SKIP) continue; - + eve = td->extra; if(eve) { eve->co[0]= -td->loc[0]; @@ -620,9 +620,9 @@ void recalcData(TransInfo *t) if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { Curve *cu= t->obedit->data; Nurb *nu= cu->editnurb->first; - + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - + if (t->state == TRANS_CANCEL) { while(nu) { calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ @@ -648,11 +648,11 @@ void recalcData(TransInfo *t) else if (t->obedit->type == OB_MESH) { if(t->spacetype==SPACE_IMAGE) { SpaceImage *sima= t->sa->spacedata.first; - + flushTransUVs(t); if(sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_re_solve(); - + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); } else { EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; @@ -667,9 +667,9 @@ void recalcData(TransInfo *t) } if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) editmesh_apply_to_mirror(t); - + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - + recalc_editnormals(em); } } @@ -679,10 +679,10 @@ void recalcData(TransInfo *t) EditBone *ebo; TransData *td = t->data; int i; - + /* Ensure all bones are correctly adjusted */ for (ebo = edbo->first; ebo; ebo = ebo->next){ - + if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ /* If this bone has a parent tip that has been moved */ if (ebo->parent->flag & BONE_TIPSEL){ @@ -695,7 +695,7 @@ void recalcData(TransInfo *t) if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head; } } - + /* on extrude bones, oldlength==0.0f, so we scale radius of points */ ebo->length= VecLenf(ebo->head, ebo->tail); if(ebo->oldlength==0.0f) { @@ -715,8 +715,8 @@ void recalcData(TransInfo *t) ebo->oldlength= ebo->length; } } - - + + if (t->mode != TFM_BONE_ROLL) { /* fix roll */ @@ -726,10 +726,10 @@ void recalcData(TransInfo *t) { float vec[3], up_axis[3]; float qrot[4]; - + ebo = td->extra; VECCOPY(up_axis, td->axismtx[2]); - + if (t->mode != TFM_ROTATION) { VecSubf(vec, ebo->tail, ebo->head); @@ -741,15 +741,15 @@ void recalcData(TransInfo *t) { Mat3MulVecfl(t->mat, up_axis); } - + ebo->roll = ED_rollBoneToVector(ebo, up_axis); } } } - + if(arm->flag & ARM_MIRROR_EDIT) transform_armature_mirror_update(t->obedit); - + } else DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ @@ -757,7 +757,7 @@ void recalcData(TransInfo *t) else if( (t->flag & T_POSE) && t->poseobj) { Object *ob= t->poseobj; bArmature *arm= ob->data; - + /* if animtimer is running, and the object already has animation data, * check if the auto-record feature means that we should record 'samples' * (i.e. uneditable animation values) @@ -769,7 +769,7 @@ void recalcData(TransInfo *t) animrecord_check_state(t->scene, &ob->id, t->animtimer); autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); } - + /* old optimize trick... this enforces to bypass the depgraph */ if (!(arm->flag & ARM_DELAYDEFORM)) { DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ @@ -780,13 +780,13 @@ void recalcData(TransInfo *t) else { for(base= FIRSTBASE; base; base= base->next) { Object *ob= base->object; - + /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */ if(base->flag & BA_HAS_RECALC_OB) ob->recalc |= OB_RECALC_OB; if(base->flag & BA_HAS_RECALC_DATA) ob->recalc |= OB_RECALC_DATA; - + /* if object/base is selected */ if ((base->flag & SELECT) || (ob->flag & SELECT)) { /* if animtimer is running, and the object already has animation data, @@ -799,7 +799,7 @@ void recalcData(TransInfo *t) autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode); } } - + /* proxy exception */ if(ob->proxy) ob->proxy->recalc |= ob->recalc; @@ -807,7 +807,7 @@ void recalcData(TransInfo *t) group_tag_recalc(ob->proxy_group->dup_group); } } - + /* update shaded drawmode while transform */ if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED) reshadeall_displist(t->scene); @@ -821,18 +821,18 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) if (t->spacetype == SPACE_VIEW3D) { View3D *v3d = t->view; - + glPushMatrix(); - + //if(t->obedit) glLoadMatrixf(t->obedit->obmat); // sets opengl viewing - - + + VecCopyf(v3, dir); VecMulf(v3, v3d->far); - + VecSubf(v2, center, v3); VecAddf(v1, center, v3); - + if (options & DRAWLIGHT) { col[0] = col[1] = col[2] = 220; } @@ -841,13 +841,13 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) } UI_make_axis_color(col, col2, axis); glColor3ubv((GLubyte *)col2); - + setlinestyle(0); glBegin(GL_LINE_STRIP); glVertex3fv(v1); glVertex3fv(v2); glEnd(); - + glPopMatrix(); } } @@ -864,33 +864,33 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) ARegion *ar = CTX_wm_region(C); ScrArea *sa = CTX_wm_area(C); Object *obedit = CTX_data_edit_object(C); - + /* moving: is shown in drawobject() (transform color) */ // TRANSFORM_FIX_ME // if(obedit || (t->flag & T_POSE) ) G.moving= G_TRANSFORM_EDIT; // else if(G.f & G_PARTICLEEDIT) G.moving= G_TRANSFORM_PARTICLE; // else G.moving= G_TRANSFORM_OBJ; - + t->scene = sce; t->sa = sa; t->ar = ar; t->obedit = obedit; t->settings = ts; - + t->data = NULL; t->ext = NULL; - + t->helpline = HLP_NONE; - + t->flag = 0; - + t->redraw = 1; /* redraw first time */ - + if (event) { t->imval[0] = event->x - t->ar->winrct.xmin; t->imval[1] = event->y - t->ar->winrct.ymin; - + t->event_type = event->type; } else @@ -898,45 +898,45 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->imval[0] = 0; t->imval[1] = 0; } - + t->con.imval[0] = t->imval[0]; t->con.imval[1] = t->imval[1]; - + t->mval[0] = t->imval[0]; t->mval[1] = t->imval[1]; - + t->transform = NULL; t->handleEvent = NULL; - + t->total = 0; - + t->val = 0.0f; - + t->vec[0] = t->vec[1] = t->vec[2] = 0.0f; - + t->center[0] = t->center[1] = t->center[2] = 0.0f; - + Mat3One(t->mat); - + t->spacetype = sa->spacetype; if(t->spacetype == SPACE_VIEW3D) { View3D *v3d = sa->spacedata.first; - + t->view = v3d; t->animtimer= CTX_wm_screen(C)->animtimer; - + if(v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN; t->around = v3d->around; - + if (op && RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_orientation")) { t->current_orientation = RNA_enum_get(op->ptr, "constraint_orientation"); - + if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C) - 1) { t->current_orientation = V3D_MANIP_GLOBAL; @@ -958,10 +958,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) { // XXX for now, get View2D from the active region t->view = &ar->v2d; - + t->around = V3D_CENTER; } - + if (op && RNA_struct_find_property(op->ptr, "mirror") && RNA_property_is_set(op->ptr, "mirror")) { if (RNA_boolean_get(op->ptr, "mirror")) @@ -977,7 +977,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->flag |= T_MIRROR; } } - + /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */ if (op && RNA_struct_find_property(op->ptr, "proportional")) { @@ -996,12 +996,12 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) { if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) { t->flag |= T_PROP_EDIT; - + if(ts->proportional == 2) t->flag |= T_PROP_CONNECTED; // yes i know, has to become define } } - + if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size")) { t->prop_size = RNA_float_get(op->ptr, "proportional_size"); @@ -1010,8 +1010,8 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) { t->prop_size = ts->proportional_size; } - - + + /* TRANSFORM_FIX_ME rna restrictions */ if (t->prop_size <= 0) { @@ -1031,12 +1031,12 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) { t->options |= CTX_NO_PET; } - - + + setTransformViewMatrices(t); initNumInput(&t->num); initNDofInput(&t->ndof); - + return 1; } @@ -1044,20 +1044,20 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) void postTrans (TransInfo *t) { TransData *td; - + if (t->draw_handle) { ED_region_draw_cb_exit(t->ar->type, t->draw_handle); } - + /* postTrans can be called when nothing is selected, so data is NULL already */ if (t->data) { int a; - + /* since ipokeys are optional on objects, we mallocced them per trans-data */ for(a=0, td= t->data; a<t->total; a++, td++) { - if(td->tdi) MEM_freeN(td->tdi); - if (td->flag & TD_BEZTRIPLE) MEM_freeN(td->hdata); + if (td->flag & TD_BEZTRIPLE) + MEM_freeN(td->hdata); } MEM_freeN(t->data); } @@ -1067,20 +1067,18 @@ void postTrans (TransInfo *t) MEM_freeN(t->data2d); t->data2d= NULL; } - + if(t->spacetype==SPACE_IMAGE) { SpaceImage *sima= t->sa->spacedata.first; if(sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL); } - else if(ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { - } - + if (t->mouse.data) { MEM_freeN(t->mouse.data); } - + if (t->customFree) { t->customFree(t); } @@ -1092,7 +1090,7 @@ void postTrans (TransInfo *t) void applyTransObjects(TransInfo *t) { TransData *td; - + for (td = t->data; td < t->data + t->total; td++) { VECCOPY(td->iloc, td->loc); if (td->ext->rot) { @@ -1105,16 +1103,6 @@ void applyTransObjects(TransInfo *t) recalcData(t); } -/* helper for below */ -static void restore_ipokey(float *poin, float *old) -{ - if(poin) { - poin[0]= old[0]; - poin[-3]= old[3]; - poin[3]= old[6]; - } -} - static void restoreElement(TransData *td) { /* TransData for crease has no loc */ if (td->loc) { @@ -1130,45 +1118,27 @@ static void restoreElement(TransData *td) { if (td->ext->size) { VECCOPY(td->ext->size, td->ext->isize); } - if(td->flag & TD_USEQUAT) { - if (td->ext->quat) { - QUATCOPY(td->ext->quat, td->ext->iquat); - } + if (td->ext->quat) { + QUATCOPY(td->ext->quat, td->ext->iquat); } } - + if (td->flag & TD_BEZTRIPLE) { *(td->hdata->h1) = td->hdata->ih1; *(td->hdata->h2) = td->hdata->ih2; } - - if(td->tdi) { - TransDataIpokey *tdi= td->tdi; - - restore_ipokey(tdi->locx, tdi->oldloc); - restore_ipokey(tdi->locy, tdi->oldloc+1); - restore_ipokey(tdi->locz, tdi->oldloc+2); - - restore_ipokey(tdi->rotx, tdi->oldrot); - restore_ipokey(tdi->roty, tdi->oldrot+1); - restore_ipokey(tdi->rotz, tdi->oldrot+2); - - restore_ipokey(tdi->sizex, tdi->oldsize); - restore_ipokey(tdi->sizey, tdi->oldsize+1); - restore_ipokey(tdi->sizez, tdi->oldsize+2); - } } void restoreTransObjects(TransInfo *t) { TransData *td; - + for (td = t->data; td < t->data + t->total; td++) { restoreElement(td); } - + Mat3One(t->mat); - + recalcData(t); } @@ -1177,7 +1147,7 @@ void calculateCenter2D(TransInfo *t) if (t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; float vec[3]; - + VECCOPY(vec, t->center); Mat4MulVecfl(ob->obmat, vec); projectIntView(t, vec, t->center2d); @@ -1190,21 +1160,21 @@ void calculateCenter2D(TransInfo *t) void calculateCenterCursor(TransInfo *t) { float *cursor; - + cursor = give_cursor(t->scene, t->view); VECCOPY(t->center, cursor); - + /* If edit or pose mode, move cursor in local space */ if (t->flag & (T_EDIT|T_POSE)) { Object *ob = t->obedit?t->obedit:t->poseobj; float mat[3][3], imat[3][3]; - + VecSubf(t->center, t->center, ob->obmat[3]); Mat3CpyMat4(mat, ob->obmat); Mat3Inv(imat, mat); Mat3MulVecfl(imat, t->center); } - + calculateCenter2D(t); } @@ -1212,15 +1182,15 @@ void calculateCenterCursor2D(TransInfo *t) { View2D *v2d= t->view; float aspx=1.0, aspy=1.0; - + if(t->spacetype==SPACE_IMAGE) /* only space supported right now but may change */ ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); - + if (v2d) { t->center[0] = v2d->cursor[0] * aspx; t->center[1] = v2d->cursor[1] * aspy; } - + calculateCenter2D(t); } @@ -1229,7 +1199,7 @@ void calculateCenterMedian(TransInfo *t) float partial[3] = {0.0f, 0.0f, 0.0f}; int total = 0; int i; - + for(i = 0; i < t->total; i++) { if (t->data[i].flag & TD_SELECTED) { if (!(t->data[i].flag & TD_NOCENTER)) @@ -1249,7 +1219,7 @@ void calculateCenterMedian(TransInfo *t) if(i) VecMulf(partial, 1.0f / total); VECCOPY(t->center, partial); - + calculateCenter2D(t); } @@ -1279,7 +1249,7 @@ void calculateCenterBound(TransInfo *t) } VecAddf(t->center, min, max); VecMulf(t->center, 0.5); - + calculateCenter2D(t); } @@ -1315,7 +1285,7 @@ void calculateCenter(TransInfo *t) break; } /* END EDIT MODE ACTIVE ELEMENT */ #endif - + calculateCenterMedian(t); if((t->flag & (T_EDIT|T_POSE))==0) { @@ -1327,10 +1297,10 @@ void calculateCenter(TransInfo *t) projectIntView(t, t->center, t->center2d); } } - + } } - + /* setting constraint center */ VECCOPY(t->con.center, t->center); if(t->flag & (T_EDIT|T_POSE)) @@ -1338,8 +1308,8 @@ void calculateCenter(TransInfo *t) Object *ob= t->obedit?t->obedit:t->poseobj; Mat4MulVecfl(ob->obmat, t->con.center); } - - /* voor panning from cameraview */ + + /* for panning from cameraview */ if(t->flag & T_OBJECT) { if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW) @@ -1347,21 +1317,21 @@ void calculateCenter(TransInfo *t) View3D *v3d = t->view; Scene *scene = t->scene; RegionView3D *rv3d = t->ar->regiondata; - + if(v3d->camera == OBACT && rv3d->persp==V3D_CAMOB) { float axis[3]; /* persinv is nasty, use viewinv instead, always right */ VECCOPY(axis, t->viewinv[2]); Normalize(axis); - + /* 6.0 = 6 grid units */ axis[0]= t->center[0]- 6.0f*axis[0]; axis[1]= t->center[1]- 6.0f*axis[1]; axis[2]= t->center[2]- 6.0f*axis[2]; - + projectIntView(t, axis, t->center2d); - + /* rotate only needs correct 2d center, grab needs initgrabz() value */ if(t->mode==TFM_TRANSLATION) { @@ -1371,14 +1341,14 @@ void calculateCenter(TransInfo *t) } } } - + if(t->spacetype==SPACE_VIEW3D) { /* initgrabz() defines a factor for perspective depth correction, used in window_to_3d_delta() */ if(t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; float vec[3]; - + VECCOPY(vec, t->center); Mat4MulVecfl(ob->obmat, vec); initgrabz(t->ar->regiondata, vec[0], vec[1], vec[2]); @@ -1418,7 +1388,7 @@ void calculatePropRatio(TransInfo *t) /* Use rdist for falloff calculations, it is the real distance */ td->flag &= ~TD_NOACTION; dist= (t->prop_size-td->rdist)/t->prop_size; - + /* * Clamp to positive numbers. * Certain corner cases with connectivity and individual centers @@ -1426,7 +1396,7 @@ void calculatePropRatio(TransInfo *t) */ if (dist < 0.0f) dist = 0.0f; - + switch(t->prop_mode) { case PROP_SHARP: td->factor= dist*dist; @@ -1493,20 +1463,20 @@ float get_drawsize(ARegion *ar, float *co) { RegionView3D *rv3d= ar->regiondata; float size, vec[3], len1, len2; - + /* size calculus, depending ortho/persp settings, like initgrabz() */ size= rv3d->persmat[0][3]*co[0]+ rv3d->persmat[1][3]*co[1]+ rv3d->persmat[2][3]*co[2]+ rv3d->persmat[3][3]; - + VECCOPY(vec, rv3d->persinv[0]); len1= Normalize(vec); VECCOPY(vec, rv3d->persinv[1]); len2= Normalize(vec); - + size*= 0.01f*(len1>len2?len1:len2); - + /* correct for window size to make widgets appear fixed size */ if(ar->winx > ar->winy) size*= 1000.0f/(float)ar->winx; else size*= 1000.0f/(float)ar->winy; - + return size; } diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index 4aebda1347c..dc0c2c4c12f 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -785,7 +785,7 @@ static bool joint_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintV /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */ EulOToMat3(chan->eul, chan->rotmode, rmat); } - else if (chan->rotmode == PCHAN_ROT_AXISANGLE) { + else if (chan->rotmode == ROT_MODE_AXISANGLE) { /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */ AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat); } diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 2ed08150f3e..05a4e502c84 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -202,24 +202,25 @@ typedef enum ePchan_IkFlag { } ePchan_IkFlag; -/* PoseChannel->rotmode */ -typedef enum ePchan_RotMode { +/* PoseChannel->rotmode and Object->rotmode */ +typedef enum eRotationModes { /* quaternion rotations (default, and for older Blender versions) */ - PCHAN_ROT_QUAT = 0, + ROT_MODE_QUAT = 0, /* euler rotations - keep in sync with enum in BLI_arithb.h */ - PCHAN_ROT_XYZ = 1, /* Blender 'default' (classic) - must be as 1 to sync with PoseChannel rotmode */ - PCHAN_ROT_XZY, - PCHAN_ROT_YXZ, - PCHAN_ROT_YZX, - PCHAN_ROT_ZXY, - PCHAN_ROT_ZYX, + ROT_MODE_EUL = 1, /* Blender 'default' (classic) - must be as 1 to sync with arithb defines */ + ROT_MODE_XYZ = 1, /* Blender 'default' (classic) - must be as 1 to sync with arithb defines */ + ROT_MODE_XZY, + ROT_MODE_YXZ, + ROT_MODE_YZX, + ROT_MODE_ZXY, + ROT_MODE_ZYX, /* NOTE: space is reserved here for 18 other possible * euler rotation orders not implemented */ - PCHAN_ROT_MAX, /* sentinel for Py API*/ + ROT_MODE_MAX, /* sentinel for Py API */ /* axis angle rotations */ - PCHAN_ROT_AXISANGLE = -1 -} ePchan_RotMode; + ROT_MODE_AXISANGLE = -1 +} eRotationModes; /* Pose ------------------------------------ */ @@ -265,6 +266,8 @@ typedef enum ePose_Flags { POSE_GAME_ENGINE = (1<<6), } ePose_Flags; +/* IK Solvers ------------------------------------ */ + /* bPose->iksolver and bPose->ikparam->iksolver */ typedef enum { IKSOLVER_LEGACY = 0, diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index c1e9ed4be40..9921878e926 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -632,7 +632,7 @@ typedef enum eKSP_TemplateTypes { KSP_TEMPLATE_CONSTRAINT = (1<<2), /* #con - active only */ KSP_TEMPLATE_NODE = (1<<3), /* #nod - selected node */ - KSP_TEMPLATE_PCHAN_ROT = (1<<16), /* modify rotation paths based on rotation mode of Pose Channel */ + KSP_TEMPLATE_ROT = (1<<16), /* modify rotation paths based on rotation mode of Object or Pose Channel */ } eKSP_TemplateTypes; /* ---------------- */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index f0fd3e60cf2..a6532409e6e 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -134,7 +134,7 @@ typedef struct Object { float loc[3], dloc[3], orig[3]; float size[3], dsize[3]; float rot[3], drot[3]; - /* float quat[4], dquat[4]; (not used yet) */ + float quat[4], dquat[4]; float obmat[4][4]; float parentinv[4][4]; /* inverse result of parent, so that object doesn't 'stick' to parent */ float constinv[4][4]; /* inverse result of constraints. doesn't include effect of parent or object local transform */ @@ -176,9 +176,11 @@ typedef struct Object { float max_vel; /* clamp the maximum velocity 0.0 is disabled */ float min_vel; /* clamp the maximum velocity 0.0 is disabled */ float m_contactProcessingThreshold; - + + short rotmode; /* rotation mode - uses defines set out in DNA_action_types.h for PoseChannel rotations... */ + char dt, dtx; - char empty_drawtype, pad1[5]; + char empty_drawtype, pad1[3]; float empty_drawsize; float dupfacesca; /* dupliface scale */ @@ -313,6 +315,7 @@ extern Object workob; /* (short) transflag */ #define OB_OFFS_LOCAL 1 + // XXX OB_QUAT was never used, but is now depreceated in favour of standard rotation handling... #define OB_QUAT 2 #define OB_NEG_SCALE 4 #define OB_DUPLI (8+16+256+512+2048) @@ -402,6 +405,7 @@ extern Object workob; #define BA_HAS_RECALC_OB 4 #define BA_HAS_RECALC_DATA 8 + // XXX DEPRECEATED SETTING... #define BA_DO_IPO 32 #define BA_FROMSET 128 diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 5fff2af29ff..98df8c34d58 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -108,8 +108,9 @@ typedef enum PropertySubType { PROP_MATRIX = 25, PROP_EULER = 26|PROP_UNIT_ROTATION, PROP_QUATERNION = 27, - PROP_XYZ = 28, - PROP_RGB = 29, + PROP_AXISANGLE = 28, + PROP_XYZ = 29, + PROP_RGB = 30, /* booleans */ PROP_LAYER = 40, diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 961fb9a3d0b..63b58f27c53 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1416,6 +1416,7 @@ static const char *rna_property_subtypename(PropertyType type) case PROP_MATRIX: return "PROP_MATRIX"; case PROP_EULER: return "PROP_EULER"; case PROP_QUATERNION: return "PROP_QUATERNION"; + case PROP_AXISANGLE: return "PROP_AXISANGLE"; case PROP_VELOCITY: return "PROP_VELOCITY"; case PROP_ACCELERATION: return "PROP_ACCELERATION"; case PROP_XYZ: return "PROP_XYZ"; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 55893b42a92..21fbc9fa66d 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -620,7 +620,7 @@ char RNA_property_array_item_char(PropertyRNA *prop, int index) PropertySubType subtype= rna_ensure_property(prop)->subtype; /* get string to use for array index */ - if ((index < 4) && (subtype == PROP_QUATERNION)) + if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) return quatitem[index]; else if((index < 4) && ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION)) return vectoritem[index]; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 5c665c0d730..a2b4d6d7335 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -31,6 +31,7 @@ #include "rna_internal.h" +#include "DNA_action_types.h" #include "DNA_customdata_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" @@ -82,6 +83,8 @@ EnumPropertyItem object_type_items[] = { #ifdef RNA_RUNTIME +#include "BLI_arithb.h" + #include "DNA_key_types.h" #include "BKE_armature.h" @@ -446,6 +449,43 @@ static void rna_Object_active_particle_system_index_set(struct PointerRNA *ptr, psys_set_current_num(ob, value); } +/* rotation - euler angles */ +static void rna_Object_rotation_euler_get(PointerRNA *ptr, float *value) +{ + Object *ob= ptr->data; + + if(ob->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ + AxisAngleToEulO(&ob->quat[1], ob->quat[0], value, EULER_ORDER_DEFAULT); + else if(ob->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ + QuatToEul(ob->quat, value); + else + VECCOPY(value, ob->rot); +} + +/* rotation - euler angles */ +static void rna_Object_rotation_euler_set(PointerRNA *ptr, const float *value) +{ + Object *ob= ptr->data; + + if(ob->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ + EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, &ob->quat[1], &ob->quat[0]); + else if(ob->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ + EulToQuat((float*)value, ob->quat); + else + VECCOPY(ob->rot, value); +} + +static void rna_Object_rotation_mode_set(PointerRNA *ptr, int value) +{ + Object *ob= ptr->data; + + /* use API Method for conversions... */ + BKE_rotMode_change_values(ob->quat, ob->rot, ob->rotmode, (short)value); + + /* finally, set the new rotation type */ + ob->rotmode= value; +} + static PointerRNA rna_MaterialSlot_material_get(PointerRNA *ptr) { Object *ob= (Object*)ptr->id.data; @@ -1051,6 +1091,18 @@ static void rna_def_object(BlenderRNA *brna) {OB_DUPLIFACES, "FACES", 0, "Faces", "Duplicate child objects on all faces."}, {OB_DUPLIGROUP, "GROUP", 0, "Group", "Enable group instancing."}, {0, NULL, 0, NULL, NULL}}; + + // XXX: this RNA enum define is currently duplicated for objects, since there is some text here which is not applicable + static EnumPropertyItem prop_rotmode_items[] = { + {ROT_MODE_QUAT, "QUATERNION", 0, "Quaternion (WXYZ)", "No Gimbal Lock."}, + {ROT_MODE_XYZ, "XYZ", 0, "XYZ Euler", "XYZ Rotation Order. Prone to Gimbal Lock. (Default)"}, + {ROT_MODE_XZY, "XZY", 0, "XZY Euler", "XZY Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_YXZ, "YXZ", 0, "YXZ Euler", "YXZ Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."}, + {0, NULL, 0, NULL, NULL}}; int matrix_dimsize[]= {4, 4}; @@ -1167,37 +1219,72 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, NULL); /* transform */ - prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "loc"); RNA_def_property_ui_text(prop, "Location", "Location of the object."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); - - prop= RNA_def_property(srna, "delta_location", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_float_sdna(prop, NULL, "dloc"); - RNA_def_property_ui_text(prop, "Delta Location", "Extra added translation to object location."); + + prop= RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION); + RNA_def_property_float_sdna(prop, NULL, "quat"); + RNA_def_property_ui_text(prop, "Quaternion Rotation", "Rotation in Quaternions."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + + /* XXX: for axis-angle, it would have been nice to have 2 separate fields for UI purposes, but + * having a single one is better for Keyframing and other property-management situations... + */ + prop= RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE); + RNA_def_property_float_sdna(prop, NULL, "quat"); + // TODO: we may need some validation funcs + RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); - prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER); + prop= RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rot"); - RNA_def_property_ui_text(prop, "Rotation", "Rotation of the object."); + RNA_def_property_float_funcs(prop, "rna_Object_rotation_euler_get", "rna_Object_rotation_euler_set", NULL); + RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); - - prop= RNA_def_property(srna, "delta_rotation", PROP_FLOAT, PROP_EULER); - RNA_def_property_float_sdna(prop, NULL, "drot"); - RNA_def_property_ui_text(prop, "Delta Rotation", "Extra added rotation to the rotation of the object."); + + prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "rotmode"); + RNA_def_property_enum_items(prop, prop_rotmode_items); // XXX move to using a single define of this someday + RNA_def_property_enum_funcs(prop, NULL, "rna_Object_rotation_mode_set", NULL); + RNA_def_property_ui_text(prop, "Rotation Mode", ""); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_ui_text(prop, "Scale", "Scaling of the object."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); - + + /* delta transforms */ + prop= RNA_def_property(srna, "delta_location", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_float_sdna(prop, NULL, "dloc"); + RNA_def_property_ui_text(prop, "Delta Location", "Extra added translation to object location."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + + prop= RNA_def_property(srna, "delta_rotation_euler", PROP_FLOAT, PROP_EULER); + RNA_def_property_float_sdna(prop, NULL, "drot"); + RNA_def_property_ui_text(prop, "Delta Rotation (Euler)", "Extra added rotation to the rotation of the object (when using Euler rotations)."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + + prop= RNA_def_property(srna, "delta_rotation_quaternion", PROP_FLOAT, PROP_QUATERNION); + RNA_def_property_float_sdna(prop, NULL, "dquat"); + RNA_def_property_ui_text(prop, "Delta Rotation (Quaternion)", "Extra added rotation to the rotation of the object (when using Quaternion rotations)."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + +#if 0 // XXX not supported well yet... + prop= RNA_def_property(srna, "delta_rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE); + RNA_def_property_float_sdna(prop, NULL, "dquat"); + RNA_def_property_ui_text(prop, "Delta Rotation (Axis Angle)", "Extra added rotation to the rotation of the object (when using Axis-Angle rotations)."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); +#endif + prop= RNA_def_property(srna, "delta_scale", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "dsize"); RNA_def_property_ui_text(prop, "Delta Scale", "Extra added scaling to the scale of the object."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); - + + /* transform locks */ prop= RNA_def_property(srna, "lock_location", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_LOCX); RNA_def_property_array(prop, 3); @@ -1207,6 +1294,14 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTX); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation in the interface."); + // XXX this is sub-optimal - it really should be included above, but due to technical reasons we can't do this! + prop= RNA_def_property(srna, "lock_rotation_w", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTW); + RNA_def_property_ui_text(prop, "Lock Rotation (4D Angle)", "Lock editing of 'angle' component of four-component rotations in the interface."); + // XXX this needs a better name + prop= RNA_def_property(srna, "lock_rotations_4d", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROT4D); + RNA_def_property_ui_text(prop, "Lock Rotations (4D)", "Lock editing of four component rotations by components (instead of as Eulers)."); prop= RNA_def_property(srna, "lock_scale", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_SCALEX); @@ -1230,7 +1325,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting the geometric data of the Object."); /* game engine */ - prop= RNA_def_property(srna, "game", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "GameObjectSettings"); @@ -1238,7 +1332,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Game Settings", "Game engine related settings for the object."); /* vertex groups */ - prop= RNA_def_property(srna, "vertex_groups", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "defbase", NULL); RNA_def_property_struct_type(prop, "VertexGroup"); @@ -1257,7 +1350,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Object_update_data"); /* empty */ - prop= RNA_def_property(srna, "empty_draw_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype"); RNA_def_property_enum_items(prop, empty_drawtype_items); @@ -1271,7 +1363,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); /* render */ - prop= RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "index"); RNA_def_property_ui_text(prop, "Pass Index", "Index # for the IndexOB render pass."); @@ -1282,7 +1373,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); /* physics */ - prop= RNA_def_property(srna, "field", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "pd"); RNA_def_property_struct_type(prop, "FieldSettings"); @@ -1316,7 +1406,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); /* restrict */ - prop= RNA_def_property(srna, "restrict_view", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_VIEW); RNA_def_property_ui_text(prop, "Restrict View", "Restrict visibility in the viewport."); @@ -1333,20 +1422,9 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); /* anim */ - rna_def_animdata_common(srna); - prop= RNA_def_property(srna, "draw_keys", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_DRAWKEY); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); // update ipo flag indirect - RNA_def_property_ui_text(prop, "Draw Keys", "Draw object as key positions."); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); - - prop= RNA_def_property(srna, "draw_keys_selected", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_DRAWKEYSEL); - RNA_def_property_ui_text(prop, "Draw Keys Selected", "Limit the drawing of object keys to selected."); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); - + /* duplicates */ prop= RNA_def_property(srna, "track_override_parent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_POWERTRACK); RNA_def_property_ui_text(prop, "Track Override Parent", "Override rotation from parenting."); @@ -1420,7 +1498,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Dupli list", "Object duplis."); /* time offset */ - prop= RNA_def_property(srna, "time_offset", PROP_FLOAT, PROP_NONE|PROP_UNIT_TIME); RNA_def_property_float_sdna(prop, NULL, "sf"); RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); @@ -1447,7 +1524,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); /* drawing */ - prop= RNA_def_property(srna, "max_draw_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "dt"); RNA_def_property_enum_items(prop, drawtype_items); @@ -1514,7 +1590,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Pose", "Current pose for armatures."); /* shape keys */ - prop= RNA_def_property(srna, "shape_key_lock", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shapeflag", OB_SHAPE_LOCK); RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_shape_key_lock_set"); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index e76cd56af4e..a1f4005df46 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -156,105 +156,37 @@ static void rna_Pose_ik_solver_update(bContext *C, PointerRNA *ptr) } /* rotation - euler angles */ -static void rna_PoseChannel_euler_rotation_get(PointerRNA *ptr, float *value) +static void rna_PoseChannel_rotation_euler_get(PointerRNA *ptr, float *value) { bPoseChannel *pchan= ptr->data; - if(pchan->rotmode == PCHAN_ROT_AXISANGLE) /* default XYZ eulers */ + if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], value, EULER_ORDER_DEFAULT); - else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers */ + else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ QuatToEul(pchan->quat, value); else VECCOPY(value, pchan->eul); } /* rotation - euler angles */ -static void rna_PoseChannel_euler_rotation_set(PointerRNA *ptr, const float *value) +static void rna_PoseChannel_rotation_euler_set(PointerRNA *ptr, const float *value) { bPoseChannel *pchan= ptr->data; - if(pchan->rotmode == PCHAN_ROT_AXISANGLE) /* default XYZ eulers */ + if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]); - else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers */ + else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ EulToQuat((float*)value, pchan->quat); else VECCOPY(pchan->eul, value); } -/* rotation - axis angle only */ -static void rna_PoseChannel_rotation_axis_get(PointerRNA *ptr, float *value) -{ - bPoseChannel *pchan= ptr->data; - - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { - /* axis is stord in quat for now */ - VecCopyf(value, &pchan->quat[1]); - } -} - -/* rotation - axis angle only */ -static void rna_PoseChannel_rotation_axis_set(PointerRNA *ptr, const float *value) -{ - bPoseChannel *pchan= ptr->data; - - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { - /* axis is stored in quat for now */ - VecCopyf(&pchan->quat[1], (float *)value); - } -} - static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) { bPoseChannel *pchan= ptr->data; - /* check if any change - if so, need to convert data */ - // TODO: this needs to be generalised at some point to work for objects too... - if (value > 0) { /* to euler */ - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { - /* axis-angle to euler */ - AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], pchan->eul, value); - } - else if (pchan->rotmode == PCHAN_ROT_QUAT) { - /* quat to euler */ - QuatToEulO(pchan->quat, pchan->eul, value); - } - /* else { no conversion needed } */ - } - else if (value == PCHAN_ROT_QUAT) { /* to quat */ - if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { - /* axis angle to quat */ - float q[4]; - - /* copy to temp var first, since quats and axis-angle are stored in same place */ - QuatCopy(q, pchan->quat); - AxisAngleToQuat(q, &pchan->quat[1], pchan->quat[0]); - } - else if (pchan->rotmode > 0) { - /* euler to quat */ - EulOToQuat(pchan->eul, pchan->rotmode, pchan->quat); - } - /* else { no conversion needed } */ - } - else { /* to axis-angle */ - if (pchan->rotmode > 0) { - /* euler to axis angle */ - EulOToAxisAngle(pchan->eul, pchan->rotmode, &pchan->quat[1], &pchan->quat[0]); - } - else if (pchan->rotmode == PCHAN_ROT_QUAT) { - /* quat to axis angle */ - float q[4]; - - /* copy to temp var first, since quats and axis-angle are stored in same place */ - QuatCopy(q, pchan->quat); - QuatToAxisAngle(q, &pchan->quat[1], &pchan->quat[0]); - } - - /* when converting to axis-angle, we need a special exception for the case when there is no axis */ - if (IS_EQ(pchan->quat[1], pchan->quat[2]) && IS_EQ(pchan->quat[2], pchan->quat[3])) { - /* for now, rotate around y-axis then (so that it simply becomes the roll) */ - pchan->quat[2]= 1.0f; - } - } + /* use API Method for conversions... */ + BKE_rotMode_change_values(pchan->quat, pchan->eul, pchan->rotmode, (short)value); /* finally, set the new rotation type */ pchan->rotmode= value; @@ -559,15 +491,16 @@ static EnumPropertyItem prop_solver_items[] = { static void rna_def_pose_channel(BlenderRNA *brna) { + // XXX: this RNA enum define is currently duplicated for objects, since there is some text here which is not applicable static EnumPropertyItem prop_rotmode_items[] = { - {PCHAN_ROT_QUAT, "QUATERNION", 0, "Quaternion (WXYZ)", "No Gimbal Lock (default)"}, - {PCHAN_ROT_XYZ, "XYZ", 0, "XYZ Euler", "XYZ Rotation Order. Prone to Gimbal Lock"}, - {PCHAN_ROT_XZY, "XZY", 0, "XZY Euler", "XZY Rotation Order. Prone to Gimbal Lock"}, - {PCHAN_ROT_YXZ, "YXZ", 0, "YXZ Euler", "YXZ Rotation Order. Prone to Gimbal Lock"}, - {PCHAN_ROT_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"}, - {PCHAN_ROT_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"}, - {PCHAN_ROT_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"}, - {PCHAN_ROT_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."}, + {ROT_MODE_QUAT, "QUATERNION", 0, "Quaternion (WXYZ)", "No Gimbal Lock (default)"}, + {ROT_MODE_XYZ, "XYZ", 0, "XYZ Euler", "XYZ Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_XZY, "XZY", 0, "XZY Euler", "XZY Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_YXZ, "YXZ", 0, "YXZ Euler", "YXZ Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"}, + {ROT_MODE_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."}, {0, NULL, 0, NULL, NULL}}; StructRNA *srna; @@ -635,32 +568,29 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Scale", ""); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); - prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_QUATERNION); + prop= RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION); RNA_def_property_float_sdna(prop, NULL, "quat"); - RNA_def_property_ui_text(prop, "Rotation", "Rotation in Quaternions."); + RNA_def_property_ui_text(prop, "Quaternion Rotation", "Rotation in Quaternions."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); - prop= RNA_def_property(srna, "rotation_angle", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "quat[0]"); - RNA_def_property_ui_text(prop, "Rotation Angle", "Angle of Rotation for Axis-Angle rotation representation."); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); - - prop= RNA_def_property(srna, "rotation_axis", PROP_FLOAT, PROP_XYZ); + /* XXX: for axis-angle, it would have been nice to have 2 separate fields for UI purposes, but + * having a single one is better for Keyframing and other property-management situations... + */ + prop= RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE); RNA_def_property_float_sdna(prop, NULL, "quat"); - RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_axis_get", "rna_PoseChannel_rotation_axis_set", NULL); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Rotation Axis", "Axis for Axis-Angle rotation representation."); + // TODO: we may need some validation funcs + RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); - prop= RNA_def_property(srna, "euler_rotation", PROP_FLOAT, PROP_EULER); + prop= RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "eul"); - RNA_def_property_float_funcs(prop, "rna_PoseChannel_euler_rotation_get", "rna_PoseChannel_euler_rotation_set", NULL); - RNA_def_property_ui_text(prop, "Rotation (Euler)", "Rotation in Eulers."); + RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_euler_get", "rna_PoseChannel_rotation_euler_set", NULL); + RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "rotmode"); - RNA_def_property_enum_items(prop, prop_rotmode_items); + RNA_def_property_enum_items(prop, prop_rotmode_items); // XXX move to using a single define of this someday RNA_def_property_enum_funcs(prop, NULL, "rna_PoseChannel_rotation_mode_set", NULL); RNA_def_property_ui_text(prop, "Rotation Mode", ""); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); |