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

PickModeMove.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: PickModeMove.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.24 $       $Date: 2019/01/17 21:21:01 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *  Pick mode for moving atoms (no forces applied)
00019  ***************************************************************************/
00020 
00021 #include <math.h>
00022 #include <string.h>
00023 #include "PickModeMove.h"
00024 #include "DrawMolecule.h"
00025 #include "utilities.h"
00026 #include "VMDQuat.h"
00027 #include "Mouse.h"
00028 #include "DisplayDevice.h"
00029 
00031 
00032 void PickModeMove::get_pointer_pos(DrawMolecule *m, DisplayDevice *d, 
00033                                    int moveAtom, const int *cell,
00034                                    int dim, const float *pos,
00035                                    float *retpos) {
00036 
00037   Timestep *ts = m->current();
00038   if(!(moveAtom < 0 || ts == NULL)) {
00039     // get the current pointer position in 3 space
00040     float atomPos[3];
00041     vec_copy(atomPos, ts->pos + moveAtom * 3L); 
00042     const float *newpos;
00043     float mouseObjPos[3];
00044     if(dim == 2) {
00045       float atomWorldPos[3];
00046 
00047       // Apply unit cell transform
00048       Matrix4 mat;
00049       ts->get_transform_from_cell(cell, mat);
00050       mat.multpoint3d(atomPos, atomPos);
00051 
00052       // convert the atom position to world coordinates
00053       (m->tm).multpoint3d(atomPos, atomWorldPos);
00054 
00055       // find the 3D position (in world coords) of the mouse
00056       d->find_3D_from_2D(atomWorldPos, pos, mouseObjPos);
00057 
00058       // indicate the mouse world pos is the position to convert back to
00059       // molecule object coordinates
00060       newpos = mouseObjPos;
00061 
00062     } else {
00063 
00064       // for 3D pointer, just use the pointer position as-is
00065       newpos = pos;
00066     }
00067     vec_copy(retpos, newpos);
00068   } 
00069 }
00070 
00071 void PickModeMove::pick_molecule_start(DrawMolecule *m, DisplayDevice *d, 
00072                                        int theBtn, int tag, const int *cell,
00073                                        int dim, const float *pos) {
00074 
00075   // convert the pointer position to world coordinates; store in lastPos
00076   memcpy(lastCell, cell, 3L*sizeof(int));
00077   get_pointer_pos(m, d, tag, cell, dim, pos, lastPos);
00078   btn = theBtn;
00079 }
00080 
00082 // compute the transformation matrix for a rotation with the mouse
00083 // newpos should be in world coordinates
00084 Quat PickModeMove::calc_rot_quat(int dim, int b, DisplayDevice *d,
00085                                  const float *mat, const float *newpos) {
00086   Quat quatx, quaty, quatz;                               
00087   Quat transquat;
00088   if (dim == 2) {                           
00089     if ((b == Mouse::B_MIDDLE || b == Mouse::B_RIGHT) || 
00090         d->shift_state() & DisplayDevice::ALT) {    
00091       quatz.rotate('z',(newpos[0] - lastPos[0])*150); 
00092     } else {                                
00093       quaty.rotate('y',(newpos[0] - lastPos[0])*150);  
00094       quatx.rotate('x',(-newpos[1] + lastPos[1])*150);
00095     }                                       
00096   } else {                                 
00097     quatx.rotate('x', (newpos[0] - lastPos[0])*150);  
00098     quaty.rotate('y', (newpos[1] - lastPos[1])*150);  
00099     quatz.rotate('z', (newpos[2] - lastPos[2])*150);  
00100   }                                         
00101   Quat rotq;                               
00102   rotq.fromMatrix(mat);     
00103   transquat = rotq;                  
00104   transquat.mult(quatz);            
00105   transquat.mult(quaty);           
00106   transquat.mult(quatx);         
00107   rotq.invert();               
00108   transquat.mult(rotq);      
00109   return transquat;
00110 }  
00111 
00112 void PickModeMove::pick_molecule_move(DrawMolecule *m, DisplayDevice *d,
00113                         int tag, int dim, const float *pos) {
00114   
00115   float newpos[3], atomPos[3];
00116 
00117   // Convert the pointer position into world coordinates
00118   get_pointer_pos(m,d,tag,lastCell,dim,pos,newpos);
00119 
00120   // Copy the current atom coordinates into a buffer
00121   Timestep *ts = m->current();
00122   memcpy(atomPos, ts->pos + 3L*tag, 3L*sizeof(float));
00123 
00124   // if the shift key is pressed, do rotations
00125   if (d->shift_state() & DisplayDevice::SHIFT) {
00126     Quat transquat = calc_rot_quat(dim,btn,d,(m->rotm).mat, newpos);
00127     rotate(m, tag, atomPos, transquat);
00128   } 
00129   else { // do translations
00130     // convert the pointer position to object coordinates, subtract the 
00131     // coordinates of the picked atom, and add the result to all atoms in
00132     // the residue.
00133 
00134     // Apply unit cell transform
00135     Matrix4 mat;
00136     ts->get_transform_from_cell(lastCell, mat);
00137     mat.multpoint3d(atomPos, atomPos);
00138 
00139     Matrix4 tminv(m->tm);
00140     tminv.inverse();
00141 
00142     float moveAmount[3];
00143     tminv.multpoint3d(newpos, moveAmount);
00144     vec_sub(moveAmount, moveAmount, atomPos);
00145  
00146     translate(m, tag, moveAmount);
00147   }
00148  
00149   vec_copy(lastPos, newpos);
00150 
00151   // tell the the molecule to update now - don't wait for the pick to end
00152   // XXX some reps (e.g., volumetric reps) don't care about changed coordinates
00153   m->force_recalc(DrawMolItem::MOL_REGEN | DrawMolItem::SEL_REGEN);
00154 }
00155 
00156 void PickModeMoveAtom::translate(DrawMolecule *m, int tag, const float *p) {
00157   float *pos = m->current()->pos+3L*tag;
00158   vec_add(pos, pos, p);
00159 }
00160 
00161 void PickModeMoveResidue::rotate(DrawMolecule *m, int tag, const float *p,
00162                                  const Quat &q) {
00163 
00164   Residue *res = m->atom_residue(tag);
00165   if (res) {
00166     int natm = (res->atoms).num();
00167     for (int n=0; n<natm; n++) {
00168       float *ap = m->current()->pos + 3L * (res->atoms)[n];
00169       // Rotate about the picked atom
00170       vec_sub(ap, ap, p);
00171       q.multpoint3(ap,ap);
00172       vec_add(ap, ap, p);
00173     }
00174   }
00175 }
00176 
00177 void PickModeMoveResidue::translate(DrawMolecule *m, int tag, const float *p) {
00178 
00179   Residue *res = m->atom_residue(tag);
00180   if(res) {
00181     int natm = (res->atoms).num();
00182     for(int n = 0; n < natm; n++) {
00183       float *ap = m->current()->pos + 3L * (res->atoms)[n];
00184       vec_add(ap, ap, p);
00185     }
00186   }
00187 }
00188 
00189 void PickModeMoveFragment::rotate(DrawMolecule *m, int tag, const float *p, 
00190                                   const Quat &q) {
00191 
00192   Fragment *frag = m->atom_fragment(tag);
00193   if (frag) {
00194     int nres = frag->num();
00195     for (int r=0; r < nres; r++) {
00196       Residue *res = m->residue((*frag)[r]);
00197       int natm = (res->atoms).num();
00198       for (int n=0; n < natm; n++) {
00199         float *ap = m->current()->pos + 3L * (res->atoms)[n];
00200         vec_sub(ap,ap,p);
00201         q.multpoint3(ap,ap); 
00202         vec_add(ap,ap,p);
00203       }
00204     }
00205   }
00206 }
00207 
00208 void PickModeMoveFragment::translate(DrawMolecule *m, int tag, const float *p){
00209   Fragment *frag = m->atom_fragment(tag);
00210   if (frag) {
00211     int nres = frag->num();
00212     for (int r=0; r < nres; r++) {
00213       Residue *res = m->residue((*frag)[r]);
00214       int natm = (res->atoms).num();
00215       for (int n=0; n < natm; n++) {
00216         float *ap = m->current()->pos + 3L * (res->atoms)[n];
00217         vec_add(ap,ap,p);
00218       }
00219     }
00220   }
00221 }
00222 
00223 void PickModeMoveMolecule::rotate(DrawMolecule *m, int, const float *p, 
00224                                   const Quat &q) {
00225   int natm = m->nAtoms;
00226   for (int i=0; i < natm; i++) {
00227     float *ap = m->current()->pos + 3L*i;
00228     vec_sub(ap,ap,p);
00229     q.multpoint3(ap,ap); 
00230     vec_add(ap,ap,p);
00231   }
00232 }
00233 
00234 void PickModeMoveMolecule::translate(DrawMolecule *m, int, const float *p){ 
00235 
00236   int natm = m->nAtoms;
00237   for (int i=0; i < natm; i++) {
00238     float *ap = m->current()->pos + 3L*i;
00239     vec_add(ap,ap,p);
00240   }
00241 }
00242 
00243 void PickModeMoveRep::rotate(DrawMolecule *m, int tag, const float *p, 
00244                                   const Quat &q) {
00245   if (!m->components()) 
00246     return;
00247   int rep = m->highlighted_rep();
00248   if (rep < 0 || rep >= m->components())
00249     return;
00250 
00251   const AtomSel *sel = m->component(rep)->atomSel;
00252   const int n = sel->num_atoms;
00253   const int *on = sel->on;
00254   if (!on[tag]) 
00255     return;
00256   float *ap = m->current()->pos;
00257   for (int i=0; i<n; i++) {
00258     if (on[i]) {
00259       float *pos = ap + 3L*i;
00260       vec_sub(pos, pos, p);
00261       q.multpoint3(pos, pos);
00262       vec_add(pos, pos, p);
00263     }
00264   }
00265 } 
00266    
00267 void PickModeMoveRep::translate(DrawMolecule *m, int tag, const float *p) {
00268 
00269   if (!m->components()) 
00270     return;
00271   int rep = m->highlighted_rep();
00272   if (rep < 0 || rep >= m->components())
00273     return;
00274 
00275   const AtomSel *sel = m->component(rep)->atomSel;
00276   const int n = sel->num_atoms;
00277   const int *on = sel->on;
00278   if (!on[tag]) 
00279     return;
00280   float *ap = m->current()->pos;
00281   for (int i=0; i<n; i++) {
00282     if (on[i]) {
00283       vec_add(ap+3L*i, ap+3L*i, p);
00284     }
00285   }
00286 }
00287 
00288 void PickModeMove::pick_molecule_end(DrawMolecule *, DisplayDevice *) {
00289   // pick_move takes care of everything
00290 }
00291 

Generated on Fri Apr 26 02:44:05 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002