Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/intern/action.c10
-rw-r--r--source/blender/blenkernel/intern/armature.c28
-rw-r--r--source/blender/blenkernel/intern/object.c8
-rw-r--r--source/blender/editors/animation/keyframes_general.c1
-rw-r--r--source/blender/editors/armature/editarmature.c49
-rw-r--r--source/blender/editors/armature/poseobject.c14
-rw-r--r--source/blender/editors/object/object_transform.c50
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c4
-rw-r--r--source/blender/editors/transform/transform_conversions.c4
-rw-r--r--source/blender/makesdna/DNA_action_types.h11
-rw-r--r--source/blender/makesdna/DNA_object_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_object.c30
-rw-r--r--source/blender/makesrna/intern/rna_pose.c32
14 files changed, 172 insertions, 77 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index e5d0c4274b3..8f109034e3e 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -104,7 +104,7 @@ void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *
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);
+void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode);
/* B-Bone support */
typedef struct Mat4 {
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 7be763eae9d..25f539a1992 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -446,7 +446,7 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
strncpy(chan->name, name, 31);
/* init vars to prevent math errors */
- chan->quat[0] = 1.0f;
+ chan->quat[0] = chan->rotAxis[1]= 1.0f;
chan->size[0] = chan->size[1] = chan->size[2] = 1.0f;
chan->limitmin[0]= chan->limitmin[1]= chan->limitmin[2]= -180.0f;
@@ -607,6 +607,8 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
VECCOPY(pchan->loc, chan->loc);
VECCOPY(pchan->size, chan->size);
VECCOPY(pchan->eul, chan->eul);
+ VECCOPY(pchan->rotAxis, chan->rotAxis);
+ pchan->rotAngle= chan->rotAngle;
QUATCOPY(pchan->quat, chan->quat);
pchan->rotmode= chan->rotmode;
Mat4CpyMat4(pchan->chan_mat, (float(*)[4])chan->chan_mat);
@@ -975,14 +977,16 @@ void rest_pose(bPose *pose)
memset(pose->stride_offset, 0, sizeof(pose->stride_offset));
memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
- for (pchan=pose->chanbase.first; pchan; pchan= pchan->next){
+ for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) {
for (i=0; i<3; i++) {
pchan->loc[i]= 0.0f;
pchan->quat[i+1]= 0.0f;
pchan->eul[i]= 0.0f;
pchan->size[i]= 1.0f;
+ pchan->rotAxis[i]= 0.0f;
}
- pchan->quat[0]= 1.0f;
+ pchan->quat[0]= pchan->rotAxis[1]= 1.0f;
+ pchan->rotAngle= 0.0f;
pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 6220835a620..a0abe780273 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1285,16 +1285,14 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float
/* 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)
+void BKE_rotMode_change_values (float quat[4], float eul[3], float *axis, float angle[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);
+ AxisAngleToEulO(axis, *angle, eul, newMode);
}
else if (oldMode == ROT_MODE_QUAT) {
/* quat to euler */
@@ -1305,11 +1303,7 @@ void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, shor
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]);
+ AxisAngleToQuat(quat, axis, *angle);
}
else if (oldMode > 0) {
/* euler to quat */
@@ -1317,24 +1311,20 @@ void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, shor
}
/* else { no conversion needed } */
}
- else { /* to axis-angle */
+ else if (newMode == ROT_MODE_AXISANGLE) { /* 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]);
+ QuatToAxisAngle(quat, axis, angle);
}
/* 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])) {
+ if (IS_EQ(axis[0], axis[1]) && IS_EQ(axis[1], axis[2])) {
/* for now, rotate around y-axis then (so that it simply becomes the roll) */
- quat[2]= 1.0f;
+ axis[1]= 1.0f;
}
}
}
@@ -1651,8 +1641,8 @@ void chan_calc_mat(bPoseChannel *chan)
EulOToMat3(chan->eul, chan->rotmode, rmat);
}
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);
+ /* axis-angle - not really that great for 3D-changing orientations */
+ AxisAngleToMat3(chan->rotAxis, chan->rotAngle, rmat);
}
else {
/* quats are normalised before use to eliminate scaling issues */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index ddf7e7ff4a3..89757533fb8 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1041,6 +1041,8 @@ Object *add_object(struct Scene *scene, int type)
* but rotations default to quaternions
*/
ob->rotmode= ROT_MODE_EUL;
+ /* axis-angle must not have a 0,0,0 axis, so set y-axis as default... */
+ ob->rotAxis[1]= ob->drotAxis[1]= 1.0f;
base= scene_add_base(scene, ob);
scene_select_base(scene, base);
@@ -1602,9 +1604,9 @@ void object_rot_to_mat3(Object *ob, float mat[][3])
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);
+ /* axis-angle - not really that great for 3D-changing orientations */
+ AxisAngleToMat3(ob->rotAxis, ob->rotAngle, rmat);
+ AxisAngleToMat3(ob->drotAxis, ob->drotAngle, dmat);
}
else {
/* quats are normalised before use to eliminate scaling issues */
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index f13d35c7d4a..3ad6ddf2c6f 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -581,6 +581,7 @@ short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data)
for (aci= animcopybuf.first; aci; aci= aci->next) {
/* check that paths exist */
if (aci->rna_path && fcu->rna_path) {
+ // FIXME: this breaks for bone names!
if (strcmp(aci->rna_path, fcu->rna_path) == 0) {
/* should be a match unless there's more than one of these */
if ((no_name) || (aci->array_index == fcu->array_index))
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index c32837be420..0343fea5bfb 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -4875,14 +4875,39 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
/* check if convert to eulers for locking... */
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 == 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)
- pchan->quat[2]= 0.0f;
- if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
- pchan->quat[3]= 0.0f;
+ if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+ if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
+ pchan->rotAngle= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
+ pchan->rotAxis[0]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
+ pchan->rotAxis[1]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
+ pchan->rotAxis[2]= 0.0f;
+
+ /* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
+ if (IS_EQ(pchan->rotAxis[0], pchan->rotAxis[1]) && IS_EQ(pchan->rotAxis[1], pchan->rotAxis[2]))
+ pchan->rotAxis[1] = 1.0f;
+ }
+ else if (pchan->rotmode == ROT_MODE_QUAT) {
+ if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
+ pchan->quat[0]= 1.0f;
+ if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
+ pchan->quat[1]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
+ pchan->quat[2]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
+ pchan->quat[3]= 0.0f;
+ }
+ else {
+ /* the flag may have been set for the other modes, so just ignore the extra flag... */
+ if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
+ pchan->eul[0]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
+ pchan->eul[1]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
+ pchan->eul[2]= 0.0f;
+ }
}
else {
/* perform clamping using euler form (3-components) */
@@ -4893,7 +4918,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
QuatToEul(pchan->quat, oldeul);
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
- AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT);
+ AxisAngleToEulO(pchan->rotAxis, pchan->rotAngle, oldeul, EULER_ORDER_DEFAULT);
}
else {
VECCOPY(oldeul, pchan->eul);
@@ -4916,7 +4941,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
}
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
- AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT);
+ EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, &pchan->rotAngle);
}
else {
VECCOPY(pchan->eul, eul);
@@ -4930,8 +4955,8 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
}
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;
+ pchan->rotAxis[0]=pchan->rotAxis[2]=pchan->rotAngle= 0.0f;
+ pchan->rotAxis[1]= 1.0f;
}
else {
pchan->eul[0]= pchan->eul[1]= pchan->eul[2]= 0.0f;
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index edbc7b9ae9b..461a70bbf86 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -819,7 +819,7 @@ void pose_copy_menu(Scene *scene)
/* need to convert to quat first (in temp var)... */
Mat4ToQuat(delta_mat, tmp_quat);
- QuatToAxisAngle(tmp_quat, &pchan->quat[1], &pchan->quat[0]);
+ QuatToAxisAngle(tmp_quat, pchan->rotAxis, &pchan->rotAngle);
}
else if (pchan->rotmode == ROT_MODE_QUAT)
Mat4ToQuat(delta_mat, pchan->quat);
@@ -1024,23 +1024,23 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
else if (pchan->rotmode > 0) {
/* quat/axis-angle to euler */
if (chan->rotmode == ROT_MODE_AXISANGLE)
- AxisAngleToEulO(&chan->quat[1], chan->quat[0], pchan->eul, pchan->rotmode);
+ AxisAngleToEulO(chan->rotAxis, chan->rotAngle, pchan->eul, pchan->rotmode);
else
QuatToEulO(chan->quat, pchan->eul, pchan->rotmode);
}
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]);
+ EulOToAxisAngle(chan->eul, chan->rotmode, pchan->rotAxis, &pchan->rotAngle);
else
- QuatToAxisAngle(chan->quat, &pchan->quat[1], &pchan->quat[0]);
+ QuatToAxisAngle(chan->quat, pchan->rotAxis, &pchan->rotAngle);
}
else {
/* euler/axis-angle to quat */
if (chan->rotmode > 0)
EulOToQuat(chan->eul, chan->rotmode, pchan->quat);
else
- AxisAngleToQuat(pchan->quat, &chan->quat[1], chan->quat[0]);
+ AxisAngleToQuat(pchan->quat, chan->rotAxis, pchan->rotAngle);
}
/* paste flipped pose? */
@@ -1055,10 +1055,10 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float eul[3];
- AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], eul, EULER_ORDER_DEFAULT);
+ AxisAngleToEulO(pchan->rotAxis, pchan->rotAngle, eul, EULER_ORDER_DEFAULT);
eul[1]*= -1;
eul[2]*= -1;
- EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]);
+ EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, &pchan->rotAngle);
// experimental method (uncomment to test):
#if 0
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index cd0d97eed44..898d541d09d 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -117,17 +117,41 @@ 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)) {
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;
+ if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ if ((ob->protectflag & OB_LOCK_ROTW) == 0)
+ ob->rotAngle= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTX) == 0)
+ ob->rotAxis[0]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTY) == 0)
+ ob->rotAxis[1]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTZ) == 0)
+ ob->rotAxis[2]= 0.0f;
+
+ /* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
+ if (IS_EQ(ob->rotAxis[0], ob->rotAxis[1]) && IS_EQ(ob->rotAxis[1], ob->rotAxis[2]))
+ ob->rotAxis[1] = 1.0f;
+ }
+ else if (ob->rotmode == ROT_MODE_QUAT) {
+ if ((ob->protectflag & OB_LOCK_ROTW) == 0)
+ ob->quat[0]= 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 {
+ /* the flag may have been set for the other modes, so just ignore the extra flag... */
+ if ((ob->protectflag & OB_LOCK_ROTX) == 0)
+ ob->rot[0]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTY) == 0)
+ ob->rot[1]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTZ) == 0)
+ ob->rot[2]= 0.0f;
+ }
}
else {
/* perform clamping using euler form (3-components) */
@@ -138,7 +162,7 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op)
QuatToEul(ob->quat, oldeul);
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
- AxisAngleToEulO(&ob->quat[1], ob->quat[0], oldeul, EULER_ORDER_DEFAULT);
+ AxisAngleToEulO(ob->rotAxis, ob->rotAngle, oldeul, EULER_ORDER_DEFAULT);
}
else {
VECCOPY(oldeul, ob->rot);
@@ -161,7 +185,7 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op)
}
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
- AxisAngleToEulO(&ob->quat[1], ob->quat[0], oldeul, EULER_ORDER_DEFAULT);
+ EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, ob->rotAxis, &ob->rotAngle);
}
else {
VECCOPY(ob->rot, eul);
@@ -175,8 +199,8 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op)
}
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;
+ ob->rotAxis[0]=ob->rotAxis[2]=ob->rotAngle= 0.0f;
+ ob->rotAxis[1]= 1.0f;
}
else {
ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0f;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index ec72d72013b..c2f5d736875 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -689,6 +689,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
case B_OBJECTPANELROT:
if(ob) {
+ // TODO: need to support roation modes
ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0;
ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0;
ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0;
@@ -870,13 +871,12 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
float quat[4];
/* convert to axis-angle, passing through quats */
EulToQuat(eul, quat);
- QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]);
+ QuatToAxisAngle(quat, pchan->rotAxis, &pchan->rotAngle);
}
else if (pchan->rotmode == ROT_MODE_QUAT)
EulToQuat(eul, pchan->quat);
else
VecCopyf(pchan->eul, eul);
-
}
/* no break, pass on */
case B_ARMATUREPANEL2:
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index f6d30a7bec9..1b11d43c200 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -509,7 +509,7 @@ static short apply_targetless_ik(Object *ob)
if (parchan->rotmode > 0)
Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode);
else if (parchan->rotmode == ROT_MODE_AXISANGLE)
- Mat3ToAxisAngle(rmat3, &parchan->quat[1], &parchan->quat[0]);
+ Mat3ToAxisAngle(rmat3, parchan->rotAxis, &pchan->rotAngle);
else
Mat3ToQuat(rmat3, parchan->quat);
@@ -519,7 +519,7 @@ static short apply_targetless_ik(Object *ob)
if (parchan->rotmode > 0)
EulOToMat3(parchan->eul, parchan->rotmode, qrmat);
else if (parchan->rotmode == ROT_MODE_AXISANGLE)
- AxisAngleToMat3(&parchan->quat[1], parchan->quat[0], qrmat);
+ AxisAngleToMat3(parchan->rotAxis, parchan->rotAngle, qrmat);
else
QuatToMat3(parchan->quat, qrmat);
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 3201a1df6a5..e2eb13f0bdf 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -128,12 +128,15 @@ typedef struct bPoseChannel {
void *dual_quat;
void *b_bone_dual_quats;
- float loc[3]; /* transforms - written in by actions or transform */
+ /* transforms - written in by actions or transform */
+ float loc[3];
float size[3];
- float eul[3]; /* rotations - written in by actions or transform (but only euler/quat in use at any one time!) */
- float quat[4];
- short rotmode; /* for now either quat (0), or xyz-euler (1) */
+ /* rotations - written in by actions or transform (but only one representation gets used at any time) */
+ float eul[3]; /* euler rotation */
+ float quat[4]; /* quaternion rotation */
+ float rotAxis[3], rotAngle; /* axis-angle rotation */
+ short rotmode; /* eRotationModes - rotation representation to use */
short pad;
float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index ade22e4ebd4..0940a88267c 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -133,8 +133,10 @@ typedef struct Object {
/* rot en drot have to be together! (transform('r' en 's')) */
float loc[3], dloc[3], orig[3];
float size[3], dsize[3];
- float rot[3], drot[3];
- float quat[4], dquat[4];
+ float rot[3], drot[3]; /* euler rotation */
+ float quat[4], dquat[4]; /* quaternion rotation */
+ float rotAxis[3], drotAxis[3]; /* axis angle rotation - axis part */
+ float rotAngle, drotAngle; /* axis angle rotation - angle part */
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 */
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 4fb2db42b8b..3184ebc6db2 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -484,12 +484,34 @@ static void rna_Object_rotation_euler_set(PointerRNA *ptr, const float *value)
VECCOPY(ob->rot, value);
}
+/* rotation - axis-angle */
+static void rna_Object_rotation_axis_angle_get(PointerRNA *ptr, float *value)
+{
+ Object *ob= ptr->data;
+
+ /* for now, assume that rotation mode is axis-angle */
+ value[0]= ob->rotAngle;
+ VecCopyf(&value[1], ob->rotAxis);
+}
+
+/* rotation - axis-angle */
+static void rna_Object_rotation_axis_angle_set(PointerRNA *ptr, const float *value)
+{
+ Object *ob= ptr->data;
+
+ /* for now, assume that rotation mode is axis-angle */
+ ob->rotAngle= value[0];
+ VecCopyf(ob->rotAxis, (float *)&value[1]);
+
+ // TODO: validate axis?
+}
+
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);
+ BKE_rotMode_change_values(ob->quat, ob->rot, ob->rotAxis, &ob->rotAngle, ob->rotmode, (short)value);
/* finally, set the new rotation type */
ob->rotmode= value;
@@ -1242,8 +1264,8 @@ static void rna_def_object(BlenderRNA *brna)
* 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_array(prop, 4); // TODO: maybe we'll need to define the 'default value' getter too...
+ RNA_def_property_float_funcs(prop, "rna_Object_rotation_axis_angle_get", "rna_Object_rotation_axis_angle_set", NULL);
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");
@@ -1283,7 +1305,7 @@ static void rna_def_object(BlenderRNA *brna)
#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_float_sdna(prop, NULL, "dquat"); // FIXME: this is not a single field any more! (drotAxis and drotAngle)
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
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index ecb2dba0197..27069b361fd 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -162,7 +162,7 @@ static void rna_PoseChannel_rotation_euler_get(PointerRNA *ptr, float *value)
bPoseChannel *pchan= ptr->data;
if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */
- AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], value, EULER_ORDER_DEFAULT);
+ AxisAngleToEulO(pchan->rotAxis, pchan->rotAngle, value, EULER_ORDER_DEFAULT);
else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */
QuatToEul(pchan->quat, value);
else
@@ -175,19 +175,41 @@ static void rna_PoseChannel_rotation_euler_set(PointerRNA *ptr, const float *val
bPoseChannel *pchan= ptr->data;
if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */
- EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]);
+ EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, pchan->rotAxis, &pchan->rotAngle);
else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */
EulToQuat((float*)value, pchan->quat);
else
VECCOPY(pchan->eul, value);
}
+/* rotation - axis-angle */
+static void rna_PoseChannel_rotation_axis_angle_get(PointerRNA *ptr, float *value)
+{
+ bPoseChannel *pchan= ptr->data;
+
+ /* for now, assume that rotation mode is axis-angle */
+ value[0]= pchan->rotAngle;
+ VecCopyf(&value[1], pchan->rotAxis);
+}
+
+/* rotation - axis-angle */
+static void rna_PoseChannel_rotation_axis_angle_set(PointerRNA *ptr, const float *value)
+{
+ bPoseChannel *pchan= ptr->data;
+
+ /* for now, assume that rotation mode is axis-angle */
+ pchan->rotAngle= value[0];
+ VecCopyf(pchan->rotAxis, (float *)&value[1]);
+
+ // TODO: validate axis?
+}
+
static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value)
{
bPoseChannel *pchan= ptr->data;
/* use API Method for conversions... */
- BKE_rotMode_change_values(pchan->quat, pchan->eul, pchan->rotmode, (short)value);
+ BKE_rotMode_change_values(pchan->quat, pchan->eul, pchan->rotAxis, &pchan->rotAngle, pchan->rotmode, (short)value);
/* finally, set the new rotation type */
pchan->rotmode= value;
@@ -578,8 +600,8 @@ static void rna_def_pose_channel(BlenderRNA *brna)
* 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_array(prop, 4); // TODO: maybe we'll need to define the 'default value' getter too...
+ RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_axis_angle_get", "rna_PoseChannel_rotation_axis_angle_set", NULL);
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");