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 Tue Nov 18 02:47:51 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /