package org.squidy.nodes.optitrack; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.MouseInfo; import java.awt.Point; import java.awt.PointerInfo; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.JWindow; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; import org.squidy.designer.util.ImageUtils; import org.squidy.manager.controls.TextField; import org.squidy.manager.data.DataConstant; import org.squidy.manager.data.IData; import org.squidy.manager.data.IDataContainer; import org.squidy.manager.data.Processor; import org.squidy.manager.data.Property; import org.squidy.manager.data.Processor.Status; import org.squidy.manager.data.impl.DataDigital; import org.squidy.manager.data.impl.DataPosition2D; import org.squidy.manager.data.impl.DataPosition3D; import org.squidy.manager.data.impl.DataPosition6D; import org.squidy.manager.model.AbstractNode; import org.squidy.manager.util.DataUtility; import org.squidy.manager.util.MathUtility; import org.squidy.nodes.optitrack.multicursor.MCursor; import org.squidy.nodes.optitrack.utils.TrackingConstant; /*<code>MultiCursor</code>. * * <pre> * Date: Jan 29 2010 * Time: 1:35:05 AMd * </pre> * * @author Simon Faeh, <a href="mailto:simon.faeh@uni-konstanz.de">Simon.Faeh@uni-konstanz.de<a/>, University of Konstanz * * @version 17.11.2010 / sf */ @XmlType(name = "MultiCursor") @Processor( name = "MultiCursor", icon = "/org/squidy/nodes/image/48x48/multicursor.png", description = "Displays multiple cursors for 2D-Data", types = {Processor.Type.OUTPUT, Processor.Type.INPUT }, tags = { "cursor", "multi", "Dataposition2D"}, status = Status.UNSTABLE ) public class MultiCursor extends AbstractNode { // ################################################################################ // Begin OF ADJUSTABLES // ################################################################################ // ################################################################################ @XmlAttribute(name = "manual-width") @Property(name = "Manual display width", group = "Display Settings", description = "The manual display width of the allowed mouse positioning in pixels. Only used if positioning is set manually.") @TextField private double manualWidth = 1024; /** * @return the manualWidth */ public final double getManualWidth() { return manualWidth; } /** * @param manualWidth * the manualWidth to set */ public final void setManualWidth(double manualWidth) { this.manualWidth = manualWidth; } // ################################################################################ @XmlAttribute(name = "manual-height") @Property(name = "Manual display height", group = "Display Settings", description = "The manual display height of the allowed mouse positioning in pixels. Only used if positioning is set manually.") @TextField private double manualHeight = 768; /** * @return the manualHeight */ public final double getManualHeight() { return manualHeight; } /** * @param manualHeight * the manualHeight to set */ public final void setManualHeight(double manualHeight) { this.manualHeight = manualHeight; } // ################################################################################ @XmlAttribute(name = "origin-offset-x") @Property(name = "Manual display origin offset X", group = "Display Settings", description = "The manual display origin X offset of mouse positions in pixels.") @TextField private double originOffsetX = 0; /** * @return the originOffsetX */ public final double getOriginOffsetX() { return originOffsetX; } /** * @param originOffsetX * the originOffsetX to set */ public final void setOriginOffsetX(double originOffsetX) { this.originOffsetX = originOffsetX; } // ################################################################################ @XmlAttribute(name = "origin-offset-y") @Property(name = "Manual display origin offset Y", group = "Display Settings", description = "The manual display origin Y offset of mouse positions in pixels.") @TextField private double originOffsetY = 0; /** * @return the originOffsetY */ public final double getOriginOffsetY() { return originOffsetY; } /** * @param originOffsetY * the originOffsetY to set */ public final void setOriginOffsetY(double originOffsetY) { this.originOffsetY = originOffsetY; } // ################################################################################ // ################################################################################ @XmlAttribute(name = "timeout") @Property(name = "Cursor Timeout", group = "Display Settings", description = "Hides Cursor if no Data is received (ms)") @TextField private double cursorTimeout = 500; /** * @return the timeout */ public final double getCursorTimeout() { return cursorTimeout; } /** * @param originOffsetY * the originOffsetY to set */ public final void setCursorTimeout(double cursorTimeout) { this.cursorTimeout = cursorTimeout; } // ################################################################################ // @XmlAttribute(name = "hidePosition") // @Property(name = "Cursor hide location", group = "Display Settings", description = "Hides Cursor if placed on this location") // @TextField // private String hideLocation = "0,0"; // // /** // * @return the timeout // */ // public final String getHideLocation() { // return hideLocation; // } // // /** // * @param originOffsetY // * the originOffsetY to set // */ // public final void setHideLocation(String hideLocation) { // this.hideLocation = hideLocation; // } // ################################################################################ // END OF ADJUSTABLES // ################################################################################ private ArrayList<MCursor> cursorThreads; private long lastUpdate; private Point cursorHideLocation; @Override public void onStart() { cursorThreads = new ArrayList<MCursor>(); // cursorHideLocation = new Point(0,0); // if (hideLocation.length() > 0) // { // String[] chunks = this.hideLocation.split(","); // cursorHideLocation.x = Integer.parseInt(chunks[0]); // cursorHideLocation.y = Integer.parseInt(chunks[1]); // } } @Override public void onStop() { for (MCursor cThread : cursorThreads) { cThread.isReadyToDestroy(true); } } private boolean changed = false; private String imagePath = ""; private int handSide = 0; private int gestureID = 0; private int currentHand = 0; private int currentdGesture = 0; public IData process(DataPosition2D d2d) { //lastTimeOfDataPosition2D = System.currentTimeMillis(); int sessionID; if (d2d.hasAttribute(TrackingConstant.RIGIDBODYID)) { sessionID = Integer.valueOf(d2d.getAttribute(TrackingConstant.RIGIDBODYID).toString()); }else { sessionID = Integer.MAX_VALUE - 10; } if (d2d.hasAttribute(TrackingConstant.GESTUREID)) { handSide = Integer.valueOf(d2d.getAttribute(TrackingConstant.HANDSIDE).toString()); gestureID = Integer.valueOf(d2d.getAttribute(TrackingConstant.GESTUREID).toString()); } else { gestureID = 0; handSide = sessionID; } //int sessionID = 1;// boolean cursorFound = false; boolean noNewCursor = false; if (cursorThreads.size() > 0) for (MCursor cThread : cursorThreads) { if (cThread.getCursorID() == sessionID) { imagePath = ""; if (d2d.getX() == 0 && d2d.getY() == 0) { // gestureID = -1; // imagePath = "/org/squidy/nodes/image/32x32/hand_null.png"; } else { // if (d2d.hasAttribute(TrackingConstant.GESTUREID) && this.gestureID != cThread.getGestureID()) // { // switch (Integer.valueOf(d2d.getAttribute(TrackingConstant.GESTUREID).toString())) // { // case 1 : // { // if (Integer.valueOf(d2d.getAttribute(TrackingConstant.HANDSIDE).toString()) == 1) // imagePath = "/org/squidy/nodes/image/32x32/hand_click_right.png"; // else // imagePath = "/org/squidy/nodes/image/32x32/hand_click_left.png"; // break; // } // case 2 : // { // if (Integer.valueOf(d2d.getAttribute(TrackingConstant.HANDSIDE).toString()) == 1) // imagePath ="/org/squidy/nodes/image/32x32/hand_grab_right.png"; // else // imagePath ="/org/squidy/nodes/image/32x32/hand_grab_left.png"; // break; // } // case 3 : // { // if (Integer.valueOf(d2d.getAttribute(TrackingConstant.HANDSIDE).toString()) == 1) // imagePath ="/org/squidy/nodes/image/32x32/hand_click_right.png"; // else // imagePath ="/org/squidy/nodes/image/32x32/hand_click_left.png"; // break; // } // default : // { // if (Integer.valueOf(d2d.getAttribute(TrackingConstant.HANDSIDE).toString()) == 1) // imagePath = "/org/squidy/nodes/image/32x32/hand_point_right.png"; // else // imagePath = "/org/squidy/nodes/image/32x32/hand_point_left.png"; // break; // } // } // } } if (imagePath != "") { changed = true; cThread.forceDestruction(); cursorThreads.remove(cThread); MCursor mCursor = new MCursor(imagePath,32,getScreenCoordinates(d2d), sessionID, handSide, gestureID); //CursorThread cThread = new CursorThread(new CursorRunnable("/org/squidy/nodes/image/32x32/hand_point4.png",32,getScreenCoordinates(d2d), sessionID)); cursorThreads.add(mCursor); lastUpdate = System.currentTimeMillis(); cursorFound = true; System.out.println("cursor added "); } else { if (this.gestureID != cThread.getGestureID()) { // changed = true; // cThread.forceDestruction(); // cursorThreads.remove(cThread); // MCursor mCursor; // if (handSide == 2) // { // mCursor = new MCursor("/org/squidy/nodes/image/32x32/hand_point_right.png",32,getScreenCoordinates(d2d), sessionID, handSide, gestureID); // } // else // { // mCursor = new MCursor("/org/squidy/nodes/image/32x32/hand_point_left.png",32,getScreenCoordinates(d2d), sessionID, handSide, gestureID); // } // //CursorThread cThread = new CursorThread(new CursorRunnable("/org/squidy/nodes/image/32x32/hand_point4.png",32,getScreenCoordinates(d2d), sessionID)); // cursorThreads.add(mCursor); // System.out.println("cursor added "); // lastUpdate = System.currentTimeMillis(); // cursorFound = true; } cThread.updateLocation(getScreenCoordinates(d2d)); cursorFound = true; } break; } } // if (!cThread.isReadyToDestroy()) // { // //if (d2d.getX() < 100) // //if (lastUpdate + 5000 < System.currentTimeMillis()) // if (d2d.getX() == 0 && d2d.getY() == 0) // { // //cThread.interrupt(); // //noNewCursor = true; // cThread.isReadyToDestroy(true); // cursorThreads.remove(cThread); // if (cursorThreads.size() > 0) // System.out.println("FUUUUUUUUUUUUUCK"); // }else // { // cThread.updateLocation(getScreenCoordinates(d2d)); // cursorFound = true; // } // // break; // } // } if (!cursorFound) { System.out.println("new cursor"); MCursor mCursor; if (handSide == 2) { mCursor = new MCursor("/org/squidy/nodes/image/32x32/hand_point_right.png",32,getScreenCoordinates(d2d), sessionID, handSide, gestureID); } else { mCursor = new MCursor("/org/squidy/nodes/image/32x32/hand_point_left.png",32,getScreenCoordinates(d2d), sessionID, handSide, gestureID); } //CursorThread cThread = new CursorThread(new CursorRunnable("/org/squidy/nodes/image/32x32/hand_point4.png",32,getScreenCoordinates(d2d), sessionID)); cursorThreads.add(mCursor); lastUpdate = System.currentTimeMillis(); } return d2d; } private Point getScreenCoordinates(DataPosition2D d2d) { return new Point((int)(d2d.getX() * manualWidth + originOffsetX), (int)(d2d.getY() * manualHeight + originOffsetY)); } }