[Bf-committers] NDOF - viewmoveNDOF patch

Shaul Kedem shaul.kedem at gmail.com
Sat Jul 21 17:36:34 CEST 2007


Hi,
 posting it here may work, but it may not, I suggest talking to
someone with check-in priviliges in irc, letting them review it and
then check it in,

 don't assume that if the patch is here it will get in, however, since
this is ndof and you directly wrote this to Luc, the chances are good.

regards,
shaul


On 7/20/07, sfogoros <sfogoros at att.net> wrote:
> Luc,
>
> Here is a new view.c:viewmoveNDOF() function for ndof branch. I created
> the patch against branch revision 11311 updated on July 18, 2007.
>
> I hacked the G.vd->dist corrections as a temporary fix. I allows using
> the spacenav and mouse without severe problems with the view jumping and
> maintains the mouse view rotate center point.
>
> I still have a problem with the mouse wheel zoom becoming non-functional
> after using the spacenav. Using the mouse restores the mouse wheel.
>
> This is the first patch I've created and I'm not sure if posting it here
> is all I need to do. I have attached it to this email in addition to
> copying it as follows:
>
>
> Index: source/blender/src/ghostwinlay.c
> ===================================================================
> --- source/blender/src/ghostwinlay.c    (revision 11322)
> +++ source/blender/src/ghostwinlay.c    (working copy)
> @@ -561,13 +561,13 @@
>
>                        // the multipliers are arbitrary values
>                        // they could be ajustable in the future
> -            win->ndof[0] = sb->tx  * (1.0f/1024.0f);
> -            win->ndof[1] = sb->ty  * (1.0f/1024.0f);
> -            win->ndof[2] = sb->tz  * (1.0f/1024.0f);
> -            win->ndof[3] = sb->rx  * 0.00003f;
> -            win->ndof[4] = sb->ry  * 0.00003f;
> -            win->ndof[5] = sb->rz  * 0.00003f;
> -            win->ndof[6] = sb->delta  / 1000000.0f;
> +            win->ndof[0] = sb->tx; // * (1.0f/1024.0f);
> +            win->ndof[1] = sb->ty; // * (1.0f/1024.0f);
> +            win->ndof[2] = sb->tz; // * (1.0f/1024.0f);
> +            win->ndof[3] = sb->rx; // * 0.00003f;
> +            win->ndof[4] = sb->ry; // * 0.00003f;
> +            win->ndof[5] = sb->rz; // * 0.00003f;
> +            win->ndof[6] = sb->delta; // / 1000000.0f;
>   //           printf(" motion capted %f %f %f %f %f %f %f \n",
> win->ndof[0], win->ndof[1], win->ndof[2],
>   //                                                            win->ndof[3], win->ndof[4], win->ndof[5],
> win->ndof[6]);
>
> Index: source/blender/src/view.c
> ===================================================================
> --- source/blender/src/view.c   (revision 11322)
> +++ source/blender/src/view.c   (working copy)
> @@ -532,6 +532,179 @@
>
>  }
>
> +
> +// ndof scaling will be moved to user setting.
> +// In the mean time this is just a place holder.
> +
> +// Note: scaling in the plugin and ghostwinlay.c
> +// should be removed. With driver default setting,
> +// each axis returns approx. +-200 max deflection.
> +
> +// The values I selected are based on the older
> +// polling i/f. With event i/f, the sensistivity
> +// can be increased for improved response from
> +// small deflections of the device input.
> +
> +float ndof_axis_scale[6] = {
> +2.0,   // Tx
> +2.0,   // Tz
> +2.0,   // Ty
> +0.25,  // Rx
> +0.25,  // Rz
> +0.25   // Ry
> +};
> +
> +// statics for controlling G.vd->dist corrections.
> +// viewmoveNDOF zeros and adjusts G.vd->ofs.
> +// viewmove restores based on dz_flag state.
> +
> +int dz_flag = 0;
> +float m_dist;
> +
> +void getndof(float *sbval);
> +
> +void viewmoveNDOF(int mode)
> +{
> +    int i;
> +    float phi;
> +    float dval[7];
> +       // static fval[6] for low pass filter; device input vector is dval[6]
> +       static float fval[6];
> +    float tvec[3],rvec[3];
> +    float q1[4];
> +       float mat[3][3];
> +       float upvec[3];
> +
> +
> +    /*----------------------------------------------------
> +        * sometimes this routine is called from headerbuttons
> +     * viewmove needs to refresh the screen
> +     */
> +       areawinset(curarea->win);
> +
> +
> +       // fetch the current state of the ndof device
> +
> +       getndof(dval);
> +
> +       //for(i=0;i<7;i++) printf("%f ",dval[i]);
> +       //printf("\n");
> +
> +
> +       // Scale input values
> +
> +       if(dval[6] == 0) return; // guard against divide by zero
> +
> +       for(i=0;i<6;i++) {
> +               dval[i] = dval[i] / dval[6]; // this should be moved to device specific
> +
> +               // user scaling
> +               dval[i] = dval[i] * ndof_axis_scale[i];
> +
> +               // non-linear scaling
> +               if(dval[i]<0.0f)
> +                       dval[i] = -1.0f * dval[i] * dval[i];
> +               else
> +                       dval[i] = dval[i] * dval[i];
> +       }
> +
> +
> +       // low pass filter with zero crossing reset
> +
> +       for(i=0;i<6;i++) {
> +               if((dval[i] * fval[i]) >= 0)
> +                       dval[i] = (fval[i] * 15 + dval[i]) / 16;
> +               else
> +                       fval[i] = 0;
> +       }
> +
> +
> +       // force perspective mode. This is a hack and is
> +       // incomplete. It doesn't actually effect the view
> +       // until the first draw and doesn't update the menu
> +       // to reflect persp mode.
> +
> +       G.vd->persp = 1;
> +
> +
> +       // Correct the distance jump if G.vd->dist != 0
> +
> +       // This is due to a side effect of the original
> +       // mouse view rotation code. The rotation point is
> +       // set a distance in front of the viewport to
> +       // make rotating with the mouse look better.
> +       // The distance effect is written at a low level
> +       // in the view management instead of the mouse
> +       // view function. This means that all other view
> +       // movement devices must subtract this from their
> +       // view transformations.
> +
> +       if(G.vd->dist != 0.0) {
> +               dz_flag = 1;
> +               m_dist = G.vd->dist;
> +               upvec[0] = upvec[1] = 0;
> +               upvec[2] = G.vd->dist;
> +               Mat3CpyMat4(mat, G.vd->viewinv);
> +               Mat3MulVecfl(mat, upvec);
> +               VecSubf(G.vd->ofs, G.vd->ofs, upvec);
> +               G.vd->dist = 0.0;
> +       }
> +
> +
> +       // Apply rotation
> +
> +       rvec[0] = -dval[3];
> +       rvec[1] = -dval[4];
> +       rvec[2] = dval[5];
> +
> +       // rotate device x and y by view z
> +
> +       Mat3CpyMat4(mat, G.vd->viewinv);
> +       mat[2][2] = 0.0f;
> +       Mat3MulVecfl(mat, rvec);
> +
> +       // rotate the view
> +
> +       phi = Normalize(rvec);
> +       if(phi != 0) {
> +               VecRotToQuat(rvec,phi,q1);
> +               QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
> +       }
> +
> +
> +       // Apply translation
> +
> +       tvec[0] = dval[0];
> +       tvec[1] = dval[1];
> +       tvec[2] = -dval[2];
> +
> +       // the next three lines rotate the x and y translation coordinates
> +       // by the current z axis angle
> +
> +       Mat3CpyMat4(mat, G.vd->viewinv);
> +       mat[2][2] = 0.0f;
> +       Mat3MulVecfl(mat, tvec);
> +
> +       // translate the view
> +
> +       VecSubf(G.vd->ofs, G.vd->ofs, tvec);
> +
> +
> +       /*----------------------------------------------------
> +     * refresh the screen
> +     */
> +
> +    scrarea_do_windraw(curarea);
> +    screen_swapbuffers();
> +
> +       // update render preview window
> +
> +       BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
> +}
> +
> +
> +
> +
>  void viewmove(int mode)
>  {
>        Object *ob = OBACT;
> @@ -543,12 +716,30 @@
>        short use_sel = 0;
>        short preview3d_event= 1;
>
> +       // locals for dist correction
> +       float mat[3][3];
> +       float upvec[3];
> +
>        /* 3D window may not be defined */
>        if( !G.vd ) {
>                fprintf( stderr, "G.vd == NULL in viewmove()\n" );
>                return;
>        }
>
> +
> +       // dist correction from other movement devices
> +
> +       if(dz_flag) {
> +               dz_flag = 0;
> +               G.vd->dist = m_dist;
> +               upvec[0] = upvec[1] = 0;
> +               upvec[2] = G.vd->dist;
> +               Mat3CpyMat4(mat, G.vd->viewinv);
> +               Mat3MulVecfl(mat, upvec);
> +               VecAddf(G.vd->ofs, G.vd->ofs, upvec);
> +       }
> +
> +
>        /* sometimes this routine is called from headerbuttons */
>
>        areawinset(curarea->win);
> @@ -805,7 +996,7 @@
>
>
>
> -void viewmoveNDOF(int mode)
> +void viewmoveNDOF_original(int mode)
>  {
>      static double prevTime = 0.0;
>
>
>
>
> Index: source/blender/src/ghostwinlay.c
> ===================================================================
> --- source/blender/src/ghostwinlay.c    (revision 11322)
> +++ source/blender/src/ghostwinlay.c    (working copy)
> @@ -561,13 +561,13 @@
>
>                        // the multipliers are arbitrary values
>                        // they could be ajustable in the future
> -            win->ndof[0] = sb->tx  * (1.0f/1024.0f);
> -            win->ndof[1] = sb->ty  * (1.0f/1024.0f);
> -            win->ndof[2] = sb->tz  * (1.0f/1024.0f);
> -            win->ndof[3] = sb->rx  * 0.00003f;
> -            win->ndof[4] = sb->ry  * 0.00003f;
> -            win->ndof[5] = sb->rz  * 0.00003f;
> -            win->ndof[6] = sb->delta  / 1000000.0f;
> +            win->ndof[0] = sb->tx; // * (1.0f/1024.0f);
> +            win->ndof[1] = sb->ty; // * (1.0f/1024.0f);
> +            win->ndof[2] = sb->tz; // * (1.0f/1024.0f);
> +            win->ndof[3] = sb->rx; // * 0.00003f;
> +            win->ndof[4] = sb->ry; // * 0.00003f;
> +            win->ndof[5] = sb->rz; // * 0.00003f;
> +            win->ndof[6] = sb->delta; // / 1000000.0f;
>  //            printf(" motion capted %f %f %f %f %f %f %f \n", win->ndof[0], win->ndof[1], win->ndof[2],
>  //                                                             win->ndof[3], win->ndof[4], win->ndof[5], win->ndof[6]);
>
> Index: source/blender/src/view.c
> ===================================================================
> --- source/blender/src/view.c   (revision 11322)
> +++ source/blender/src/view.c   (working copy)
> @@ -532,6 +532,179 @@
>
>  }
>
> +
> +// ndof scaling will be moved to user setting.
> +// In the mean time this is just a place holder.
> +
> +// Note: scaling in the plugin and ghostwinlay.c
> +// should be removed. With driver default setting,
> +// each axis returns approx. +-200 max deflection.
> +
> +// The values I selected are based on the older
> +// polling i/f. With event i/f, the sensistivity
> +// can be increased for improved response from
> +// small deflections of the device input.
> +
> +float ndof_axis_scale[6] = {
> +2.0,   // Tx
> +2.0,   // Tz
> +2.0,   // Ty
> +0.25,  // Rx
> +0.25,  // Rz
> +0.25   // Ry
> +};
> +
> +// statics for controlling G.vd->dist corrections.
> +// viewmoveNDOF zeros and adjusts G.vd->ofs.
> +// viewmove restores based on dz_flag state.
> +
> +int dz_flag = 0;
> +float m_dist;
> +
> +void getndof(float *sbval);
> +
> +void viewmoveNDOF(int mode)
> +{
> +    int i;
> +    float phi;
> +    float dval[7];
> +       // static fval[6] for low pass filter; device input vector is dval[6]
> +       static float fval[6];
> +    float tvec[3],rvec[3];
> +    float q1[4];
> +       float mat[3][3];
> +       float upvec[3];
> +
> +
> +    /*----------------------------------------------------
> +        * sometimes this routine is called from headerbuttons
> +     * viewmove needs to refresh the screen
> +     */
> +       areawinset(curarea->win);
> +
> +
> +       // fetch the current state of the ndof device
> +
> +       getndof(dval);
> +
> +       //for(i=0;i<7;i++) printf("%f ",dval[i]);
> +       //printf("\n");
> +
> +
> +       // Scale input values
> +
> +       if(dval[6] == 0) return; // guard against divide by zero
> +
> +       for(i=0;i<6;i++) {
> +               dval[i] = dval[i] / dval[6]; // this should be moved to device specific
> +
> +               // user scaling
> +               dval[i] = dval[i] * ndof_axis_scale[i];
> +
> +               // non-linear scaling
> +               if(dval[i]<0.0f)
> +                       dval[i] = -1.0f * dval[i] * dval[i];
> +               else
> +                       dval[i] = dval[i] * dval[i];
> +       }
> +
> +
> +       // low pass filter with zero crossing reset
> +
> +       for(i=0;i<6;i++) {
> +               if((dval[i] * fval[i]) >= 0)
> +                       dval[i] = (fval[i] * 15 + dval[i]) / 16;
> +               else
> +                       fval[i] = 0;
> +       }
> +
> +
> +       // force perspective mode. This is a hack and is
> +       // incomplete. It doesn't actually effect the view
> +       // until the first draw and doesn't update the menu
> +       // to reflect persp mode.
> +
> +       G.vd->persp = 1;
> +
> +
> +       // Correct the distance jump if G.vd->dist != 0
> +
> +       // This is due to a side effect of the original
> +       // mouse view rotation code. The rotation point is
> +       // set a distance in front of the viewport to
> +       // make rotating with the mouse look better.
> +       // The distance effect is written at a low level
> +       // in the view management instead of the mouse
> +       // view function. This means that all other view
> +       // movement devices must subtract this from their
> +       // view transformations.
> +
> +       if(G.vd->dist != 0.0) {
> +               dz_flag = 1;
> +               m_dist = G.vd->dist;
> +               upvec[0] = upvec[1] = 0;
> +               upvec[2] = G.vd->dist;
> +               Mat3CpyMat4(mat, G.vd->viewinv);
> +               Mat3MulVecfl(mat, upvec);
> +               VecSubf(G.vd->ofs, G.vd->ofs, upvec);
> +               G.vd->dist = 0.0;
> +       }
> +
> +
> +       // Apply rotation
> +
> +       rvec[0] = -dval[3];
> +       rvec[1] = -dval[4];
> +       rvec[2] = dval[5];
> +
> +       // rotate device x and y by view z
> +
> +       Mat3CpyMat4(mat, G.vd->viewinv);
> +       mat[2][2] = 0.0f;
> +       Mat3MulVecfl(mat, rvec);
> +
> +       // rotate the view
> +
> +       phi = Normalize(rvec);
> +       if(phi != 0) {
> +               VecRotToQuat(rvec,phi,q1);
> +               QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
> +       }
> +
> +
> +       // Apply translation
> +
> +       tvec[0] = dval[0];
> +       tvec[1] = dval[1];
> +       tvec[2] = -dval[2];
> +
> +       // the next three lines rotate the x and y translation coordinates
> +       // by the current z axis angle
> +
> +       Mat3CpyMat4(mat, G.vd->viewinv);
> +       mat[2][2] = 0.0f;
> +       Mat3MulVecfl(mat, tvec);
> +
> +       // translate the view
> +
> +       VecSubf(G.vd->ofs, G.vd->ofs, tvec);
> +
> +
> +       /*----------------------------------------------------
> +     * refresh the screen
> +     */
> +
> +    scrarea_do_windraw(curarea);
> +    screen_swapbuffers();
> +
> +       // update render preview window
> +
> +       BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
> +}
> +
> +
> +
> +
>  void viewmove(int mode)
>  {
>        Object *ob = OBACT;
> @@ -543,12 +716,30 @@
>        short use_sel = 0;
>        short preview3d_event= 1;
>
> +       // locals for dist correction
> +       float mat[3][3];
> +       float upvec[3];
> +
>        /* 3D window may not be defined */
>        if( !G.vd ) {
>                fprintf( stderr, "G.vd == NULL in viewmove()\n" );
>                return;
>        }
>
> +
> +       // dist correction from other movement devices
> +
> +       if(dz_flag) {
> +               dz_flag = 0;
> +               G.vd->dist = m_dist;
> +               upvec[0] = upvec[1] = 0;
> +               upvec[2] = G.vd->dist;
> +               Mat3CpyMat4(mat, G.vd->viewinv);
> +               Mat3MulVecfl(mat, upvec);
> +               VecAddf(G.vd->ofs, G.vd->ofs, upvec);
> +       }
> +
> +
>        /* sometimes this routine is called from headerbuttons */
>
>        areawinset(curarea->win);
> @@ -805,7 +996,7 @@
>
>
>
> -void viewmoveNDOF(int mode)
> +void viewmoveNDOF_original(int mode)
>  {
>     static double prevTime = 0.0;
>
>
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers
>
>


More information about the Bf-committers mailing list