diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/include/BSE_view.h | 1 | ||||
-rw-r--r-- | source/blender/include/mydevice.h | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_userdef_types.h | 4 | ||||
-rw-r--r-- | source/blender/src/editscreen.c | 7 | ||||
-rw-r--r-- | source/blender/src/ghostwinlay.c | 67 | ||||
-rw-r--r-- | source/blender/src/space.c | 20 | ||||
-rwxr-xr-x | source/blender/src/transform.c | 6 | ||||
-rw-r--r-- | source/blender/src/usiblender.c | 7 | ||||
-rw-r--r-- | source/blender/src/view.c | 164 | ||||
-rw-r--r-- | source/blender/src/winlay.h | 2 |
10 files changed, 278 insertions, 3 deletions
diff --git a/source/blender/include/BSE_view.h b/source/blender/include/BSE_view.h index 91f360338e9..d625cbab595 100644 --- a/source/blender/include/BSE_view.h +++ b/source/blender/include/BSE_view.h @@ -76,6 +76,7 @@ void sdrawbox(short x1, short y1, short x2, short y2); void calctrackballvecfirst(struct rcti *area, short *mval, float *vec); void calctrackballvec(struct rcti *area, short *mval, float *vec); void viewmove(int mode); +void viewmoveNDOF(int mode); int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize); void setwinmatrixview3d(int winx, int winy, struct rctf *rect); diff --git a/source/blender/include/mydevice.h b/source/blender/include/mydevice.h index 113b281a017..af20c093a16 100644 --- a/source/blender/include/mydevice.h +++ b/source/blender/include/mydevice.h @@ -70,6 +70,9 @@ #define WINQUIT 0x018 /* signal from user that app is to go away */ #define Q_FIRSTTIME 0x019 /* on startup */ +/* N-degre of freedom device : 500 */ +#define NDOFMOTION 500 + /* standard keyboard */ #define AKEY 'a' diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 27c9bc16e4a..7567ab6921c 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -181,7 +181,9 @@ typedef struct UserDef { short recent_files; /* maximum number of recently used files to remember */ short smooth_viewtx; /* miliseconds to spend spinning the view */ short glreslimit; - char pad[4]; + short ndof_pan, ndof_rotate; +// short pads[4]; +// char pad[8]; } UserDef; extern UserDef U; /* from usiblender.c !!!! */ diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index c0fee24ba8a..6069ca16312 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -2163,6 +2163,12 @@ short get_activedevice(void) return window_get_activedevice(mainwin); } +short getndof(short *sbval) +{ + winlay_process_events(0); + return window_get_ndof(mainwin, sbval); +} + void add_to_mainqueue(Window *win, void *user_data, short evt, short val, char ascii) { @@ -2227,6 +2233,7 @@ static bScreen *addscreen(char *name) /* use setprefsize() if you want somethin } window_set_handler(mainwin, add_to_mainqueue, NULL); + window_open_ndof(mainwin); /* needs to occur once the mainwin handler is set */ init_mainwin(); mywinset(1); diff --git a/source/blender/src/ghostwinlay.c b/source/blender/src/ghostwinlay.c index 4a76d2d292f..9df293a0fda 100644 --- a/source/blender/src/ghostwinlay.c +++ b/source/blender/src/ghostwinlay.c @@ -55,11 +55,16 @@ #include "BIF_usiblender.h" #include "BIF_cursors.h" +#include "PIL_dynlib.h" + #include "mydevice.h" #include "blendef.h" #include "winlay.h" +#include <math.h> + + #ifdef __APPLE__ #include <OpenGL/OpenGL.h> #define __CARBONSOUND__ @@ -107,6 +112,12 @@ struct _Window { */ int faked_mbut; + /* Last known ndof device state + * note that the ghost device manager + * can handle any number of devices, but ghostwinlay can't + */ + float ndof[7]; /* tx, ty, tz, rx, ry, rz, dt */ + GHOST_TimerTaskHandle timer; int timer_event; }; @@ -334,6 +345,7 @@ Window *window_open(char *title, int posx, int posy, int sizex, int sizey, int s GHOST_WindowHandle ghostwin; GHOST_TWindowState inital_state; int scr_w, scr_h; + int i; winlay_get_screensize(&scr_w, &scr_h); posy= (scr_h-posy-sizey); @@ -366,7 +378,10 @@ Window *window_open(char *title, int posx, int posy, int sizex, int sizey, int s win->lmouse[0]= win->size[0]/2; win->lmouse[1]= win->size[1]/2; - + + for (i = 0; i < 7; ++i) + win->ndof[i] = 0; + } else { GHOST_DisposeWindow(g_system, ghostwin); @@ -538,6 +553,31 @@ static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) } switch (type) { + + case GHOST_kEventNDOFMotion: { + // update ndof device data, and dispatch motion event + GHOST_TEventNDOFData *sb= data; + + win->ndof[0] = sb->tx; + win->ndof[1] = sb->ty; + win->ndof[2] = sb->tz; + win->ndof[3] = sb->rx; + win->ndof[4] = sb->ry; + win->ndof[5] = sb->rz; + win->ndof[6] = sb->dt; + + // start interaction for larger than teeny-tiny motions + if ((fabsf(sb->tx) > 0.03f) || + (fabsf(sb->ty) > 0.03f) || + (fabsf(sb->tz) > 0.03f) || + (fabsf(sb->rx) > 0.03f) || + (fabsf(sb->ry) > 0.03f) || + (fabsf(sb->rz) > 0.03f)) { + window_handle(win, NDOFMOTION, sb->dt * 255); + } + break; + } + case GHOST_kEventCursorMove: { if(win->active == 1) { GHOST_TEventCursorData *cd= data; @@ -705,6 +745,13 @@ static int event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) return 1; } +void window_get_ndof(Window* win, float* sbval) { + int i; + for (i = 0; i < 7; ++i) { + *sbval++ = win->ndof[i]; + } +} + char *window_get_title(Window *win) { char *title= GHOST_GetTitle(win->ghostwin); char *mem_title= BLI_strdup(title); @@ -831,3 +878,21 @@ void winlay_get_screensize(int *width_r, int *height_r) { Window *winlay_get_active_window(void) { return active_gl_window; } + +void window_open_ndof(Window* win) +{ + PILdynlib* ndofLib = PIL_dynlib_open("NDOFPlugin.plug"); + printf("passing here \n"); + if (ndofLib) { + printf("and here \n"); + + GHOST_OpenNDOF(g_system, win->ghostwin, + PIL_dynlib_find_symbol(ndofLib, "ndofInit"), + PIL_dynlib_find_symbol(ndofLib, "ndofShutdown"), + PIL_dynlib_find_symbol(ndofLib, "ndofOpen"), + PIL_dynlib_find_symbol(ndofLib, "ndofEventHandler")); + } + else { + GHOST_OpenNDOF(g_system, win->ghostwin, 0, 0, 0, 0); + } + } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index a528fd260ff..c5a485b67cf 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -1566,6 +1566,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) doredraw= 1; break; + case NDOFMOTION: + viewmoveNDOF(0); + break; + case ONEKEY: if(G.qual==LR_CTRLKEY) { flip_subdivison(1); @@ -3330,7 +3334,9 @@ void drawinfospace(ScrArea *sa, void *spacedata) (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y2,(mpref/2),buth, &(U.uiflag), 0, 0, 0, 0, "Use selection as the orbiting center"); - uiBlockEndAlign(block); + + uiBlockEndAlign(block); + uiBlockBeginAlign(block); @@ -3442,6 +3448,18 @@ void drawinfospace(ScrArea *sa, void *spacedata) &(U.obcenter_dia), 4, 10, 0, 0, "Diameter in Pixels for Object/Lamp center display"); + uiDefBut(block, LABEL,0,"6DOF devices speeds :", + (xpos+edgsp+(5*mpref)+(6*midsp)),y2label,mpref,buth, + 0, 0, 0, 0, 0, ""); + //FIXME NDOF BAD ETIQUETTES + uiDefButS(block, NUM, USER_AUTOPERSP, "ndPan", + (xpos+edgsp+(5*mpref)+(6*midsp)),y1,(mpref/2),buth, + &(U.ndof_pan), 0, 200, 0, 0, + "The overall panning speed of an NDOF device, as percent of standard"); + uiDefButS(block, NUM, USER_ORBIT_SELECTION, "ndRot", + (xpos+edgsp+(5*mpref)+(6*midsp)+(mpref/2)),y1,(mpref/2),buth, + &(U.ndof_rotate), 0, 200, 0, 0, + "The overall rotation speed of an NDOF device, as percent of standard"); } else if (U.userpref == 1) { /* edit methods */ diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 2769f19f9bb..e2819cc3693 100755 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -726,6 +726,9 @@ static void transformEvent(unsigned short event, short val) { else view_editmove(event); Trans.redraw= 1; break; + case NDOFMOTION: + viewmoveNDOF(0); + break; } Trans.redraw |= handleNumInput(&(Trans.num), event); Trans.redraw |= handleSnapping(&Trans, event); @@ -1072,6 +1075,9 @@ void ManipulatorTransform() case RETKEY: Trans.state = TRANS_CONFIRM; break; + case NDOFMOTION: + viewmoveNDOF(0); + break; } if(val) { switch(event) { diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 10fcfeb45aa..020eb502765 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -190,6 +190,13 @@ static void init_userdef_file(void) if(U.pad_rot_angle==0) U.pad_rot_angle= 15; + if (U.ndof_pan==0) { + U.ndof_pan = 100; + } + if (U.ndof_rotate==0) { + U.ndof_rotate = 100; + } + if (G.main->versionfile <= 191) { strcpy(U.plugtexdir, U.textudir); strcpy(U.sounddir, "/"); diff --git a/source/blender/src/view.c b/source/blender/src/view.c index c501dbb8f73..e26b4526ebe 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -88,6 +88,7 @@ #include "blendef.h" #include "PIL_time.h" /* smoothview */ +#include <float.h> #define TRACKBALLSIZE (1.1) #define BL_NEAR_CLIP 0.001 @@ -800,6 +801,169 @@ void viewmove(int mode) } + + + + +void viewmoveNDOF(int mode) +{ + static double prevTime = 0.0; + + int i; + float fval[7]; + float dvec[3]; + float sbadjust = 1.0f; + float len; + double now, frametime; + short use_sel = 0; + Object *ob = OBACT; + float m[3][3]; + float m_inv[3][3]; + float xvec[3] = {1,0,0}; + float phi, si; + float q1[4]; + float obofs[3]; + float reverse; + float diff[4]; + float d, curareaX, curareaY; + + /* Sensitivity will control how fast the view rotates. The value was + * obtained experimentally by tweaking until the author didn't get dizzy watching. + * Perhaps this should be a configurable user parameter. + */ + float psens = 0.005f * (float) U.ndof_pan; /* pan sensitivity */ + const float rsens = 0.005f * (float) U.ndof_rotate; /* rotate sensitivity */ + const float zsens = 0.1f; /* zoom sensitivity */ + + const float minZoom = -30.0f; + const float maxZoom = 300.0f; + + if (G.obedit==NULL && ob && !(ob->flag & OB_POSEMODE)) { + use_sel = 1; + } + + /*---------------------------------------------------- + * sometimes this routine is called from headerbuttons + * viewmove needs to refresh the screen + */ + areawinset(curarea->win); + + /*---------------------------------------------------- + * record how much time has passed. clamp at 10 Hz + * pretend the previous frame occured at the clamped time + */ + now = PIL_check_seconds_timer(); + frametime = (now - prevTime); + if (frametime > 0.1f){ /* if more than 1/10s */ + frametime = 1.0f/60.0; /* clamp at 1/60s so no jumps when starting to move */ + } + prevTime = now; + sbadjust *= 60 * frametime; /* normalize ndof device adjustments to 100Hz for framerate independence */ + + /* fetch the current state of the ndof device */ + getndof(fval); + + /* set object offset */ + if (ob) { + obofs[0] = -ob->obmat[3][0]; + obofs[1] = -ob->obmat[3][1]; + obofs[2] = -ob->obmat[3][2]; + } + else { + VECCOPY(obofs, G.vd->ofs); + } + + /* calc an adjustment based on distance from camera */ + if (ob) { + VecSubf(diff, obofs, G.vd->ofs); + d = VecLength(diff); + } + else { + d = 1.0f; + } + reverse = (G.vd->persmat[2][1] < 0.0f) ? -1.0f : 1.0f; + + /*---------------------------------------------------- + * ndof device pan + */ + psens *= 1.0f + d; + curareaX = sbadjust * psens * fval[0]; + curareaY = sbadjust * psens * fval[1]; + dvec[0] = curareaX * G.vd->persinv[0][0] + curareaY * G.vd->persinv[1][0]; + dvec[1] = curareaX * G.vd->persinv[0][1] + curareaY * G.vd->persinv[1][1]; + dvec[2] = curareaX * G.vd->persinv[0][2] + curareaY * G.vd->persinv[1][2]; + VecAddf(G.vd->ofs, G.vd->ofs, dvec); + + /*---------------------------------------------------- + * ndof device dolly + */ + len = zsens * sbadjust * fval[2]; + + if (G.vd->persp==2) { + if(G.vd->persp==2) { + G.vd->camzoom+= 10.0f * -len; + } + if (G.vd->camzoom < minZoom) G.vd->camzoom = minZoom; + else if (G.vd->camzoom > maxZoom) G.vd->camzoom = maxZoom; + } + else if ((G.vd->dist> 0.001*G.vd->grid) && (G.vd->dist<10.0*G.vd->far)) { + G.vd->dist*=(1.0 + len); + } + + + /*---------------------------------------------------- + * ndof device turntable + * derived from the turntable code in viewmove + */ + + /* Get the 3x3 matrix and its inverse from the quaternion */ + QuatToMat3(G.vd->viewquat, m); + Mat3Inv(m_inv,m); + + /* Determine the direction of the x vector (for rotating up and down) */ + /* This can likely be compuated directly from the quaternion. */ + Mat3MulVecfl(m_inv,xvec); + + /* Perform the up/down rotation */ + phi = sbadjust * rsens * /*0.5f * */ fval[3]; /* spin vertically half as fast as horizontally */ + si = sin(phi); + q1[0] = cos(phi); + q1[1] = si * xvec[0]; + q1[2] = si * xvec[1]; + q1[3] = si * xvec[2]; + QuatMul(G.vd->viewquat, G.vd->viewquat, q1); + + if (use_sel) { + QuatConj(q1); /* conj == inv for unit quat */ + VecSubf(G.vd->ofs, G.vd->ofs, obofs); + QuatMulVecf(q1, G.vd->ofs); + VecAddf(G.vd->ofs, G.vd->ofs, obofs); + } + + /* Perform the orbital rotation */ + phi = sbadjust * rsens * reverse * fval[4]; /* twist the knob, y axis */ + q1[0] = cos(phi); + q1[1] = q1[2] = 0.0; + q1[3] = sin(phi); + QuatMul(G.vd->viewquat, G.vd->viewquat, q1); + + if (use_sel) { + QuatConj(q1); + VecSubf(G.vd->ofs, G.vd->ofs, obofs); + QuatMulVecf(q1, G.vd->ofs); + VecAddf(G.vd->ofs, G.vd->ofs, obofs); + } + + /*---------------------------------------------------- + * refresh the screen + */ + scrarea_do_windraw(curarea); + screen_swapbuffers(); +} + + + + /* Gets the lens and clipping values from a camera of lamp type object */ void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend) { diff --git a/source/blender/src/winlay.h b/source/blender/src/winlay.h index 2fdc2c70ac3..1734c0e2867 100644 --- a/source/blender/src/winlay.h +++ b/source/blender/src/winlay.h @@ -79,6 +79,8 @@ void window_warp_pointer (Window *win, int x, int y); void window_queue_redraw (Window *win); +void window_open_ndof(Window* win); + /* Global windowing operations */ Window* winlay_get_active_window(void); |