VisClient/org/hfbk/nubsi/Spacemouse.java

Go to the documentation of this file.
00001 package org.hfbk.nubsi;
00002 
00003 import java.io.IOException;
00004 import java.io.OutputStream;
00005 import java.io.PrintStream;
00006 import java.util.HashMap;
00007 
00008 import net.java.games.input.Component;
00009 import net.java.games.input.Controller;
00010 import net.java.games.input.ControllerEnvironment;
00011 import net.java.games.input.Event;
00012 
00013 import org.hfbk.util.Sleeper;
00014 import org.lwjgl.util.vector.Vector3f;
00015 
00027 public class Spacemouse extends Thread {
00028 
00029         public static Spacemouse instance;
00030         
00031         public Vector3f trans = new Vector3f(), rot = new Vector3f();
00032 
00033         final float transSpeed = 0.015f, rotSpeed = 0.003f;
00034         
00035         
00036         // time in millies between polls.
00037         // this must be high enough to prevent
00038         // the polling overrun the device.
00039         // in this case we got no event from one
00040         // or more axes in one cycle even if they are
00041         // active. too bad the driver doesn't send
00042         // events for inactive axes, so we never truly
00043         // know wether the axis has not just fired the
00044         // event until now or it is in neutral position.
00045         //
00046         // i think a nice event system should fire at
00047         // all value changes even if they led to zero..
00048         //
00049         final int DELAY = 100;
00050 
00051         private HashMap<Component, Integer> mapping = new HashMap<Component, Integer>();
00052 
00053         private Controller spacemouse = null;
00054 
00055         
00056         private Spacemouse() {
00057                 super("Spacemouse");
00058                 setDaemon(true);
00059                 
00060                 int[] map=null;
00061                 
00062                 //set a null stdout stream to suppress input device problems blah
00063                 PrintStream out=System.out;
00064                 System.setOut(new PrintStream(new OutputStream(){
00065                         public void write(int b) throws IOException {}
00066                 }));
00067                 ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
00068                 for (Controller c : ce.getControllers())
00069                         if (c.getComponents().length > 5)
00070                                 if (c.getName().matches("3Dconnexion.*")){ //linux HID{                         
00071                                         spacemouse = c;
00072                                         map=new int[]{0,2,1,3,5,4}; //x,z,y, throttle 1-3
00073                                 }else if (c.getName().matches("Space.*")){ //windows HID
00074                                         spacemouse = c;
00075                                         map=new int[]{1,2,0,4,5,3}; //x,z,y,rx,rz,ry
00076                                 }
00077                 //reset out stream
00078                 System.setOut(out);
00079                                         
00080                 if (spacemouse != null) {
00081                         System.out.println("Spacemouse found: " + spacemouse.getName());
00082 
00083                         // this is somewhat akward: as the usual axes are depleted after
00084                         // x,y,z, the further ones are all "throttle" controllers on linux
00085                         // machines.
00086                         // so we cannot retrieve its function of an axis by itself, rather
00087                         // we just enumerate them via the "mapping" map, assigning
00088                         // each axis a unique number. hopefully their sequence does not
00089                         // change between devices :-[
00090                         int i = 0;
00091                         for (Component c : spacemouse.getComponents())
00092                                 if (c.isAnalog()) {// assign numbers to axes
00093                                         //System.out.println(map[i]+" -> "+c.getName()+":"+c.getIdentifier().getName());
00094                                         mapping.put(c, map[i++]);                                       
00095                                 }
00096                         //let's go..
00097                         start();
00098                 }
00099         }
00100 
00101         public void run() {
00102                 while (true) {
00103                         spacemouse.poll();
00104 
00105                         float[] vals = new float[6];
00106 
00107                         // consume all events that happend since last poll.
00108                         // this are usually multiple ones for each axes.
00109                         // it would be easier to get the summated value via
00110                         // Component.getPolledValue, but the accumulation
00111                         // depends on the number of events happend inbetween.
00112                         // as sometimes more rendering frames as events happens,
00113                         // we don't like to do the motion in the controllers event
00114                         // speed, rather we just use the most recent value each
00115                         // frame. so we can continue to move on even if rendering
00116                         // occurs more often than controller events. this gives a
00117                         // more smooth movement.
00118                         Event e = new Event();
00119                         while (spacemouse.getEventQueue().getNextEvent(e)) {
00120                                 Component c = e.getComponent();
00121                                 if (c.isAnalog())
00122                                         if (mapping.get(c) != null) {// we've got some of the 6
00123                                                                                                         // axes...
00124                                                 int i = mapping.get(c);
00125                                                 vals[i] = e.getValue();
00126                                         }
00127                         }
00128 
00129                         // update the visible values
00130                         synchronized (this) {
00131                                 trans.set(vals[0] * transSpeed, -vals[1] * transSpeed, vals[2]* transSpeed);
00132                                 rot.set(vals[3] * rotSpeed, -vals[4] * rotSpeed, vals[5]* rotSpeed);
00133                         }
00134                         Sleeper.sleep(DELAY);
00135                 }
00136         }
00137         
00138         public boolean isReady(){
00139                 return spacemouse!=null;
00140         }
00141 
00142         public static Spacemouse getInstance() {
00143                 if (instance==null) instance=new Spacemouse();
00144                 return instance;
00145         }
00146 }

Generated on Tue Apr 7 17:57:19 2009 for visclient by  doxygen 1.5.1