Ton broke a couple of things in his last commit including PET in rotation mode and local axis constraints on objects.

Bringing that back and enabling PET in trackball rotate.

Changed the rotation manipulator drawing code to really align the Trackball rotate ball with the view (using getViewVector) so that it always looks centered on the selection.
This was particularly ugly in perspective mode with a selection far from the center of the screen: http://www.clubinfo.bdeb.qc.ca/~theeth/screenie.jpg

Moved getViewVector from transform_constraints.c to transform_generics.c since it is not really a constraint related function. Also made it independant on the TransInfo structure so it might be useful elsewhere too.
This commit is contained in:
2005-03-20 02:00:16 +00:00
parent 0d2179774d
commit e65b0beea8
5 changed files with 189 additions and 133 deletions

View File

@@ -2176,101 +2176,6 @@ int ToSphere(TransInfo *t, short mval[2])
/* ************************** ROTATION *************************** */ /* ************************** ROTATION *************************** */
static void ApplyRotation(TransInfo *t, float mat[][3])
{
TransData *td = t->data;
float vec[3], totmat[3][3], smat[3][3];
int i;
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (G.vd->around == V3D_LOCAL) {
VECCOPY(t->center, td->center);
}
if (t->flag & T_EDIT) {
Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat);
VecSubf(vec, td->iloc, t->center);
Mat3MulVecfl(smat, vec);
VecAddf(td->loc, vec, t->center);
}
else {
float eul[3], fmat[3][3];
/* translation */
VecSubf(vec, td->center, t->center);
Mat3MulVecfl(mat, vec);
VecAddf(vec, vec, t->center);
/* vec now is the location where the object has to be */
VecSubf(vec, vec, td->center);
Mat3MulVecfl(td->smtx, vec);
VecAddf(td->loc, td->iloc, vec);
if(td->flag & TD_USEQUAT) {
float quat[4];
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);
}
else if ((G.vd->flag & V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
float obmat[3][3];
/* are there ipo keys? */
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
float rot[3];
/* 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);
Mat3ToEul(fmat, eul);
compatible_eul(eul, td->ext->irot);
/* 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);
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 {
/* 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, mat, obmat);
Mat3ToEul(fmat, eul);
compatible_eul(eul, td->ext->irot);
/* correct back for delta rot */
VecSubf(eul, eul, td->ext->drot);
/* and apply */
VECCOPY(td->ext->rot, eul);
}
}
}
}
}
void initRotation(TransInfo *t) void initRotation(TransInfo *t)
{ {
@@ -2283,6 +2188,117 @@ void initRotation(TransInfo *t)
t->transform = Rotation; t->transform = Rotation;
} }
static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
float vec[3], totmat[3][3], smat[3][3];
if (t->flag & T_EDIT) {
Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat);
VecSubf(vec, td->iloc, t->center);
Mat3MulVecfl(smat, vec);
VecAddf(td->loc, vec, t->center);
}
else {
float eul[3], fmat[3][3];
/* translation */
VecSubf(vec, td->center, t->center);
Mat3MulVecfl(mat, vec);
VecAddf(vec, vec, t->center);
/* vec now is the location where the object has to be */
VecSubf(vec, vec, td->center);
Mat3MulVecfl(td->smtx, vec);
VecAddf(td->loc, td->iloc, vec);
if(td->flag & TD_USEQUAT) {
float quat[4];
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);
}
else if ((G.vd->flag & V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
float obmat[3][3];
/* are there ipo keys? */
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
float rot[3];
/* 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);
Mat3ToEul(fmat, eul);
compatible_eul(eul, td->ext->irot);
/* 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);
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 {
/* 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, mat, obmat);
Mat3ToEul(fmat, eul);
compatible_eul(eul, td->ext->irot);
/* correct back for delta rot */
VecSubf(eul, eul, td->ext->drot);
/* and apply */
VECCOPY(td->ext->rot, eul);
}
}
}
}
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 (G.vd->around == V3D_LOCAL) {
VECCOPY(t->center, td->center);
}
if (t->con.applyRot) {
t->con.applyRot(t, td, axis);
VecRotToMat3(axis, angle * td->factor, mat);
}
else if (G.f & G_PROPORTIONAL) {
VecRotToMat3(axis, angle * td->factor, mat);
}
ElementRotation(t, td, mat);
}
}
int Rotation(TransInfo *t, short mval[2]) int Rotation(TransInfo *t, short mval[2])
{ {
TransData *td = t->data; TransData *td = t->data;
@@ -2357,7 +2373,7 @@ int Rotation(TransInfo *t, short mval[2])
Mat3CpyMat3(t->mat, mat); // used in manipulator Mat3CpyMat3(t->mat, mat); // used in manipulator
ApplyRotation(t, mat); applyRotation(t, final, axis);
recalcData(t); recalcData(t);
@@ -2373,7 +2389,7 @@ int Rotation(TransInfo *t, short mval[2])
/* ************************** TRACKBALL *************************** */ /* ************************** TRACKBALL *************************** */
void initTrackball(TransInfo *t) static void initTrackball(TransInfo *t)
{ {
t->idx_max = 1; t->idx_max = 1;
t->num.idx_max = 1; t->num.idx_max = 1;
@@ -2384,7 +2400,37 @@ void initTrackball(TransInfo *t)
t->transform = Trackball; t->transform = Trackball;
} }
int Trackball(TransInfo *t, short mval[2]) static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float angles[2])
{
TransData *td = t->data;
float mat[3][3], smat[3][3], totmat[3][3];
int i;
VecRotToMat3(axis1, angles[0], smat);
VecRotToMat3(axis2, angles[1], totmat);
Mat3MulMat3(mat, smat, totmat);
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (G.vd->around == V3D_LOCAL) {
VECCOPY(t->center, td->center);
}
if (G.f & G_PROPORTIONAL) {
VecRotToMat3(axis1, td->factor * angles[0], smat);
VecRotToMat3(axis2, td->factor * angles[1], totmat);
Mat3MulMat3(mat, smat, totmat);
}
ElementRotation(t, td, mat);
}
}
static int Trackball(TransInfo *t, short mval[2])
{ {
char str[50]; char str[50];
float axis1[3], axis2[3]; float axis1[3], axis2[3];
@@ -2397,8 +2443,8 @@ int Trackball(TransInfo *t, short mval[2])
Normalise(axis2); Normalise(axis2);
/* factore has to become setting or so */ /* factore has to become setting or so */
phi[0]= .01*(float)( t->imval[1] - mval[1] ); phi[0]= 0.01f*(float)( t->imval[1] - mval[1] );
phi[1]= .01*(float)( mval[0] - t->imval[0] ); phi[1]= 0.01f*(float)( mval[0] - t->imval[0] );
//if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f; //if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
//else t->fac += dphi; //else t->fac += dphi;
@@ -2427,7 +2473,7 @@ int Trackball(TransInfo *t, short mval[2])
Mat3CpyMat3(t->mat, mat); // used in manipulator Mat3CpyMat3(t->mat, mat); // used in manipulator
ApplyRotation(t, mat); applyTrackball(t, axis1, axis2, phi);
recalcData(t); recalcData(t);

View File

@@ -186,35 +186,12 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) {
Mat3MulVecfl(t->con.mtx, vec); Mat3MulVecfl(t->con.mtx, vec);
} }
static void getViewVector(TransInfo *t, float coord[3], float vec[3]) {
if (G.vd->persp)
{
float p1[4], p2[4];
VecAddf(p1, coord, t->con.center);
p1[3] = 1.0f;
VECCOPY(p2, p1);
p2[3] = 1.0f;
Mat4MulVec4fl(G.vd->viewmat, p2);
p2[0] = 2.0f * p2[0];
p2[1] = 2.0f * p2[1];
p2[2] = 2.0f * p2[2];
Mat4MulVec4fl(G.vd->viewinv, p2);
VecSubf(vec, p2, p1);
Normalise(vec);
}
else {
VECCOPY(vec, G.vd->viewinv[2]);
}
}
static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3]) { static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3]) {
float norm[3], n[3], vec[3], factor; float norm[3], n[3], vec[3], factor;
getViewVector(t, in, norm); VecAddf(vec, in, t->con.center);
getViewVector(vec, norm);
Normalise(axis); Normalise(axis);
@@ -239,7 +216,8 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3
static void planeProjection(TransInfo *t, float in[3], float out[3]) { static void planeProjection(TransInfo *t, float in[3], float out[3]) {
float vec[3], factor, angle, norm[3]; float vec[3], factor, angle, norm[3];
getViewVector(t, in, norm); VecAddf(vec, in, t->con.center);
getViewVector(vec, norm);
VecSubf(vec, out, in); VecSubf(vec, out, in);
factor = Normalise(vec); factor = Normalise(vec);

View File

@@ -114,6 +114,32 @@ extern TransInfo Trans;
/* ************************** Functions *************************** */ /* ************************** Functions *************************** */
void getViewVector(float coord[3], float vec[3]) {
if (G.vd->persp)
{
float p1[4], p2[4];
VECCOPY(p1, coord);
p1[3] = 1.0f;
VECCOPY(p2, p1);
p2[3] = 1.0f;
Mat4MulVec4fl(G.vd->viewmat, p2);
p2[0] = 2.0f * p2[0];
p2[1] = 2.0f * p2[1];
p2[2] = 2.0f * p2[2];
Mat4MulVec4fl(G.vd->viewinv, p2);
VecSubf(vec, p2, p1);
}
else {
VECCOPY(vec, G.vd->viewinv[2]);
}
Normalise(vec);
}
/* ************************** GENERICS **************************** */ /* ************************** GENERICS **************************** */
/* called for objects updating while transform acts, once per redraw */ /* called for objects updating while transform acts, once per redraw */

View File

@@ -64,6 +64,8 @@ void calculatePropRatio(TransInfo *t);
void snapGrid(TransInfo *t, float *val); void snapGrid(TransInfo *t, float *val);
void getViewVector(float coord[3], float vec[3]);
TransInfo * BIF_GetTransInfo(void); TransInfo * BIF_GetTransInfo(void);
#endif #endif

View File

@@ -79,6 +79,7 @@
#include "blendef.h" #include "blendef.h"
#include "transform.h" #include "transform.h"
#include "transform_generics.h"
/* drawing defines */ /* drawing defines */
#define MAN_SIZE 0.15 #define MAN_SIZE 0.15
@@ -430,27 +431,30 @@ static void draw_manipulator_rotate(float mat[][4])
/* Trackball center */ /* Trackball center */
if(Gval & MAN_ROT_T) { if(Gval & MAN_ROT_T) {
float smat[3][3], imat[3][3], tmat[3][3]; float smat[3][3], imat[3][3];
float offset[3];
if(G.f & G_PICKSEL) glLoadName(MAN_ROT_T); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_T);
Mat3CpyMat4(smat, mat); Mat3CpyMat4(smat, mat);
Mat3Inv(imat, smat); Mat3Inv(imat, smat);
Mat3CpyMat4(smat, G.vd->viewinv);
Mat3MulMat3(tmat, imat, smat);
Normalise(tmat[2]); getViewVector(mat[3], offset);
VecMulf(offset, -1.0f);
Mat3MulVecfl(imat, offset);
BIF_ThemeColor(TH_TRANSFORM); BIF_ThemeColor(TH_TRANSFORM);
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glVertex3fv(tmat[2]); glVertex3fv(offset);
glEnd(); glEnd();
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
BIF_GetThemeColor3fv(TH_TRANSFORM, vec); BIF_GetThemeColor3fv(TH_TRANSFORM, vec);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, vec); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, vec);
VECCOPY(vec, tmat[2]); VECCOPY(vec, offset);
glTranslatef(vec[0], vec[1], vec[2]); glTranslatef(vec[0], vec[1], vec[2]);
gluSphere(qobj, CYWID, 8, 6); gluSphere(qobj, CYWID, 8, 6);