forked from bartvdbraak/blender
Transform widgets; Scale and Rotate versions
To use; press the (temporal) icon in header. Switching widget types is by pressing G, R or S once, if current widget type is different it switches, otherwise it goes to normal Transform(). Widgets need a bit test for picking accuracy, correct drawing etc. The rotate widget has a center button for 'trackball' rotate. That latter can also be used for hotkey-based rotate. In current code, all widgets remain in "Global" space, also in editmode. Also widget updates while using normal transform has to be done. 2 Bugfixes: - rotate in PoseMode had error for 2d 'around' center - transform in postemode could crash, due to typo (& or |)
This commit is contained in:
parent
a96ed881dc
commit
a2ed880c9f
@ -4625,6 +4625,7 @@ static void do_versions(Main *main)
|
||||
if(main->versionfile <= 236) {
|
||||
Scene *sce= main->scene.first;
|
||||
Camera *cam= main->camera.first;
|
||||
bScreen *sc;
|
||||
|
||||
while(sce) {
|
||||
if(sce->r.postsat==0.0) sce->r.postsat= 1.0;
|
||||
@ -4637,6 +4638,19 @@ static void do_versions(Main *main)
|
||||
}
|
||||
cam= cam->id.next;
|
||||
}
|
||||
/* set manipulator type */
|
||||
for (sc= main->screen.first; sc; sc= sc->id.next) {
|
||||
ScrArea *sa;
|
||||
for (sa= sc->areabase.first; sa; sa= sa->next) {
|
||||
SpaceLink *sl;
|
||||
for (sl= sa->spacedata.first; sl; sl= sl->next) {
|
||||
if(sl->spacetype==SPACE_VIEW3D) {
|
||||
View3D *v3d= (View3D *)sl;
|
||||
if(v3d->twtype==0) v3d->twtype= V3D_MANIPULATOR_TRANSLATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* don't forget to set version number in blender.c! */
|
||||
|
@ -61,6 +61,7 @@ void drawcircball(float *cent, float rad, float tmat[][4]);
|
||||
void get_local_bounds(struct Object *ob, float *centre, float *size);
|
||||
void draw_object(struct Base *base);
|
||||
void draw_object_ext(struct Base *base);
|
||||
void drawsolidcube(float size);
|
||||
extern void draw_object_backbufsel(struct Object *ob);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -33,7 +33,7 @@
|
||||
#ifndef BIF_TRANSFORM_H
|
||||
#define BIF_TRANSFORM_H
|
||||
|
||||
#define NEWTRANSFORM 1
|
||||
//#define NEWTRANSFORM 1
|
||||
|
||||
/* ******************** Macros & Prototypes *********************** */
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
#define TFM_TILT 9
|
||||
|
||||
#define TFM_LAMP_ENERGY 10
|
||||
#define TFM_TRACKBALL 11
|
||||
|
||||
// not sure if adding modes is the right way... context detecting could be done different (ton)
|
||||
#define TFM_TEX 32
|
||||
|
@ -147,10 +147,10 @@ typedef struct View3D {
|
||||
#define V3D_SHOW_Y 4
|
||||
#define V3D_SHOW_Z 8
|
||||
|
||||
/* View3d->twtype */
|
||||
#define V3D_MANIPULATOR_TRANSLATE 0
|
||||
#define V3D_MANIPULATOR_ROTATE 1
|
||||
#define V3D_MANIPULATOR_SCALE 2
|
||||
/* View3d->twtype (bits, we can combine them) */
|
||||
#define V3D_MANIPULATOR_TRANSLATE 1
|
||||
#define V3D_MANIPULATOR_ROTATE 2
|
||||
#define V3D_MANIPULATOR_SCALE 4
|
||||
|
||||
/* View3d->twmode */
|
||||
#define V3D_MANIPULATOR_GLOBAL 0
|
||||
|
@ -318,11 +318,14 @@ void drawaxes(float size)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void drawgourcube(void)
|
||||
|
||||
void drawsolidcube(float size)
|
||||
{
|
||||
float n[3];
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(size, size, size);
|
||||
|
||||
n[0]=0; n[1]=0; n[2]=0;
|
||||
glBegin(GL_QUADS);
|
||||
n[0]= -1.0;
|
||||
@ -364,8 +367,9 @@ static void drawgourcube(void)
|
||||
glNormal3fv(n);
|
||||
glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void drawcube(void)
|
||||
{
|
||||
|
@ -1217,7 +1217,12 @@ void screenmain(void)
|
||||
if (event==0 || event==EXECUTE) {
|
||||
screen_dispatch_events();
|
||||
}
|
||||
|
||||
|
||||
if(G.f & G_DEBUG) {
|
||||
GLenum error = glGetError();
|
||||
if (error)
|
||||
printf("GL error: %s\n", gluErrorString(error));
|
||||
}
|
||||
/* Bizar hack. The event queue has mutated... */
|
||||
if ( (firsttime) && (event == 0) ) {
|
||||
|
||||
|
@ -720,7 +720,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
unsigned short event= evt->event;
|
||||
short val= evt->val;
|
||||
char ascii= evt->ascii;
|
||||
View3D *v3d= curarea->spacedata.first;
|
||||
View3D *v3d= sa->spacedata.first;
|
||||
Object *ob;
|
||||
float *curs;
|
||||
int doredraw= 0, pupval;
|
||||
@ -1220,12 +1220,20 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
if(okee("Clear location")) {
|
||||
clear_object('g');
|
||||
}
|
||||
} else if((G.qual==0))
|
||||
} else if((G.qual==0)) {
|
||||
if(v3d->twflag & V3D_USE_MANIPULATOR) {
|
||||
if((v3d->twtype & V3D_MANIPULATOR_TRANSLATE)==0) {
|
||||
v3d->twtype= V3D_MANIPULATOR_TRANSLATE;
|
||||
doredraw= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef NEWTRANSFORM
|
||||
Transform(TFM_TRANSLATION);
|
||||
#else
|
||||
transform('g');
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case HKEY:
|
||||
if(G.obedit) {
|
||||
@ -1485,19 +1493,35 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
if (G.obedit->type==OB_MESH)
|
||||
loopoperations(LOOP_CUT);
|
||||
}
|
||||
else if((G.qual==0))
|
||||
else if((G.qual==0)) {
|
||||
if(v3d->twflag & V3D_USE_MANIPULATOR) {
|
||||
if((v3d->twtype & V3D_MANIPULATOR_ROTATE)==0) {
|
||||
v3d->twtype= V3D_MANIPULATOR_ROTATE;
|
||||
doredraw= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef NEWTRANSFORM
|
||||
Transform(TFM_ROTATION);
|
||||
#else
|
||||
transform('r');
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if((G.qual==0))
|
||||
else if((G.qual==0)) {
|
||||
if(v3d->twflag & V3D_USE_MANIPULATOR) {
|
||||
if((v3d->twtype & V3D_MANIPULATOR_ROTATE)==0) {
|
||||
v3d->twtype= V3D_MANIPULATOR_ROTATE;
|
||||
doredraw= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef NEWTRANSFORM
|
||||
Transform(TFM_ROTATION);
|
||||
#else
|
||||
transform('r');
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case SKEY:
|
||||
if(G.obedit) {
|
||||
@ -1517,14 +1541,25 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
#endif
|
||||
else if(G.qual==LR_SHIFTKEY)
|
||||
snapmenu();
|
||||
else if(G.qual==0)
|
||||
else if(G.qual==0) {
|
||||
if(v3d->twflag & V3D_USE_MANIPULATOR) {
|
||||
if((v3d->twtype & V3D_MANIPULATOR_SCALE)==0) {
|
||||
v3d->twtype= V3D_MANIPULATOR_SCALE;
|
||||
doredraw= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef NEWTRANSFORM
|
||||
Transform(TFM_RESIZE);
|
||||
else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
|
||||
Transform(TFM_TOSPHERE);
|
||||
#else
|
||||
transform('s');
|
||||
#endif
|
||||
}
|
||||
else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
|
||||
#ifdef NEWTRANSFORM
|
||||
Transform(TFM_TOSPHERE);
|
||||
#endif
|
||||
|
||||
}
|
||||
else if(G.qual==LR_ALTKEY) {
|
||||
if(okee("Clear size")) {
|
||||
@ -1534,15 +1569,25 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
else if(G.qual==LR_SHIFTKEY) {
|
||||
snapmenu();
|
||||
}
|
||||
else if((G.qual==0))
|
||||
else if((G.qual==0)) {
|
||||
if(v3d->twflag & V3D_USE_MANIPULATOR) {
|
||||
if((v3d->twtype & V3D_MANIPULATOR_SCALE)==0) {
|
||||
v3d->twtype= V3D_MANIPULATOR_SCALE;
|
||||
doredraw= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef NEWTRANSFORM
|
||||
Transform(TFM_RESIZE);
|
||||
#else
|
||||
transform('s');
|
||||
#endif
|
||||
}
|
||||
#ifdef NEWTRANSFORM
|
||||
else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
|
||||
Transform(TFM_TOSPHERE);
|
||||
else if(G.qual==(LR_CTRLKEY|LR_ALTKEY))
|
||||
Transform(TFM_SHEAR);
|
||||
#else
|
||||
transform('s');
|
||||
#endif
|
||||
break;
|
||||
case TKEY:
|
||||
|
@ -1227,7 +1227,7 @@ static void createTransData(TransInfo *t)
|
||||
t->mode &= ~TFM_TEX; // now becoming normal grab/rot/scale
|
||||
}
|
||||
else if (G.obpose) {
|
||||
t->flag &= T_POSE;
|
||||
t->flag |= T_POSE;
|
||||
createTransPose();
|
||||
}
|
||||
else if (G.obedit) {
|
||||
@ -1338,6 +1338,9 @@ void Transform(int mode)
|
||||
case TFM_TILT:
|
||||
initTilt(&Trans);
|
||||
break;
|
||||
case TFM_TRACKBALL:
|
||||
initTrackball(&Trans);
|
||||
break;
|
||||
}
|
||||
|
||||
// Emptying event queue
|
||||
@ -1572,8 +1575,6 @@ void Transform(int mode)
|
||||
scrarea_queue_headredraw(curarea);
|
||||
}
|
||||
|
||||
static void draw_nothing(TransInfo *t) {}
|
||||
|
||||
void ManipulatorTransform(int mode)
|
||||
{
|
||||
int ret_val = 0;
|
||||
@ -1597,9 +1598,6 @@ void ManipulatorTransform(int mode)
|
||||
if (Trans.total == 0)
|
||||
return;
|
||||
|
||||
/* no drawing of constraint lines */
|
||||
Trans.con.drawExtra= draw_nothing;
|
||||
|
||||
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
|
||||
/* EVIL2: we gave as argument also texture space context bit... was cleared */
|
||||
mode= Trans.mode;
|
||||
@ -1617,8 +1615,12 @@ void ManipulatorTransform(int mode)
|
||||
case TFM_RESIZE:
|
||||
initResize(&Trans);
|
||||
break;
|
||||
case TFM_TRACKBALL:
|
||||
initTrackball(&Trans);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Trans.flag |= T_USES_MANIPULATOR;
|
||||
Trans.redraw = 1;
|
||||
|
||||
while (ret_val == 0) {
|
||||
@ -1915,6 +1917,8 @@ void initResize(TransInfo *t)
|
||||
(Trans.center2d[0] - Trans.imval[0])*(Trans.center2d[0] - Trans.imval[0])
|
||||
) );
|
||||
|
||||
if(Trans.fac==0.0f) Trans.fac= 1.0f; // prevent Inf
|
||||
|
||||
t->idx_max = 2;
|
||||
t->num.idx_max = 2;
|
||||
t->snap[0] = 0.0f;
|
||||
@ -1960,13 +1964,19 @@ int Resize(TransInfo *t, short mval[2])
|
||||
int i;
|
||||
char str[50];
|
||||
|
||||
ratio = (float)sqrt( (float)
|
||||
(
|
||||
(t->center2d[1] - mval[1])*(t->center2d[1] - mval[1])
|
||||
+
|
||||
(t->center2d[0] - mval[0])*(t->center2d[0] - mval[0])
|
||||
) ) / t->fac;
|
||||
|
||||
/* for manipulator, center handle, the scaling can't be done relative to center */
|
||||
if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) {
|
||||
ratio = 1.0f - ((t->center2d[0] - mval[0]) + (t->center2d[1] - mval[1]))/100.0f;
|
||||
}
|
||||
else {
|
||||
ratio = (float)sqrt( (float)
|
||||
(
|
||||
(t->center2d[1] - mval[1])*(t->center2d[1] - mval[1])
|
||||
+
|
||||
(t->center2d[0] - mval[0])*(t->center2d[0] - mval[0])
|
||||
) ) / t->fac;
|
||||
}
|
||||
|
||||
size[0] = size[1] = size[2] = ratio;
|
||||
|
||||
snapGrid(t, size);
|
||||
@ -1982,6 +1992,8 @@ int Resize(TransInfo *t, short mval[2])
|
||||
t->con.applySize(t, NULL, mat);
|
||||
}
|
||||
|
||||
Mat3CpyMat3(t->mat, mat); // used in manipulator
|
||||
|
||||
headerResize(t, size, str);
|
||||
|
||||
for(i = 0 ; i < t->total; i++, td++) {
|
||||
@ -2064,7 +2076,7 @@ int Resize(TransInfo *t, short mval[2])
|
||||
|
||||
force_draw(0);
|
||||
|
||||
helpline (t->center);
|
||||
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t->center);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -2249,6 +2261,8 @@ int Rotation(TransInfo *t, short mval[2])
|
||||
//printf("Axis %f %f %f\n", axis[0], axis[1], axis[2]);
|
||||
VecRotToMat3(axis, final * td->factor, mat);
|
||||
|
||||
Mat3CpyMat3(t->mat, mat); // used in manipulator
|
||||
|
||||
for(i = 0 ; i < t->total; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
@ -2352,11 +2366,170 @@ int Rotation(TransInfo *t, short mval[2])
|
||||
|
||||
force_draw(0);
|
||||
|
||||
helpline (t->center);
|
||||
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t->center);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ************************** TRACKBALL *************************** */
|
||||
|
||||
void initTrackball(TransInfo *t)
|
||||
{
|
||||
t->idx_max = 1;
|
||||
t->num.idx_max = 1;
|
||||
t->snap[0] = 0.0f;
|
||||
t->snap[1] = G.vd->grid * (float)((5.0/180)*M_PI);
|
||||
t->snap[2] = t->snap[1] * 0.2f;
|
||||
t->fac = 0;
|
||||
t->transform = Trackball;
|
||||
}
|
||||
|
||||
int Trackball(TransInfo *t, short mval[2])
|
||||
{
|
||||
TransData *td = t->data;
|
||||
int i;
|
||||
char str[50];
|
||||
float vec[3], axis1[3], axis2[3];
|
||||
float mat[3][3], totmat[3][3], smat[3][3];
|
||||
float phi[2];
|
||||
|
||||
VECCOPY(axis1, G.vd->persinv[0]);
|
||||
VECCOPY(axis2, G.vd->persinv[1]);
|
||||
Normalise(axis1);
|
||||
Normalise(axis2);
|
||||
|
||||
/* factore has to become setting or so */
|
||||
phi[0]= .01*(float)( t->imval[1] - mval[1] );
|
||||
phi[1]= .01*(float)( mval[0] - t->imval[0] );
|
||||
|
||||
//if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
|
||||
//else t->fac += dphi;
|
||||
|
||||
snapGrid(t, phi);
|
||||
|
||||
if (hasNumInput(&t->num)) {
|
||||
//char c[20];
|
||||
|
||||
//applyNumInput(&t->num, phi);
|
||||
|
||||
//outputNumInput(&(t->num), c);
|
||||
|
||||
//sprintf(str, "Trackball: %s %s", &c[0], t->proptext);
|
||||
|
||||
//final *= (float)(M_PI / 180.0);
|
||||
}
|
||||
else {
|
||||
sprintf(str, "Trackball: %.2f %.2f %s", 180.0*phi[0]/M_PI, 180.0*phi[1]/M_PI, t->proptext);
|
||||
}
|
||||
|
||||
VecRotToMat3(axis1, phi[0], smat);
|
||||
VecRotToMat3(axis2, phi[1], totmat);
|
||||
|
||||
Mat3MulMat3(mat, smat, totmat);
|
||||
|
||||
Mat3CpyMat3(t->mat, mat); // used in manipulator
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
headerprint(str);
|
||||
|
||||
force_draw(0);
|
||||
|
||||
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t->center);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ************************** TRANSLATION *************************** */
|
||||
|
||||
void initTranslation(TransInfo *t)
|
||||
|
@ -146,8 +146,11 @@ typedef struct TransInfo {
|
||||
#define T_EDIT 2
|
||||
#define T_POSE 4
|
||||
#define T_TEXTURE 8
|
||||
// for manipulator exceptions, like scaling using center point, drawing help lines
|
||||
#define T_USES_MANIPULATOR 128
|
||||
|
||||
|
||||
/* transinfo->con->mode */
|
||||
#define CON_APPLY 1
|
||||
#define CON_AXIS0 2
|
||||
#define CON_AXIS1 4
|
||||
@ -186,5 +189,8 @@ int ShrinkFatten(TransInfo *t, short mval[2]);
|
||||
void initTilt(TransInfo *t);
|
||||
int Tilt(TransInfo *t, short mval[2]);
|
||||
|
||||
void initTrackball(TransInfo *t);
|
||||
int Trackball(TransInfo *t, short mval[2]);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -589,6 +589,7 @@ void BIF_setSingleAxisConstraint(float vec[3]) {
|
||||
|
||||
Crossf(space[1], vec, v);
|
||||
Crossf(space[2], vec, space[1]);
|
||||
Mat3Ortho(space);
|
||||
|
||||
Mat3Ortho(space);
|
||||
|
||||
@ -603,6 +604,8 @@ void BIF_setSingleAxisConstraint(float vec[3]) {
|
||||
t->con.applySize = applyAxisConstraintSize;
|
||||
t->con.applyRot = applyAxisConstraintRot;
|
||||
t->redraw = 1;
|
||||
|
||||
startConstraint(t);
|
||||
}
|
||||
|
||||
void BIF_setDualAxisConstraint(float vec1[3], float vec2[3]) {
|
||||
@ -612,7 +615,6 @@ void BIF_setDualAxisConstraint(float vec1[3], float vec2[3]) {
|
||||
VECCOPY(space[0], vec1);
|
||||
VECCOPY(space[1], vec2);
|
||||
Crossf(space[2], space[0], space[1]);
|
||||
|
||||
Mat3Ortho(space);
|
||||
|
||||
Mat3CpyMat3(t->con.mtx, space);
|
||||
@ -626,6 +628,8 @@ void BIF_setDualAxisConstraint(float vec1[3], float vec2[3]) {
|
||||
t->con.applySize = applyAxisConstraintSize;
|
||||
t->con.applyRot = applyAxisConstraintRot;
|
||||
t->redraw = 1;
|
||||
|
||||
startConstraint(t);
|
||||
}
|
||||
|
||||
|
||||
@ -636,6 +640,8 @@ void BIF_drawConstraint(void)
|
||||
|
||||
if (!(tc->mode & CON_APPLY))
|
||||
return;
|
||||
if (t->flag & T_USES_MANIPULATOR)
|
||||
return;
|
||||
|
||||
if (tc->drawExtra) {
|
||||
tc->drawExtra(t);
|
||||
|
@ -133,7 +133,7 @@ void recalcData(TransInfo *t)
|
||||
for (i=0; i<t->total; i++, td++) {
|
||||
chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel");
|
||||
|
||||
if (t->mode == TFM_ROTATION) {
|
||||
if (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) {
|
||||
chan->flag |= POSE_ROT;
|
||||
memcpy (chan->quat, td->ext->quat, sizeof (chan->quat));
|
||||
}
|
||||
@ -230,16 +230,17 @@ void recalcData(TransInfo *t)
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if(base->flag & BA_DO_IPO) {
|
||||
IpoCurve *icu;
|
||||
|
||||
base->object->ctime= -1234567.0;
|
||||
|
||||
icu= base->object->ipo->curve.first;
|
||||
while(icu) {
|
||||
calchandles_ipocurve(icu);
|
||||
icu= icu->next;
|
||||
}
|
||||
|
||||
if(base->object->ipo) {
|
||||
IpoCurve *icu;
|
||||
|
||||
base->object->ctime= -1234567.0;
|
||||
|
||||
icu= base->object->ipo->curve.first;
|
||||
while(icu) {
|
||||
calchandles_ipocurve(icu);
|
||||
icu= icu->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(base->object->partype & PARSLOW) {
|
||||
base->object->partype -= PARSLOW;
|
||||
@ -639,8 +640,9 @@ void calculateCenter(TransInfo *t)
|
||||
|
||||
/* setting constraint center */
|
||||
VECCOPY(t->con.center, t->center);
|
||||
if(t->flag & T_EDIT) {
|
||||
Mat4MulVecfl(G.obedit->obmat, t->con.center);
|
||||
if(t->flag & (T_EDIT|T_POSE)) {
|
||||
Object *ob= G.obedit?G.obedit:G.obpose;
|
||||
Mat4MulVecfl(ob->obmat, t->con.center);
|
||||
}
|
||||
|
||||
/* voor panning from cameraview */
|
||||
|
@ -76,6 +76,7 @@
|
||||
|
||||
#include "BSE_edit.h"
|
||||
#include "BSE_view.h"
|
||||
#include "BDR_drawobject.h"
|
||||
|
||||
#include "blendef.h"
|
||||
#include "transform.h"
|
||||
@ -95,7 +96,14 @@
|
||||
#define MAN_ROT_X 8
|
||||
#define MAN_ROT_Y 16
|
||||
#define MAN_ROT_Z 32
|
||||
#define MAN_ROT_C 63
|
||||
#define MAN_ROT_V 64
|
||||
#define MAN_ROT_T 128
|
||||
#define MAN_ROT_C 248
|
||||
|
||||
#define MAN_SCALE_X 256
|
||||
#define MAN_SCALE_Y 512
|
||||
#define MAN_SCALE_Z 1024
|
||||
#define MAN_SCALE_C 1792
|
||||
|
||||
|
||||
/* GLOBAL VARIABLE THAT SHOULD MOVED TO SCREEN MEMBER OR SOMETHING */
|
||||
@ -273,9 +281,9 @@ static int calc_manipulator(ScrArea *sa)
|
||||
/* global, local or normal orientation? */
|
||||
if(ob) {
|
||||
// local....
|
||||
if(totsel==1 || v3d->around==V3D_LOCAL) {
|
||||
Mat4CpyMat4(v3d->twmat, ob->obmat);
|
||||
Mat4Ortho(v3d->twmat);
|
||||
if(totsel==1 || v3d->around==V3D_LOCAL || G.obedit || G.obpose) {
|
||||
//Mat4CpyMat4(v3d->twmat, ob->obmat);
|
||||
//Mat4Ortho(v3d->twmat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,7 +306,7 @@ static void manipulator_setcolor(char mode)
|
||||
else {
|
||||
switch(mode) {
|
||||
case 'x':
|
||||
glColor3ub(255, 100, 100);
|
||||
glColor3ub(255, 0, 100);
|
||||
break;
|
||||
case 'y':
|
||||
glColor3ub(100, 255, 100);
|
||||
@ -324,14 +332,228 @@ static void manipulator_setcolor(char mode)
|
||||
|
||||
static int Gval= 0xFFFF; // defines drawmodus while moving...
|
||||
|
||||
static void draw_manipulator_rotate(float mat[][4])
|
||||
{
|
||||
double plane[4];
|
||||
float size, vec[3], unitmat[4][4];
|
||||
|
||||
/* when called while moving in mixed mode, do not draw when... */
|
||||
if((Gval & MAN_ROT_C)==0) return;
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
Mat4One(unitmat);
|
||||
|
||||
/* Screen aligned help circle */
|
||||
glPushMatrix();
|
||||
glTranslatef(mat[3][0], mat[3][1], mat[3][2]);
|
||||
|
||||
/* clipplane makes nice handles, calc here because of multmatrix but with translate! */
|
||||
VECCOPY(plane, G.vd->viewinv[2]);
|
||||
plane[3]= -0.001; // clip full circle
|
||||
glClipPlane(GL_CLIP_PLANE0, plane);
|
||||
|
||||
glRotatef( -360.0*saacos(G.vd->viewquat[0])/M_PI, G.vd->viewquat[1], G.vd->viewquat[2], G.vd->viewquat[3]);
|
||||
VECCOPY(vec, mat[0]);
|
||||
size= Normalise(vec);
|
||||
if((G.f & G_PICKSEL)==0) {
|
||||
BIF_ThemeColorShade(TH_BACK, -30);
|
||||
drawcircball(unitmat[3], size, unitmat);
|
||||
}
|
||||
/* Screen aligned view rot circle */
|
||||
if(Gval & MAN_ROT_V) {
|
||||
if(G.f & G_PICKSEL) glLoadName(MAN_ROT_V);
|
||||
BIF_ThemeColor(TH_TRANSFORM);
|
||||
drawcircball(unitmat[3], 1.2*size, unitmat);
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
/* apply the transform delta */
|
||||
if(G.moving) {
|
||||
float matt[4][4];
|
||||
Mat4CpyMat4(matt, mat); // to copy the parts outside of [3][3]
|
||||
Mat4MulMat34(matt, Trans.mat, mat);
|
||||
mymultmatrix(matt);
|
||||
}
|
||||
else mymultmatrix(mat);
|
||||
|
||||
/* Trackball center */
|
||||
if(Gval & MAN_ROT_T) {
|
||||
GLUquadricObj *qobj = gluNewQuadric();
|
||||
|
||||
if(G.f & G_PICKSEL) glLoadName(MAN_ROT_T);
|
||||
|
||||
BIF_ThemeColor(TH_TRANSFORM);
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glVertex3fv(G.vd->viewinv[2]);
|
||||
glEnd();
|
||||
|
||||
BIF_GetThemeColor3fv(TH_TRANSFORM, vec);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, vec);
|
||||
|
||||
/* only has to be set here */
|
||||
gluQuadricDrawStyle(qobj, GLU_FILL);
|
||||
gluQuadricNormals(qobj, GLU_SMOOTH);
|
||||
glEnable(GL_CULL_FACE); // backface removal
|
||||
glEnable(GL_LIGHTING);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glTranslatef(G.vd->viewinv[2][0], G.vd->viewinv[2][1], G.vd->viewinv[2][2]);
|
||||
|
||||
gluSphere(qobj, CYWID, 8, 6);
|
||||
|
||||
/* restore */
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_LIGHTING);
|
||||
glTranslatef(-G.vd->viewinv[2][0], -G.vd->viewinv[2][1], -G.vd->viewinv[2][2]);
|
||||
|
||||
gluDeleteQuadric(qobj);
|
||||
}
|
||||
|
||||
glEnable(GL_CLIP_PLANE0);
|
||||
|
||||
/* Z circle */
|
||||
if(Gval & MAN_ROT_Z) {
|
||||
if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Z);
|
||||
manipulator_setcolor('z');
|
||||
drawcircball(unitmat[3], 1.0, unitmat);
|
||||
}
|
||||
/* X circle */
|
||||
if(Gval & MAN_ROT_X) {
|
||||
if(G.f & G_PICKSEL) glLoadName(MAN_ROT_X);
|
||||
glRotatef(90.0, 0.0, 1.0, 0.0);
|
||||
manipulator_setcolor('x');
|
||||
drawcircball(unitmat[3], 1.0, unitmat);
|
||||
glRotatef(-90.0, 0.0, 1.0, 0.0);
|
||||
}
|
||||
/* Y circle */
|
||||
if(Gval & MAN_ROT_Y) {
|
||||
if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Y);
|
||||
glRotatef(-90.0, 1.0, 0.0, 0.0);
|
||||
manipulator_setcolor('y');
|
||||
drawcircball(unitmat[3], 1.0, unitmat);
|
||||
glRotatef(-90.0, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
glDisable(GL_CLIP_PLANE0);
|
||||
|
||||
myloadmatrix(G.vd->viewmat);
|
||||
|
||||
if(G.zbuf) glEnable(GL_DEPTH_TEST); // shouldn't be global, tsk!
|
||||
}
|
||||
|
||||
static void draw_manipulator_scale(float mat[][4])
|
||||
{
|
||||
float cusize= CYWID*0.75;
|
||||
|
||||
/* when called while moving in mixed mode, do not draw when... */
|
||||
if((Gval & MAN_SCALE_C)==0) return;
|
||||
|
||||
if(G.moving) {
|
||||
float matt[4][4];
|
||||
|
||||
Mat4CpyMat4(matt, mat); // to copy the parts outside of [3][3]
|
||||
Mat4MulMat34(matt, Trans.mat, mat);
|
||||
mymultmatrix(matt);
|
||||
}
|
||||
else mymultmatrix(mat);
|
||||
|
||||
/* if not shiftkey, center point as first, for selectbuffer order */
|
||||
if(G.f & G_PICKSEL) {
|
||||
if(!(G.qual & LR_SHIFTKEY)) {
|
||||
glLoadName(MAN_SCALE_C);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
else {
|
||||
float vec[3];
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
/* axis */
|
||||
glBegin(GL_LINES);
|
||||
if(Gval & MAN_SCALE_X) {
|
||||
manipulator_setcolor('x');
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glVertex3f(1.0, 0.0, 0.0);
|
||||
}
|
||||
if(Gval & MAN_SCALE_Y) {
|
||||
manipulator_setcolor('y');
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glVertex3f(0.0, 1.0, 0.0);
|
||||
}
|
||||
if(Gval & MAN_SCALE_Z) {
|
||||
manipulator_setcolor('z');
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glVertex3f(0.0, 0.0, 1.0);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* only has to be set when not in picking */
|
||||
glEnable(GL_CULL_FACE); // backface removal
|
||||
glEnable(GL_LIGHTING);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
/* center cube */
|
||||
BIF_GetThemeColor3fv(TH_TRANSFORM, vec);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, vec);
|
||||
|
||||
drawsolidcube(cusize);
|
||||
}
|
||||
|
||||
/* Z cube */
|
||||
glTranslatef(0.0, 0.0, 1.0+cusize/2);
|
||||
if(Gval & MAN_SCALE_Z) {
|
||||
if(G.f & G_PICKSEL) glLoadName(MAN_SCALE_Z);
|
||||
manipulator_setcolor('Z');
|
||||
drawsolidcube(cusize);
|
||||
}
|
||||
/* X cube */
|
||||
glTranslatef(1.0+cusize/2, 0.0, -(1.0+cusize/2));
|
||||
if(Gval & MAN_SCALE_X) {
|
||||
if(G.f & G_PICKSEL) glLoadName(MAN_SCALE_X);
|
||||
manipulator_setcolor('X');
|
||||
drawsolidcube(cusize);
|
||||
}
|
||||
/* Y cube */
|
||||
glTranslatef(-(1.0+cusize/2), 1.0+cusize/2, 0.0);
|
||||
if(Gval & MAN_SCALE_Y) {
|
||||
if(G.f & G_PICKSEL) glLoadName(MAN_SCALE_Y);
|
||||
manipulator_setcolor('Y');
|
||||
drawsolidcube(cusize);
|
||||
}
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
/* if shiftkey, center point as last, for selectbuffer order */
|
||||
if(G.f & G_PICKSEL) {
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
glTranslatef(0.0, -(1.0+cusize/2), 0.0);
|
||||
glLoadName(MAN_SCALE_C);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
myloadmatrix(G.vd->viewmat);
|
||||
|
||||
if(G.zbuf) glEnable(GL_DEPTH_TEST); // shouldn't be global, tsk!
|
||||
}
|
||||
|
||||
static void draw_manipulator_translate(float mat[][4])
|
||||
{
|
||||
GLUquadricObj *qobj = gluNewQuadric();
|
||||
|
||||
/* when called while moving in mixed mode, do not draw when... */
|
||||
if((Gval & MAN_TRANS_C)==0) return;
|
||||
|
||||
if(G.moving) glTranslatef(Trans.vec[0], Trans.vec[1], Trans.vec[2]);
|
||||
|
||||
glMultMatrixf(mat);
|
||||
mymultmatrix(mat);
|
||||
|
||||
/* if not shiftkey, center point as first, for selectbuffer order */
|
||||
if(G.f & G_PICKSEL) {
|
||||
@ -482,14 +704,17 @@ void BIF_draw_manipulator(ScrArea *sa)
|
||||
|
||||
if(v3d->twflag & V3D_DRAW_MANIPULATOR) {
|
||||
|
||||
if(v3d->twmode==V3D_MANIPULATOR_TRANSLATE)
|
||||
if(v3d->twtype & V3D_MANIPULATOR_ROTATE)
|
||||
draw_manipulator_rotate(v3d->twmat);
|
||||
if(v3d->twtype & V3D_MANIPULATOR_SCALE)
|
||||
draw_manipulator_scale(v3d->twmat);
|
||||
if(v3d->twtype & V3D_MANIPULATOR_TRANSLATE)
|
||||
draw_manipulator_translate(v3d->twmat);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int manipulator_selectbuf(ScrArea *sa)
|
||||
static int manipulator_selectbuf(ScrArea *sa, float hotspot)
|
||||
{
|
||||
View3D *v3d= sa->spacedata.first;
|
||||
rctf rect;
|
||||
@ -499,37 +724,47 @@ static int manipulator_selectbuf(ScrArea *sa)
|
||||
G.f |= G_PICKSEL;
|
||||
|
||||
getmouseco_areawin(mval);
|
||||
rect.xmin= mval[0]-7;
|
||||
rect.xmax= mval[0]+7;
|
||||
rect.ymin= mval[1]-7;
|
||||
rect.ymax= mval[1]+7;
|
||||
rect.xmin= mval[0]-hotspot;
|
||||
rect.xmax= mval[0]+hotspot;
|
||||
rect.ymin= mval[1]-hotspot;
|
||||
rect.ymax= mval[1]+hotspot;
|
||||
|
||||
/* get rid of overlay button matrix */
|
||||
persp(PERSP_VIEW);
|
||||
|
||||
setwinmatrixview3d(&rect);
|
||||
Mat4MulMat4(G.vd->persmat, G.vd->viewmat, curarea->winmat);
|
||||
|
||||
glSelectBuffer( MAXPICKBUF, (GLuint *)buffer);
|
||||
Mat4MulMat4(G.vd->persmat, G.vd->viewmat, sa->winmat);
|
||||
|
||||
glSelectBuffer( 32, buffer);
|
||||
glRenderMode(GL_SELECT);
|
||||
glInitNames(); /* these two calls whatfor? It doesnt work otherwise */
|
||||
glPushName(-1);
|
||||
|
||||
/* do the drawing */
|
||||
if(v3d->twmode==V3D_MANIPULATOR_TRANSLATE)
|
||||
if(v3d->twtype & V3D_MANIPULATOR_ROTATE)
|
||||
draw_manipulator_rotate(v3d->twmat);
|
||||
if(v3d->twtype & V3D_MANIPULATOR_SCALE)
|
||||
draw_manipulator_scale(v3d->twmat);
|
||||
if(v3d->twtype & V3D_MANIPULATOR_TRANSLATE)
|
||||
draw_manipulator_translate(v3d->twmat);
|
||||
|
||||
|
||||
glPopName(); /* see above (pushname) */
|
||||
hits= glRenderMode(GL_RENDER);
|
||||
|
||||
G.f &= ~G_PICKSEL;
|
||||
setwinmatrixview3d(0);
|
||||
Mat4MulMat4(G.vd->persmat, G.vd->viewmat, curarea->winmat);
|
||||
Mat4MulMat4(G.vd->persmat, G.vd->viewmat, sa->winmat);
|
||||
|
||||
persp(PERSP_WIN);
|
||||
|
||||
if(hits>0) {
|
||||
if(hits==1) return buffer[3];
|
||||
else if(hits>1) {
|
||||
/* we compare the two first in buffer, but exclude centers */
|
||||
|
||||
if(buffer[3]==MAN_TRANS_C || buffer[3]==MAN_SCALE_C);
|
||||
else if(buffer[4+3]==MAN_TRANS_C || buffer[4+3]==MAN_SCALE_C);
|
||||
else {
|
||||
if(buffer[4+1] < buffer[1]) return buffer[4+3];
|
||||
}
|
||||
return buffer[3];
|
||||
}
|
||||
return 0;
|
||||
@ -543,8 +778,14 @@ int BIF_do_manipulator(ScrArea *sa)
|
||||
if(!(v3d->twflag & V3D_USE_MANIPULATOR)) return 0;
|
||||
if(!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return 0;
|
||||
|
||||
// find the hotspots (Gval is for draw)
|
||||
Gval=val= manipulator_selectbuf(sa);
|
||||
// find the hotspots (Gval is for draw). first test narrow hotspot
|
||||
// warning, Gval is ugly global defining how it draws, don't set it before doing select calls!
|
||||
val= manipulator_selectbuf(sa, 7.0);
|
||||
if(val) {
|
||||
Gval= manipulator_selectbuf(sa, 3.0);
|
||||
if(Gval) val= Gval;
|
||||
else Gval= val;
|
||||
}
|
||||
|
||||
switch(val) {
|
||||
case MAN_TRANS_C:
|
||||
@ -577,6 +818,56 @@ int BIF_do_manipulator(ScrArea *sa)
|
||||
BIF_setSingleAxisConstraint(v3d->twmat[2]);
|
||||
ManipulatorTransform(TFM_TRANSLATION);
|
||||
break;
|
||||
|
||||
case MAN_SCALE_C:
|
||||
ManipulatorTransform(TFM_RESIZE);
|
||||
break;
|
||||
case MAN_SCALE_X:
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
Gval= MAN_SCALE_Y|MAN_SCALE_Z;
|
||||
BIF_setDualAxisConstraint(v3d->twmat[1], v3d->twmat[2]);
|
||||
}
|
||||
else
|
||||
BIF_setSingleAxisConstraint(v3d->twmat[0]);
|
||||
ManipulatorTransform(TFM_RESIZE);
|
||||
break;
|
||||
case MAN_SCALE_Y:
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
Gval= MAN_SCALE_X|MAN_SCALE_Z;
|
||||
BIF_setDualAxisConstraint(v3d->twmat[0], v3d->twmat[2]);
|
||||
}
|
||||
else
|
||||
BIF_setSingleAxisConstraint(v3d->twmat[1]);
|
||||
ManipulatorTransform(TFM_RESIZE);
|
||||
break;
|
||||
case MAN_SCALE_Z:
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
Gval= MAN_SCALE_X|MAN_SCALE_Y;
|
||||
BIF_setDualAxisConstraint(v3d->twmat[0], v3d->twmat[1]);
|
||||
}
|
||||
else
|
||||
BIF_setSingleAxisConstraint(v3d->twmat[2]);
|
||||
ManipulatorTransform(TFM_RESIZE);
|
||||
break;
|
||||
|
||||
case MAN_ROT_X:
|
||||
BIF_setSingleAxisConstraint(v3d->twmat[0]);
|
||||
ManipulatorTransform(TFM_ROTATION);
|
||||
break;
|
||||
case MAN_ROT_Y:
|
||||
BIF_setSingleAxisConstraint(v3d->twmat[1]);
|
||||
ManipulatorTransform(TFM_ROTATION);
|
||||
break;
|
||||
case MAN_ROT_Z:
|
||||
BIF_setSingleAxisConstraint(v3d->twmat[2]);
|
||||
ManipulatorTransform(TFM_ROTATION);
|
||||
break;
|
||||
case MAN_ROT_T:
|
||||
ManipulatorTransform(TFM_TRACKBALL);
|
||||
break;
|
||||
case MAN_ROT_V:
|
||||
ManipulatorTransform(TFM_ROTATION);
|
||||
break;
|
||||
}
|
||||
|
||||
Gval= 0xFFFF;
|
||||
|
Loading…
Reference in New Issue
Block a user