forked from bartvdbraak/blender
Transform Orientations
Edit Bone and Pose Bone can now be used as transform orientations Also fix a bug with CTO comming from non-uniformally scaled meshes.
This commit is contained in:
parent
fe7b591280
commit
8e46d777f3
@ -515,6 +515,7 @@ int handleNDofInput(NDofInput *n, unsigned short event, short val);
|
|||||||
|
|
||||||
int manageObjectSpace(int confirm, int set);
|
int manageObjectSpace(int confirm, int set);
|
||||||
int manageMeshSpace(int confirm, int set);
|
int manageMeshSpace(int confirm, int set);
|
||||||
|
int manageBoneSpace(int confirm, int set);
|
||||||
|
|
||||||
/* Those two fill in mat and return non-zero on success */
|
/* Those two fill in mat and return non-zero on success */
|
||||||
int createSpaceNormal(float mat[3][3], float normal[3]);
|
int createSpaceNormal(float mat[3][3], float normal[3]);
|
||||||
|
@ -158,7 +158,7 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* for pose mode */
|
/* for pose mode */
|
||||||
static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *plane)
|
static void stats_pose(View3D *v3d, bPoseChannel *pchan)
|
||||||
{
|
{
|
||||||
Bone *bone= pchan->bone;
|
Bone *bone= pchan->bone;
|
||||||
|
|
||||||
@ -166,9 +166,6 @@ static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *p
|
|||||||
if (bone->flag & BONE_TRANSFORM) {
|
if (bone->flag & BONE_TRANSFORM) {
|
||||||
calc_tw_center(pchan->pose_head);
|
calc_tw_center(pchan->pose_head);
|
||||||
protectflag_to_drawflags(pchan->protectflag, &v3d->twdrawflag);
|
protectflag_to_drawflags(pchan->protectflag, &v3d->twdrawflag);
|
||||||
|
|
||||||
VecAddf(normal, normal, pchan->pose_mat[2]);
|
|
||||||
VecAddf(plane, plane, pchan->pose_mat[1]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,26 +346,24 @@ int calc_manipulator_stats(ScrArea *sa)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ob && (ob->flag & OB_POSEMODE)) {
|
else if(ob && (ob->flag & OB_POSEMODE)) {
|
||||||
bArmature *arm= ob->data;
|
bArmature *arm = ob->data;
|
||||||
bPoseChannel *pchan;
|
bPoseChannel *pchan;
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
if((ob->lay & G.vd->lay)==0) return 0;
|
if((ob->lay & G.vd->lay)==0) return 0;
|
||||||
|
|
||||||
mode= Trans.mode;
|
mode = Trans.mode;
|
||||||
Trans.mode= TFM_ROTATION; // mislead counting bones... bah
|
Trans.mode = TFM_ROTATION; // mislead counting bones... bah
|
||||||
|
|
||||||
/* count total, we use same method as transform will do */
|
/* count total, we use same method as transform will do */
|
||||||
Trans.total= 0;
|
Trans.total= 0;
|
||||||
count_bone_select(&Trans, arm, &arm->bonebase, 1);
|
count_bone_select(&Trans, arm, &arm->bonebase, 1);
|
||||||
totsel= Trans.total;
|
totsel = Trans.total;
|
||||||
if(totsel) {
|
if(totsel) {
|
||||||
/* use channels to get stats */
|
/* use channels to get stats */
|
||||||
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||||
stats_pose(v3d, pchan, normal, plane);
|
stats_pose(v3d, pchan);
|
||||||
}
|
}
|
||||||
//VecMulf(normal, -1.0);
|
|
||||||
VecMulf(plane, -1.0);
|
|
||||||
|
|
||||||
VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid!
|
VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid!
|
||||||
Mat4MulVecfl(ob->obmat, G.scene->twcent);
|
Mat4MulVecfl(ob->obmat, G.scene->twcent);
|
||||||
@ -376,7 +371,7 @@ int calc_manipulator_stats(ScrArea *sa)
|
|||||||
Mat4MulVecfl(ob->obmat, G.scene->twmax);
|
Mat4MulVecfl(ob->obmat, G.scene->twmax);
|
||||||
}
|
}
|
||||||
/* restore, mode can be TFM_INIT */
|
/* restore, mode can be TFM_INIT */
|
||||||
Trans.mode= mode;
|
Trans.mode = mode;
|
||||||
}
|
}
|
||||||
else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) {
|
else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) {
|
||||||
;
|
;
|
||||||
@ -433,7 +428,7 @@ int calc_manipulator_stats(ScrArea *sa)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case V3D_MANIP_NORMAL:
|
case V3D_MANIP_NORMAL:
|
||||||
if(G.obedit) {
|
if(G.obedit || ob->flag & OB_POSEMODE) {
|
||||||
float mat[3][3];
|
float mat[3][3];
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
@ -479,34 +474,6 @@ int calc_manipulator_stats(ScrArea *sa)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* pose mode is a bit weird, so keep it separated */
|
|
||||||
else if (ob->flag & OB_POSEMODE)
|
|
||||||
{
|
|
||||||
strcpy(t->spacename, "normal");
|
|
||||||
if(normal[0]!=0.0 || normal[1]!=0.0 || normal[2]!=0.0) {
|
|
||||||
float imat[3][3], mat[3][3];
|
|
||||||
|
|
||||||
/* we need the transpose of the inverse for a normal... */
|
|
||||||
Mat3CpyMat4(imat, ob->obmat);
|
|
||||||
|
|
||||||
Mat3Inv(mat, imat);
|
|
||||||
Mat3Transp(mat);
|
|
||||||
Mat3MulVecfl(mat, normal);
|
|
||||||
Mat3MulVecfl(mat, plane);
|
|
||||||
|
|
||||||
Normalize(normal);
|
|
||||||
if(0.0==Normalize(plane)) VECCOPY(plane, mat[1]);
|
|
||||||
|
|
||||||
VECCOPY(mat[2], normal);
|
|
||||||
Crossf(mat[0], normal, plane);
|
|
||||||
Crossf(mat[1], mat[2], mat[0]);
|
|
||||||
|
|
||||||
Mat4CpyMat3(v3d->twmat, mat);
|
|
||||||
Mat4Ortho(v3d->twmat);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* no break we define 'normal' as 'local' in Object mode */
|
/* no break we define 'normal' as 'local' in Object mode */
|
||||||
case V3D_MANIP_LOCAL:
|
case V3D_MANIP_LOCAL:
|
||||||
strcpy(t->spacename, "local");
|
strcpy(t->spacename, "local");
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "DNA_armature_types.h"
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_action_types.h"
|
||||||
#include "DNA_curve_types.h"
|
#include "DNA_curve_types.h"
|
||||||
#include "DNA_listBase.h"
|
#include "DNA_listBase.h"
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
@ -68,11 +69,17 @@ void BIF_clearTransformOrientation(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BIF_manageTransformOrientation(int confirm, int set) {
|
void BIF_manageTransformOrientation(int confirm, int set) {
|
||||||
|
Object *ob = OBACT;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
|
|
||||||
if (G.obedit) {
|
if (G.obedit) {
|
||||||
if (G.obedit->type == OB_MESH)
|
if (G.obedit->type == OB_MESH)
|
||||||
index = manageMeshSpace(confirm, set);
|
index = manageMeshSpace(confirm, set);
|
||||||
|
else if (G.obedit->type == OB_ARMATURE)
|
||||||
|
index = manageBoneSpace(confirm, set);
|
||||||
|
}
|
||||||
|
else if (ob && (ob->flag & OB_POSEMODE)) {
|
||||||
|
index = manageBoneSpace(confirm, set);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
index = manageObjectSpace(confirm, set);
|
index = manageObjectSpace(confirm, set);
|
||||||
@ -122,6 +129,31 @@ int confirmSpace(int set, char text[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int manageBoneSpace(int confirm, int set) {
|
||||||
|
float mat[3][3];
|
||||||
|
float normal[3], plane[3];
|
||||||
|
char name[36] = "";
|
||||||
|
int index;
|
||||||
|
|
||||||
|
getTransformOrientation(normal, plane, 0);
|
||||||
|
|
||||||
|
if (confirm == 0 && confirmSpace(set, "Bone") == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
|
||||||
|
error("Cannot use zero-length bone");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(name, "Bone");
|
||||||
|
|
||||||
|
/* Input name */
|
||||||
|
sbutton(name, 1, 35, "name: ");
|
||||||
|
|
||||||
|
index = addMatrixSpace(mat, name);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
int manageMeshSpace(int confirm, int set) {
|
int manageMeshSpace(int confirm, int set) {
|
||||||
float mat[3][3];
|
float mat[3][3];
|
||||||
@ -363,6 +395,29 @@ void applyTransformOrientation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int count_bone_select(bArmature *arm, ListBase *lb, int do_it)
|
||||||
|
{
|
||||||
|
Bone *bone;
|
||||||
|
int do_next;
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
for(bone= lb->first; bone; bone= bone->next) {
|
||||||
|
bone->flag &= ~BONE_TRANSFORM;
|
||||||
|
do_next = do_it;
|
||||||
|
if(do_it) {
|
||||||
|
if(bone->layer & arm->layer) {
|
||||||
|
if (bone->flag & BONE_SELECTED) {
|
||||||
|
bone->flag |= BONE_TRANSFORM;
|
||||||
|
total++;
|
||||||
|
do_next= 0; // no transform on children if one parent bone is selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total += count_bone_select(arm, &bone->childbase, do_next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
|
int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
|
||||||
{
|
{
|
||||||
@ -375,6 +430,14 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
|
|||||||
|
|
||||||
if(G.obedit)
|
if(G.obedit)
|
||||||
{
|
{
|
||||||
|
float imat[3][3], mat[3][3];
|
||||||
|
|
||||||
|
/* we need the transpose of the inverse for a normal... */
|
||||||
|
Mat3CpyMat4(imat, ob->obmat);
|
||||||
|
|
||||||
|
Mat3Inv(mat, imat);
|
||||||
|
Mat3Transp(mat);
|
||||||
|
|
||||||
ob= G.obedit;
|
ob= G.obedit;
|
||||||
|
|
||||||
if(G.obedit->type==OB_MESH)
|
if(G.obedit->type==OB_MESH)
|
||||||
@ -640,11 +703,47 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat4Mul3Vecfl(G.obedit->obmat, plane);
|
/* Vectors from edges don't need the special transpose inverse multiplication */
|
||||||
Mat4Mul3Vecfl(G.obedit->obmat, normal);
|
if (result == ORIENTATION_EDGE)
|
||||||
|
{
|
||||||
|
Mat4Mul3Vecfl(ob->obmat, normal);
|
||||||
|
Mat4Mul3Vecfl(ob->obmat, plane);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Mat3MulVecfl(mat, normal);
|
||||||
|
Mat3MulVecfl(mat, plane);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(ob && (ob->flag & OB_POSEMODE))
|
else if(ob && (ob->flag & OB_POSEMODE))
|
||||||
{
|
{
|
||||||
|
bArmature *arm= ob->data;
|
||||||
|
bPoseChannel *pchan;
|
||||||
|
int totsel;
|
||||||
|
|
||||||
|
totsel = count_bone_select(arm, &arm->bonebase, 1);
|
||||||
|
if(totsel) {
|
||||||
|
float imat[3][3], mat[3][3];
|
||||||
|
|
||||||
|
/* use channels to get stats */
|
||||||
|
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||||
|
if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
|
||||||
|
VecAddf(normal, normal, pchan->pose_mat[2]);
|
||||||
|
VecAddf(plane, plane, pchan->pose_mat[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VecMulf(plane, -1.0);
|
||||||
|
|
||||||
|
/* we need the transpose of the inverse for a normal... */
|
||||||
|
Mat3CpyMat4(imat, ob->obmat);
|
||||||
|
|
||||||
|
Mat3Inv(mat, imat);
|
||||||
|
Mat3Transp(mat);
|
||||||
|
Mat3MulVecfl(mat, normal);
|
||||||
|
Mat3MulVecfl(mat, plane);
|
||||||
|
|
||||||
|
result = ORIENTATION_EDGE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE))
|
else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user