00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00048 Matrix4 mat;
00049 ts->get_transform_from_cell(cell, mat);
00050 mat.multpoint3d(atomPos, atomPos);
00051
00052
00053 (m->tm).multpoint3d(atomPos, atomWorldPos);
00054
00055
00056 d->find_3D_from_2D(atomWorldPos, pos, mouseObjPos);
00057
00058
00059
00060 newpos = mouseObjPos;
00061
00062 } else {
00063
00064
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
00076 memcpy(lastCell, cell, 3L*sizeof(int));
00077 get_pointer_pos(m, d, tag, cell, dim, pos, lastPos);
00078 btn = theBtn;
00079 }
00080
00082
00083
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
00118 get_pointer_pos(m,d,tag,lastCell,dim,pos,newpos);
00119
00120
00121 Timestep *ts = m->current();
00122 memcpy(atomPos, ts->pos + 3L*tag, 3L*sizeof(float));
00123
00124
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 {
00130
00131
00132
00133
00134
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
00152
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
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
00290 }
00291