Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

P_RotateTool.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: P_RotateTool.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.46 $       $Date: 2019/01/17 21:21:01 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  * This is Paul's new Tracker code -- pgrayson@ks.uiuc.edu
00019  *
00020  *
00021  ***************************************************************************/
00022 
00023 #ifdef VMDVRPN
00024 
00025 #include <math.h>
00026 
00027 #include "Matrix4.h"
00028 #include "quat.h"
00029 #include "utilities.h"
00030 #include "Displayable.h"
00031 #include "Command.h"
00032 #include "UIObject.h"
00033 #include "JString.h"
00034 
00035 #include "P_Buttons.h"
00036 #include "P_Feedback.h"
00037 #include "P_Tracker.h"
00038 #include "P_Tool.h"
00039 #include "P_RotateTool.h"
00040 #include "P_UIVR.h"
00041 
00042 int RotateTool::isgrabbing() {
00043   if(grab_toggle && constrained != -1) return 1;
00044   else return 0;
00045 }
00046 
00047 RotateTool::RotateTool(int id, VMDApp *vmdapp, Displayable *disp) 
00048 : Tool(id,vmdapp, disp) {
00049   grab_toggle = 0;
00050   button_was_down = 0;
00051   constrained = 0;
00052 }
00053 
00054 void RotateTool::do_event() {
00055   int i,j;
00056   float newpos[3], point[3], normal[3], cpoint[3];
00057   q_vec_type qpoint, qnormal, last_qpoint;
00058   q_type rot;
00059   q_matrix_type qmat;
00060   Matrix4 mat;
00061 
00062   if(!wasgrabbing && isgrabbing()) {
00063     target(TARGET_GRAB, newpos, 0);
00064   }
00065   wasgrabbing = isgrabbing();
00066 
00067   if (orientation() == NULL) {
00068     return;
00069   }
00070 
00071   if(button_was_down && !Tool::isgrabbing()) {
00072     grab_toggle = !grab_toggle;
00073     button_was_down = 0;
00074   }
00075   else if(!button_was_down && Tool::isgrabbing()) {
00076     button_was_down = 1;
00077   }
00078 
00079   if(!constrained && (Tool::isgrabbing() || grab_toggle)) {
00080     q_make(qoffset,1,0,0,0);
00081 
00082     // get the center of rotation
00083     if(!target(TARGET_GRAB, rotatecenter, 0)) {
00084       constrained = -1;
00085       return;
00086     }
00087 
00088     // compute the radius of rotation
00089     rotateradius = distance(Tool::position(), rotatecenter);
00090 
00091     // record the current position, direction and normal to the sphere
00092     for(i=0;i<dimension();i++) {
00093       old_pos[i] = Tool::position()[i];
00094       old_normal[i] = old_pos[i]/rotateradius;
00095       qpoint[i] = (double)orientation()->mat[4*0+i];
00096       qnormal[i] = -(double)old_normal[i];
00097     }
00098 
00099     // set up the starting position
00100     for(i=0;i<4;i++) for(j=0;j<4;j++) 
00101      start.mat[4*i+j] = orientation()->mat[4*i+j];
00102 
00103     // and rotate it to be normal, just for show
00104     q_from_two_vecs(rot,qpoint,qnormal);
00105     q_to_row_matrix(qmat,rot);
00106     for(i=0;i<4;i++) for(j=0;j<4;j++) mat.mat[4*i+j]=(float) qmat[i][j];
00107     mat.multmatrix(start);
00108     start=mat;
00109 
00110     // set this flag last so it doesn't affect orientation computations
00111     constrained=1;
00112   }
00113   else if(constrained && !(Tool::isgrabbing() || grab_toggle)){
00114     let_go();
00115     constrained=0;
00116     forceoff();
00117   }
00118 
00119   if(constrained == 1) {
00120     float dist;
00121     // set up the position we are reporting
00122     dist = distance(Tool::position(),rotatecenter) / rotateradius;
00123     for(i=0;i<dimension();i++) {
00124       constrainedpos[i] = rotatecenter[i] +
00125         (Tool::position()[i] - rotatecenter[i])/dist;
00126     }
00127 
00128     // constrain the position to a plane
00129     vec_sub(normal,Tool::position(),rotatecenter);
00130     vec_normalize(normal);
00131     vec_scale(cpoint,rotateradius,normal);
00132     vec_add(point,rotatecenter,cpoint);
00133     setplaneconstraint(100,point,normal);
00134     
00135     // now add detentes (!)
00136     for(i=0;i<3;i++) {
00137       dist = (constrainedpos[i] - rotatecenter[i])/rotateradius;
00138       if(dist < 0.1 && dist > -0.1) {
00139         float normal[3]={0,0,0};
00140         normal[i]=1;
00141         addplaneconstraint(100,rotatecenter,normal);      
00142       }
00143     }
00144 
00145     sendforce();
00146 
00147     // compute the difference between the old normal and the new;
00148     // rotate the offset matrix by this amount.
00149     for(i=0;i<dimension();i++) {
00150       qpoint[i] = normal[i];
00151       last_qpoint[i] = old_normal[i];
00152       old_normal[i] = normal[i];
00153     }
00154     q_from_two_vecs(rot,last_qpoint,qpoint);
00155     q_mult(qoffset,rot,qoffset);
00156     q_to_row_matrix(qmat,qoffset);
00157     for(i=0;i<4;i++) {
00158       for(j=0;j<4;j++) {
00159         mat.mat[4*i+j]=(float) qmat[i][j];
00160       }
00161     }
00162     offset = mat;
00163   }
00164 }
00165 
00166 const float *RotateTool::position() const {
00167   const float *newpos = Tool::position();
00168   if(constrained != 1) return newpos;
00169   return constrainedpos;
00170 }
00171 
00172 const Matrix4 *RotateTool::orientation() {
00173   if(constrained != 1) {
00174     return Tool::orientation();
00175   }
00176   product = offset;
00177   product.multmatrix(start);
00178   return &product;
00179 }
00180 
00181 #endif

Generated on Thu Apr 25 02:43:21 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002