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/blenloader/intern/readfile.c14
-rw-r--r--source/blender/include/BDR_drawobject.h1
-rwxr-xr-xsource/blender/include/BIF_transform.h3
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h8
-rw-r--r--source/blender/src/drawobject.c10
-rw-r--r--source/blender/src/editscreen.c7
-rw-r--r--source/blender/src/space.c65
-rwxr-xr-xsource/blender/src/transform.c205
-rwxr-xr-xsource/blender/src/transform.h6
-rwxr-xr-xsource/blender/src/transform_constraints.c8
-rwxr-xr-xsource/blender/src/transform_generics.c28
-rw-r--r--source/blender/src/transform_manipulator.c339
12 files changed, 621 insertions, 73 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 68bd3946e55..dcf7658ab97 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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! */
diff --git a/source/blender/include/BDR_drawobject.h b/source/blender/include/BDR_drawobject.h
index a6084081336..10b6dc11c5c 100644
--- a/source/blender/include/BDR_drawobject.h
+++ b/source/blender/include/BDR_drawobject.h
@@ -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
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index 7846e4d315d..d6f1db700c9 100755
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -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
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 18e0fdf448d..19bee996a59 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -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
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 48cdd1c4763..05968be0c4d 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -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)
{
diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c
index 5c311b594ce..572e4114c5e 100644
--- a/source/blender/src/editscreen.c
+++ b/source/blender/src/editscreen.c
@@ -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) ) {
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index b7ed74a0213..70027f34f15 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -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:
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index d0ac0c95d31..a243dd81b68 100755
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -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,8 +2366,167 @@ 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;
}
diff --git a/source/blender/src/transform.h b/source/blender/src/transform.h
index 5209ec0e519..d10c066f547 100755
--- a/source/blender/src/transform.h
+++ b/source/blender/src/transform.h
@@ -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
diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c
index 54bf3dc71fe..d3c5f12260a 100755
--- a/source/blender/src/transform_constraints.c
+++ b/source/blender/src/transform_constraints.c
@@ -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);
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index 0df1044940c..e4872f7d651 100755
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -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 */
diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c
index 98768fc8a45..b91ef64cef8 100644
--- a/source/blender/src/transform_manipulator.c
+++ b/source/blender/src/transform_manipulator.c
@@ -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;