diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h index 37f4b97ebb0..7846e4d315d 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 *********************** */ @@ -67,11 +67,19 @@ void Transform(int mode); struct TransInfo; +struct ScrArea; struct TransInfo * BIF_GetTransInfo(void); void BIF_setSingleAxisConstraint(float vec[3]); +void BIF_setDualAxisConstraint(float vec1[3], float vec2[3]); void BIF_drawConstraint(void); void BIF_drawPropCircle(void); +/* view3d manipulators */ +void ManipulatorTransform(int mode); + +int BIF_do_manipulator(struct ScrArea *sa); +void BIF_draw_manipulator(struct ScrArea *sa); + #endif diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 54b93a9dfbd..8d6fed13b88 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -254,9 +254,10 @@ typedef struct Scene { struct Group *group; float cursor[3]; + float twcent[3]; /* center for transform widget */ + float twmin[3], twmax[3]; /* boundbox of selection for transform widget */ unsigned int lay; short selectmode, pad; - int pad1; void *ed; struct Radio *radio; diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index f776d6df2fb..18e0fdf448d 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -106,6 +106,11 @@ typedef struct View3D { short gridlines, viewbut; short gridflag; short modeselect, menunr, texnr; + + /* transform widget info */ + short twtype, twmode, twflag, twpad; + float twmat[4][4]; + } View3D; /* View3D->flag */ @@ -142,5 +147,22 @@ 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->twmode */ +#define V3D_MANIPULATOR_GLOBAL 0 +#define V3D_MANIPULATOR_LOCAL 1 +#define V3D_MANIPULATOR_NORMAL 2 + +/* View3d->twflag */ + /* USE = user setting, DRAW = based on selection */ +#define V3D_USE_MANIPULATOR 1 +#define V3D_DRAW_MANIPULATOR 2 +#define V3D_CALC_MANIPULATOR 4 + + #endif diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index ffba9ccbea3..06d1930619d 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1624,7 +1624,7 @@ void do_material_tex(ShadeInput *shi) warpvec[2]= mtex->warpfac*texres.nor[2]; warpdone= 1; } - +#if 0 // rotate to global coords if(mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) { // hrms, for sphere/tube map this rotating doesn't work nice @@ -1639,9 +1639,9 @@ void do_material_tex(ShadeInput *shi) } } } +#endif } - /* mapping */ if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { float tcol[3]; diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 175b3566ab4..58f1f65b05f 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -1951,9 +1951,10 @@ void drawview3dspace(ScrArea *sa, void *spacedata) base= base->next; } - if(G.scene->radio) RAD_drawall(G.vd->drawtype>=OB_SOLID); + BIF_draw_manipulator(sa); + if(G.zbuf) { G.zbuf= FALSE; glDisable(GL_DEPTH_TEST); diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index d369888a074..4dc044da4a6 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -105,9 +105,6 @@ #include "BIF_editarmature.h" #endif -/* editmball.c */ -extern ListBase editelems; /* go away ! */ - /* from editobject */ extern void make_trans_verts(float *min, float *max, int mode); @@ -544,6 +541,8 @@ void count_object(Object *ob, int sel) } +/* countall does statistics */ +/* is called on most actions, like select/add/delete/layermove */ void countall() { /* extern Lattice *editLatt; in BKE_lattice.h*/ @@ -559,9 +558,7 @@ void countall() /* struct BodyPoint *bop; */ struct EditVert *eve; struct EditFace *efa; -#ifdef __NLA struct EditBone *ebo; -#endif int a; G.totvert= G.totvertsel= G.totfacesel= G.totface= G.totobj= @@ -585,7 +582,6 @@ void countall() efa= efa->next; } } -#ifdef __NLA else if (G.obedit->type==OB_ARMATURE){ for (ebo=G.edbo.first;ebo;ebo=ebo->next){ @@ -619,7 +615,6 @@ void countall() } } -#endif else if ELEM3(G.obedit->type, OB_CURVE, OB_SURF, OB_FONT) { nu= editNurb.first; while(nu) { @@ -647,6 +642,9 @@ void countall() } } else if(G.obedit->type==OB_MBALL) { + /* editmball.c */ + extern ListBase editelems; /* go away ! */ + ml= editelems.first; while(ml) { G.totvert++; diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index c8575105fec..b9f15575b24 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -3712,6 +3712,7 @@ void do_view3d_buttons(short event) break; case B_AROUND: handle_view3d_around(); // copies to other 3d windows + allqueue(REDRAWVIEW3D, 1); break; case B_SEL_VERT: @@ -3963,6 +3964,11 @@ void view3d_buttons(void) xco+= XIC+8; + uiDefIconButS(block, TOG|BIT|0, B_REDR, ICON_OBJECT, + xco,0,XIC,YIC, + &G.vd->twflag, 0, 0, 0, 0, "Use 3d transform widgets"); + + xco+= XIC+8; /* LAYERS */ if(G.vd->localview==0) { diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index 510619e0a8a..459b3bdd8e2 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -494,6 +494,7 @@ int std_libbuttons(uiBlock *block, short xco, short yco, static void do_update_for_newframe(int mute) { extern void audiostream_scrub(unsigned int frame); /* seqaudio.c */ + ScrArea *sa; allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWACTION,0); @@ -522,6 +523,16 @@ static void do_update_for_newframe(int mute) test_all_displists(); + /* manipulators like updates too */ + for(sa=G.curscreen->areabase.first; sa; sa=sa->next) { + if(sa->spacetype==SPACE_VIEW3D) { + View3D *v3d= sa->spacedata.first; + if(v3d->twflag & V3D_USE_MANIPULATOR) break; + else break; // for now + } + } + if(sa) countall(); // does manipulator centers + if ( (CFRA>1) && (!mute) && (G.scene->audio.flag & AUDIO_SCRUB)) audiostream_scrub( CFRA ); } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 42f081c55e4..b7ed74a0213 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -734,6 +734,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(event==UI_BUT_EVENT) do_butspace(val); // temporal, view3d deserves own queue? + /* we consider manupilator a button, defaulting to leftmouse */ + if(event==LEFTMOUSE) if(BIF_do_manipulator(sa)) return; + /* swap mouse buttons based on user preference */ if (U.flag & USER_LMOUSESELECT) { if (event==LEFTMOUSE) event = RIGHTMOUSE; diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index f5d9e6724f5..02ef5856c1c 100755 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -1564,6 +1564,134 @@ void Transform(int mode) scrarea_queue_headredraw(curarea); } +static void draw_nothing(TransInfo *t) {} + +void ManipulatorTransform(int mode) +{ + int ret_val = 0; + short pmval[2] = {0, 0}, mval[2], val; + unsigned short event; + + + /* stupid PET initialisation code */ + /* START */ + if (Trans.propsize == 0.0f) { + Trans.propsize = 1.0; + } + /* END */ + + initTransModeFlags(&Trans, mode); // modal settings in struct Trans + + initTrans(&Trans); // internal data, mouse, vectors + + createTransData(&Trans); // make TransData structs from selection + + 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; + + calculatePropRatio(&Trans); + calculateCenter(&Trans); + + switch (mode) { + case TFM_TRANSLATION: + initTranslation(&Trans); + break; + case TFM_ROTATION: + initRotation(&Trans); + break; + case TFM_RESIZE: + initResize(&Trans); + break; + } + + Trans.redraw = 1; + + while (ret_val == 0) { + + getmouseco_areawin(mval); + + if (mval[0] != pmval[0] || mval[1] != pmval[1]) { + Trans.redraw = 1; + } + if (Trans.redraw) { + pmval[0] = mval[0]; + pmval[1] = mval[1]; + + //selectConstraint(&Trans); needed? + if (Trans.transform) { + Trans.transform(&Trans, mval); + } + Trans.redraw = 0; + } + + /* essential for idling subloop */ + if( qtest()==0) PIL_sleep_ms(2); + + while( qtest() ) { + event= extern_qread(&val); + + switch (event){ + /* enforce redraw of transform when modifiers are used */ + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + Trans.redraw = 1; + break; + + case ESCKEY: + case RIGHTMOUSE: + ret_val = TRANS_CANCEL; + break; + case LEFTMOUSE: + case SPACEKEY: + case PADENTER: + case RETKEY: + ret_val = TRANS_CONFIRM; + break; + } + } + } + + if(ret_val == TRANS_CANCEL) { + restoreTransObjects(&Trans); + } + else { + BIF_undo_push("Transform"); + } + + /* free data, reset vars */ + postTrans(&Trans); + + /* mess from old transform, just for now (ton) */ + { + char cmode='g'; + + if(mode==TFM_RESIZE) cmode= 's'; + else if(mode==TFM_ROTATION) cmode= 'r'; + /* aftertrans does displists, ipos and action channels */ + /* 7 = keyflags, meaning do loc/rot/scale ipos. Not sure if I like the old method to detect what changed (ton) */ + special_aftertrans_update(cmode, 0, (short)(ret_val == TRANS_CANCEL), 7); + + if(G.obedit==NULL && G.obpose==NULL) + clear_trans_object_base_flags(); + } + + /* send events out for redraws */ + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSOBJECT, 0); + scrarea_queue_headredraw(curarea); +} + + + /* ************************** WRAP *************************** */ /* warp is done fully in view space */ @@ -2294,26 +2422,27 @@ static void applyTranslation(TransInfo *t, float vec[3]) { } } +/* uses t->vec to store actual translation in */ int Translation(TransInfo *t, short mval[2]) { - float vec[3], tvec[3]; + float tvec[3]; char str[200]; - window_to_3d(vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); + window_to_3d(t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); if (t->con.mode & CON_APPLY) { float pvec[3] = {0.0f, 0.0f, 0.0f}; - t->con.applyVec(t, NULL, vec, tvec, pvec); - VECCOPY(vec, tvec); + t->con.applyVec(t, NULL, t->vec, tvec, pvec); + VECCOPY(t->vec, tvec); headerTranslation(t, pvec, str); } else { - snapGrid(t, vec); - applyNumInput(&t->num, vec); - headerTranslation(t, vec, str); + snapGrid(t, t->vec); + applyNumInput(&t->num, t->vec); + headerTranslation(t, t->vec, str); } - applyTranslation(t, vec); + applyTranslation(t, t->vec); recalcData(t); diff --git a/source/blender/src/transform.h b/source/blender/src/transform.h index a4bcd206b01..5209ec0e519 100755 --- a/source/blender/src/transform.h +++ b/source/blender/src/transform.h @@ -125,6 +125,9 @@ typedef struct TransInfo { NumInput num; /* numerical input */ float val; /* init value for some transformations */ float fac; /* factor for distance based transform */ + + float vec[3]; /* translation, to show for widget */ + float mat[3][3]; /* rot/rescale, to show for widget */ } TransInfo; diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c index d665d8ae281..641a93a2d24 100755 --- a/source/blender/src/transform_constraints.c +++ b/source/blender/src/transform_constraints.c @@ -580,6 +580,7 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) { void BIF_setSingleAxisConstraint(float vec[3]) { TransInfo *t = BIF_GetTransInfo(); float space[3][3], v[3]; + VECCOPY(space[0], vec); v[0] = vec[2]; @@ -600,6 +601,26 @@ void BIF_setSingleAxisConstraint(float vec[3]) { t->redraw = 1; } +void BIF_setDualAxisConstraint(float vec1[3], float vec2[3]) { + TransInfo *t = BIF_GetTransInfo(); + float space[3][3]; + + VECCOPY(space[0], vec1); + VECCOPY(space[1], vec2); + Crossf(space[2], space[0], space[1]); + + Mat3CpyMat3(t->con.mtx, space); + t->con.mode = (CON_AXIS0|CON_AXIS1|CON_APPLY); + getConstraintMatrix(t); + + t->con.drawExtra = NULL; + t->con.applyVec = applyAxisConstraintVec; + t->con.applySize = applyAxisConstraintSize; + t->con.applyRot = applyAxisConstraintRot; + t->redraw = 1; +} + + void BIF_drawConstraint(void) { TransInfo *t = BIF_GetTransInfo(); diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 42751be6a99..d52a40761c8 100755 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -370,6 +370,12 @@ void initTrans (TransInfo *t) t->num.val[0] = t->num.val[1] = t->num.val[2] = 0.0f; + + t->vec[0] = + t->vec[1] = + t->vec[2] = 0.0f; + + Mat3One(t->mat); } /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */