00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00083 if(!target(TARGET_GRAB, rotatecenter, 0)) {
00084 constrained = -1;
00085 return;
00086 }
00087
00088
00089 rotateradius = distance(Tool::position(), rotatecenter);
00090
00091
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
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
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
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
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
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
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
00148
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