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

PickModeForce.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: PickModeForce.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.16 $       $Date: 2019/01/17 21:21:01 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *  Pick mode for applying forces to atoms
00019  ***************************************************************************/
00020 
00021 #include "PickModeForce.h"
00022 #include "Atom.h"
00023 #include "Molecule.h"
00024 #include "DisplayDevice.h"
00025 #include "Mouse.h"
00026 
00027 void PickModeForce::get_force(const float *atomPos, const float *pos,
00028                               DrawMolecule *m, int dim, DisplayDevice *d, 
00029                               float *newforce) {
00030 
00031   float atomWorldPos[3], mouseWorldPos[3];
00032   const float *newpos;
00033   if(dim == 2) {
00034 
00035     // convert atom position to world coordinates
00036     m->tm.multpoint3d(atomPos, atomWorldPos);
00037 
00038     // find the 3D position (in world coords) of the mouse
00039     d->find_3D_from_2D(atomWorldPos, pos, mouseWorldPos);
00040 
00041     // indicate this new position as the mouse position
00042     newpos = mouseWorldPos;
00043   } else {
00044     // for 3D pointer, just use the pointer position as-is, but
00045     newpos = pos;
00046   }
00047 
00048   // now convert back from world coords to object coords
00049   Matrix4 tminv(m->tm);
00050   tminv.inverse();
00051   tminv.multpoint3d(newpos, newforce);
00052 }
00053 
00054 // This #define is copied from DrawForce
00055 
00056 #define FORCE_SCALE (10.0f / 14.0f)
00057 
00058 static const float zeroforce[] = {0.0f, 0.0f, 0.0f};
00059 
00060 void PickModeForceAtom::pick_molecule_start(DrawMolecule *m, DisplayDevice *,
00061                              int btn, int tag, const int *cell, int /* dim */, 
00062                              const float * /* pos */ ) {
00063 
00064   // if the middle or right button is down, clear the force
00065   if ((btn == Mouse::B_MIDDLE || btn == Mouse::B_RIGHT) && tag >= 0) {
00066     // XXX downcast to Molecule
00067     ((Molecule *)m)->addPersistentForce(tag, zeroforce);
00068     mytag = -1;
00069   } else if (cell[0] || cell[1] || cell[2]) {
00070     // don't apply force to periodic images
00071     mytag = -1;
00072   } else {
00073     mytag = tag;
00074   }
00075 }
00076 
00077 void PickModeForceAtom::pick_molecule_move(DrawMolecule *m, DisplayDevice *d,
00078                                            int tag, int dim, 
00079                                            const float *pos) {
00080  
00081   if (mytag < 0) return;
00082   float *atomPos = m->current()->pos + 3*tag;
00083   float newforce[3];
00084   get_force(atomPos, pos, m, dim, d, newforce);
00085   newforce[0] = FORCE_SCALE * (newforce[0] - atomPos[0]); 
00086   newforce[1] = FORCE_SCALE * (newforce[1] - atomPos[1]); 
00087   newforce[2] = FORCE_SCALE * (newforce[2] - atomPos[2]); 
00088   // XXX downcast to Molecule
00089   ((Molecule *)m)->addPersistentForce(tag, newforce);
00090 }
00091 
00092 void PickModeForceResidue::pick_molecule_start(DrawMolecule *m, DisplayDevice *,
00093                              int btn, int tag, const int *, int /* dim */, 
00094                              const float * /* pos */ ) {
00095 
00096   // if the middle or right button is down, clear the force
00097   if ((btn == Mouse::B_MIDDLE || btn == Mouse::B_RIGHT) && tag >= 0) {
00098     Residue *res = m->atom_residue(tag);
00099     if (res) {
00100       int natm = (res->atoms).num();
00101       for (int i=0; i < natm; i++)
00102         ((Molecule *)m)->addPersistentForce(res->atoms[i], zeroforce);
00103     }
00104     mytag = -1;
00105   } else {
00106     mytag = tag;
00107   }
00108 }
00109 
00110 void PickModeForceResidue::pick_molecule_move(DrawMolecule *m, DisplayDevice *d,
00111                                            int tag, int dim, 
00112                                            const float *pos) {
00113  
00114   if (mytag < 0) return;
00115   float *atomPos = m->current()->pos + 3*tag;
00116   float newforce[3];
00117   get_force(atomPos, pos, m, dim, d, newforce);
00118   newforce[0] = FORCE_SCALE * (newforce[0] - atomPos[0]); 
00119   newforce[1] = FORCE_SCALE * (newforce[1] - atomPos[1]); 
00120   newforce[2] = FORCE_SCALE * (newforce[2] - atomPos[2]); 
00121   Residue *res = m->atom_residue(tag);
00122   if (res) {
00123     int natm = (res->atoms).num();
00124     for (int i=0; i < natm; i++)
00125       ((Molecule *)m)->addPersistentForce(res->atoms[i], newforce);
00126   }
00127 }
00128 
00129 void PickModeForceFragment::pick_molecule_start(DrawMolecule *m, 
00130                                          DisplayDevice *, int btn, 
00131                                          int tag, const int *, int /* dim */, 
00132                                          const float * /* pos */ ) {
00133 
00134   // if the middle or right button is down, clear the force
00135   if ((btn == Mouse::B_MIDDLE || btn == Mouse::B_RIGHT) && tag >= 0) {
00136     Fragment *frag = m->atom_fragment(tag);
00137     if (frag) {
00138       int nres = frag->num();
00139       for (int r=0; r < nres; r++) {
00140         Residue *res = m->residue((*frag)[r]);
00141         int natm = (res->atoms).num();
00142         for (int i=0; i < natm; i++)
00143           ((Molecule *)m)->addPersistentForce(res->atoms[i], zeroforce);
00144       }  // loop over residues
00145     }    // if (frag)
00146     mytag = -1;
00147   } else {     
00148     mytag = tag;
00149   }
00150 }
00151 
00152 void PickModeForceFragment::pick_molecule_move(DrawMolecule *m, 
00153                                            DisplayDevice *d,
00154                                            int tag, int dim, 
00155                                            const float *pos) {
00156  
00157   if (mytag < 0) return; 
00158   float *atomPos = m->current()->pos + 3*tag;
00159   float newforce[3];
00160   get_force(atomPos, pos, m, dim, d, newforce);
00161   newforce[0] = FORCE_SCALE * (newforce[0] - atomPos[0]); 
00162   newforce[1] = FORCE_SCALE * (newforce[1] - atomPos[1]); 
00163   newforce[2] = FORCE_SCALE * (newforce[2] - atomPos[2]); 
00164   Fragment *frag = m->atom_fragment(tag);
00165   if (frag) {
00166     int nres = frag->num();
00167     for (int r=0; r < nres; r++) {
00168       Residue *res = m->residue((*frag)[r]);
00169       int natm = (res->atoms).num();
00170       for (int i=0; i < natm; i++)
00171         ((Molecule *)m)->addPersistentForce(res->atoms[i], newforce);
00172     }  // loop over residues
00173   }    // if (frag)
00174 }

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