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: SpaceballTracker.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.18 $ $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 00024 #include <stdlib.h> // for getenv(), abs() etc. 00025 #include <string.h> 00026 #include "VMDApp.h" 00027 #include "SpaceballTracker.h" 00028 #include "Spaceball.h" 00029 #include "Matrix4.h" 00030 #include "Inform.h" 00031 #include "utilities.h" 00032 00033 SpaceballTracker::SpaceballTracker(VMDApp *vmdapp) { 00034 app = vmdapp; // copy VMDApp pointer for use in accessing local spaceball 00035 00036 uselocal=0; // zero out the local Spaceball flag 00037 00038 #if defined(VMDLIBSBALL) 00039 sball=NULL; // zero it out to begin with 00040 #endif 00041 } 00042 00043 int SpaceballTracker::do_start(const SensorConfig *config) { 00044 #if defined(VMDLIBSBALL) 00045 if (sball) return FALSE; 00046 #endif 00047 if (!config->require_local()) return 0; 00048 if (!config->have_one_sensor()) return 0; 00049 00050 char *myUSL = stringdup(config->getname()); 00051 00052 if (!strupcmp(myUSL, "VMDLOCAL")) { 00053 msgInfo << "Opening VMD console Spaceball device (tracker)." << sendmsg; 00054 uselocal=1; // Use the main VMD spaceball for input 00055 00056 // set the default translation and rotation increments 00057 // these really need to be made user modifiable at runtime 00058 transInc = 1.0f; 00059 rotInc = 1.0f; 00060 scaleInc = 1.0f; 00061 } else { 00062 #if defined(VMDLIBSBALL) 00063 msgInfo << "Opening Spaceball tracker (direct I/O) on port: " << myUSL << sendmsg; 00064 sball = sball_open(myUSL); 00065 if (sball == NULL) 00066 msgErr << "Failed to open Spaceball serial port, tracker disabled" 00067 << sendmsg; 00068 00069 // set the default translation and rotation increments 00070 // these really need to be made user modifiable at runtime 00071 transInc = 1.0f / 6000.0f; 00072 rotInc = 1.0f / 50.0f; 00073 scaleInc = 1.0f / 6000.0f; 00074 #else 00075 msgErr << "Cannot open Spaceball with direct I/O, not compiled with " 00076 "LIBSBALL option" << sendmsg; 00077 #endif 00078 } 00079 00080 00081 // reset the position 00082 moveto(0,0,0); 00083 orient->identity(); 00084 00085 delete [] myUSL; 00086 00087 return TRUE; 00088 } 00089 00090 SpaceballTracker::~SpaceballTracker(void) { 00091 #if defined(VMDLIBSBALL) 00092 if (sball != NULL) 00093 sball_close(sball); 00094 #endif 00095 } 00096 00097 void SpaceballTracker::update() { 00098 Matrix4 temp; 00099 00100 if(!alive()) { 00101 moveto(0,0,0); 00102 orient->identity(); 00103 return; 00104 } 00105 00106 if (uselocal) { 00107 float tx, ty, tz, rx, ry, rz; 00108 tx=ty=tz=rx=ry=rz=0.0f; 00109 int buttons; 00110 buttons=0; 00111 00112 // query VMDApp spaceball for events 00113 if (app != NULL) { 00114 app->spaceball_get_tracker_status(tx, ty, tz, rx, ry, rz, buttons); 00115 } 00116 00117 // Z-axis rotation/trans have to be negated in order to convert to the 00118 // VMD coordinate system 00119 temp.identity(); 00120 temp.rot(rx, 'x'); 00121 temp.rot(ry, 'y'); 00122 temp.rot(rz, 'z'); 00123 temp.multmatrix(*orient); 00124 orient->loadmatrix(temp); 00125 pos[0] += tx; 00126 pos[1] += ty; 00127 pos[2] += tz; 00128 } else { 00129 int tx, ty, tz, rx, ry, rz, buttons; 00130 tx=ty=tz=rx=ry=rz=buttons=0; 00131 #if defined(VMDLIBSBALL) 00132 if (sball != NULL ) { 00133 if (!sball_getstatus(sball, &tx, &ty, &tz, &rx, &ry, &rz, &buttons)) 00134 return; 00135 } 00136 #endif 00137 // Z-axis rotation/trans have to be negated in order to convert to the 00138 // VMD coordinate system 00139 temp.identity(); 00140 temp.rot( ((float)rx)*rotInc, 'x' ); 00141 temp.rot( ((float)ry)*rotInc, 'y' ); 00142 temp.rot(-((float)rz)*rotInc, 'z' ); 00143 temp.multmatrix(*orient); 00144 orient->loadmatrix(temp); 00145 pos[0] += tx * transInc; 00146 pos[1] += ty * transInc; 00147 pos[2] +=-tz * transInc; 00148 } 00149 } 00150