package org.squidy.nodes.optitrack;
import java.util.ArrayList;
import java.util.List;
import javax.sound.midi.Track;
import javax.swing.KeyStroke;
import javax.vecmath.*;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
import org.squidy.manager.controls.CheckBox;
import org.squidy.manager.controls.ComboBox;
import org.squidy.manager.controls.Slider;
import org.squidy.manager.controls.TextField;
import org.squidy.manager.controls.ComboBoxControl.ComboBoxItemWrapper;
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.domainprovider.DomainProvider;
import org.squidy.manager.data.impl.DataButton;
import org.squidy.manager.data.impl.DataDigital;
import org.squidy.manager.data.impl.DataPosition3D;
import org.squidy.manager.data.impl.DataPosition6D;
import org.squidy.manager.data.impl.DataString;
import org.squidy.manager.model.AbstractNode;
import org.squidy.manager.util.DataUtility;
import org.squidy.manager.util.MathUtility;
import org.squidy.nodes.Keyboard;
import org.squidy.nodes.optitrack.RigidBody.RBIDDomainProvider;
import org.squidy.nodes.optitrack.utils.TrackingConstant;
/*<code>RoomObject</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
*/
@XmlType(name = "RoomObject")
@Processor(
name = "Room Object",
icon = "/org/squidy/nodes/image/48x48/roomobject.png",
description = "Physical object in the tracked area",
types = {Processor.Type.OUTPUT, Processor.Type.INPUT },
tags = { "room", "object", "optitrack", "handtracking", "interception" },
status = Status.UNSTABLE
)
public class RoomObject extends AbstractNode {
// ################################################################################
// BEGIN OF ADJUSTABLES
// ################################################################################
@XmlAttribute(name = "displayPreset")
@Property(
name = "Display Preset",
description = "Load Display definition"
)
@ComboBox(domainProvider = RBIDDomainProvider.class)
private int displayDef = TrackingConstant.ROOMOBJECT_MANUAL;
public final int getDisplayDef() {
return displayDef;
}
public final void setDisplayDef(int rID) {
this.displayDef = rID;
createRoomObject();
}
// ################################################################################
@XmlAttribute(name = "screenOversize")
@Property(
name = "Screen Oversize",
description = "Virutally enlarged Screen",
suffix = " %"
)
@Slider(
type = Integer.class,
minimumValue = 0,
maximumValue = 100,
showLabels = true,
showTicks = true,
majorTicks = 50,
minorTicks = 5,
snapToTicks = true
)
private int overSize = 20;
public int getOverSize() {
return overSize;
}
public void setOverSize(int overSize) {
this.overSize = overSize;
}
// ################################################################################
@XmlAttribute(name = "backFaceTracking")
@Property(
name = "Backside Pointing",
description = "Allows pointing through the backside of the display")
@CheckBox
private boolean backFaceTracking = false;
public final boolean getBackFaceTracking() {
return backFaceTracking;
}
public final void setBackFaceTracking(boolean backFaceTracking) {
this.backFaceTracking = backFaceTracking;
}
// ################################################################################
@XmlAttribute(name = "objectName")
@Property(
name = "Object Name",
description = "Name of the Target-Object",
group = "Manual")
@TextField
private String objectName = "Cubes";
public final String getObjectName() {
return objectName;
}
public final void setObjectName(String objectName) {
this.objectName = objectName;
}
// ################################################################################
@XmlAttribute(name = "displayTopLeftCornder3D")
@Property(
name = "Top Left Corner (x,y,z)",
description = "3D coordinates of the Top Left Corner \"x,y,z\" in mm",
group = "Manual")
@TextField
private String displayTL = "1445,1885,0";
public final String getDisplayTL() {
return displayTL;
}
public final void setDisplayTL(String displayTL) {
this.displayTL = displayTL;
}
// ################################################################################
@XmlAttribute(name = "displayBottomLeftCornder3D")
@Property(
name = "Bottom Left Corner (x,y,z)",
description = "3D coordinates of the Bottom Left Corner \"x,y,z\" in mm",
group = "Manual")
@TextField
private String displayBL = "1445,1135,0";
public final String getDisplayBL() {
return displayBL;
}
public final void setDisplayBL(String displayBL) {
this.displayBL = displayBL;
}
// ################################################################################
@XmlAttribute(name = "displayBottomRightCornder3D")
@Property(
name = "Bottom Right Corner (x,y,z)",
description = "3D coordinates of the Bottom Right Corner \"x,y,z\" in mm",
group = "Manual")
@TextField
private String displayBR = "4353,1135,41";
public final String getDisplayBR() {
return displayBR;
}
public final void setDisplayBR(String displayBR) {
this.displayBR = displayBR;
}
// ################################################################################
@XmlAttribute(name = "objectHeight")
@Property(
name = "Object Height",
description = "Height of the object in mm",
group = "Mobile")
@TextField
private double objectHeight = 0;
public final double getObjectHeight() {
return objectHeight;
}
public final void setObjectHeight(double displayHeight) {
this.objectHeight = displayHeight;
}
// ################################################################################
@XmlAttribute(name = "objectWidth")
@Property(
name = "Object Width",
description = "Width of the object in mm",
group = "Mobile")
@TextField
private double objectWidth = 0;
public final double getObjectWidth() {
return objectWidth;
}
public final void setObjectWidth(double displayDepth) {
this.objectWidth = displayDepth;
}
// ################################################################################
@XmlAttribute(name = "objectDepth")
@Property(
name = "Object Depth",
description = "Depth of the object in mm",
group = "Mobile")
@TextField
private double objectDepth = 0;
public final double getObjectDepth() {
return objectDepth;
}
public final void setObjectDepth(double displayDepth) {
this.objectDepth = displayDepth;
}
// ################################################################################
@XmlAttribute(name = "originOffsett")
@Property(
name = "Offset from Markers Origin",
description = "Offset \"x,y,z\" in mm",
group = "Mobile")
@TextField
private String displayOffset = "0,0,0";
public final String getDisplayOffset() {
return displayOffset;
}
public final void setDisplayOffset(String displayOS) {
this.displayOffset = displayOS;
}
// ################################################################################
@XmlAttribute(name = "isMobileDisplay")
@Property(
name = "Mobile Display",
description = "Check if this Display gets its position by a Rigidbody",
group ="Mobile")
@CheckBox
private boolean isDisplay = false;
public final boolean getIsDisplay() {
return isDisplay;
}
public final void setIsDisplay(boolean isDisplay) {
this.isDisplay = isDisplay;
}
// ################################################################################
@XmlAttribute(name = "keyID")
@Property(
name = "Calibration Key",
description = "Pressing the key sets the Object to static",
group = "Mobile"
)
@TextField
private String keyStroke = "-";
public final String getKeyStroke() {
return keyStroke;
}
public final void setKeyStroke(String key) {
this.keyStroke = key;
}
@XmlAttribute(name = "host")
@Property(
name = "Host",
description = "The host which should receive Squidy Remote data.",
group = "Remote Connection"
)
@TextField
private String host = "127.0.0.1";
/**
* @return the host
*/
public final String getHost() {
return host;
}
/**
* @param host the host to set
*/
public final void setHost(String host) {
this.host = host;
}
// ################################################################################
@XmlAttribute(name = "port")
@Property(
name = "Port",
description = "The port which should receive Squidy Remote data.",
group = "Remote Connection"
)
@TextField
private int port = 1919;
/**
* @return the port
*/
public final int getPort() {
return port;
}
/**
* @param port the port to set
*/
public final void setPort(int port) {
this.port = port;
}
// ################################################################################
// ################################################################################
// END OF ADJUSTABLES
// ################################################################################
// ################################################################################
// BEGIN OF DOMAIN PROVIDERS
// ################################################################################
public static class RBIDDomainProvider implements DomainProvider {
/*
* (non-Javadoc)
*
* @see org.squidy.manager.data.domainprovider.DomainProvider#getValues()
*/
public Object[] getValues() {
ComboBoxItemWrapper[] values = new ComboBoxItemWrapper[6];
values[0] = new ComboBoxItemWrapper(TrackingConstant.ROOMOBJECT_CUBES, "Cubes");
values[1] = new ComboBoxItemWrapper(TrackingConstant.ROOMOBJECT_CITRON, "Citron");
values[2] = new ComboBoxItemWrapper(TrackingConstant.ROOMOBJECT_SURFACE, "Surface");
values[3] = new ComboBoxItemWrapper(TrackingConstant.ROOMOBJECT_ICT, "ICT Touch-Table");
values[4] = new ComboBoxItemWrapper(TrackingConstant.ROOMOBJECT_4k, "4K-Dispaly");
values[5] = new ComboBoxItemWrapper(TrackingConstant.ROOMOBJECT_MANUAL, "Set Manually");
return values;
}
}
// ################################################################################
// END OF DOMAIN PROVIDERS
// ################################################################################
@Override
public void onStarted() {
if(!this.isDisplay)
{
publish(createRoomObject());
}
}
@Override
public void onStart() {
if(!this.isDisplay)
{
keyPressed = false;
publish(createRoomObject());
}
}
private DataString createRoomObject()
{
switch(this.displayDef)
{
case TrackingConstant.ROOMOBJECT_CUBES :
{
this.displayTL = "4480,1900,0";
this.displayBL = "4480,1140,0";
this.displayBR = "0,1135,0";
break;
}
case TrackingConstant.ROOMOBJECT_CITRON :
{
this.displayTL = "4484,1780,4320";
this.displayBL = "4484,1220,4320";
this.displayBR = "5270,1228,3775";
break;
}
case TrackingConstant.ROOMOBJECT_ICT :
{
// this.displayTL = "5020,1400,3200";
// this.displayBL = "5020,1000,3200";
// this.displayBR = "5020,1000,2700";
this.displayTL = "3450,1050,4210";
this.displayBL = "3450,800,4100";
this.displayBR = "3850,800,4100";
break;
}
case TrackingConstant.ROOMOBJECT_SURFACE :
{
this.displayTL = "4417,558,1836";
this.displayBL = "4659,579,2250";
this.displayBR = "4020,557,2537";
break;
}
case TrackingConstant.ROOMOBJECT_4k :
{
this.displayTL = "1470,1700,3820";
this.displayBL = "1470,1000,3820";
this.displayBR = "2705,1010,4600";
break;
}
case TrackingConstant.ROOMOBJECT_MANUAL :
{
break;
}
}
DataString ds = new DataString(RoomObject.class, this.displayTL+";"+this.displayBL+";"+this.displayBR);
ds.setAttribute(TrackingConstant.OBJECTHEIGHT, this.objectHeight);
ds.setAttribute(TrackingConstant.OBJECTWIDHT, this.objectDepth);
ds.setAttribute(TrackingConstant.OBJECTDEPTH, this.objectDepth);
ds.setAttribute(DataConstant.IDENTIFIER, this.objectName);
ds.setAttribute(TrackingConstant.SCREENOVERSIZE, (this.overSize/100.0));
ds.setAttribute(TrackingConstant.REMOTEHOST, this.host);
ds.setAttribute(TrackingConstant.REMOTEPORT, this.port);
ds.setAttribute(TrackingConstant.BACKFACETRACKING, this.backFaceTracking);
/*
*
*/
// Vector3d TL, BL, BR, displayUp, displaySide, displayNorm, xVec,yVec,zVec,pv,ov, rv;
// String chunks[] = displayTL.split(",");
// TL = new Vector3d(Double.parseDouble(chunks[0]),
// Double.parseDouble(chunks[1]),
// Double.parseDouble(chunks[2]));
// chunks = displayBL.split(",");
// BL = new Vector3d(Double.parseDouble(chunks[0]),
// Double.parseDouble(chunks[1]),
// Double.parseDouble(chunks[2]));
// chunks = displayBR.split(",");
// BR = new Vector3d(Double.parseDouble(chunks[0]),
// Double.parseDouble(chunks[1]),
// Double.parseDouble(chunks[2]));
//
// displayUp = (Vector3d) TL.clone();
// displayUp.sub(BL);
// double height = displayUp.length();
// displayUp.normalize();
// displaySide = (Vector3d) BR.clone();
// displaySide.sub(BL);
// double with = displaySide.length();
// displaySide.normalize();
// displayNorm = new Vector3d();
// displayNorm.cross(displayUp, displaySide);
// displayNorm.normalize();
// System.out.println("displayUP " + displayUp.toString());
// System.out.println("displaySide " + displaySide.toString());
// xVec = new Vector3d(1,0,0);
// yVec = new Vector3d(0,1,0);
// zVec = new Vector3d(0,0,-1);
// double angleX, angleY, angleZ;
// angleX = yVec.angle(displayUp);
// angleY = zVec.angle(displayNorm);
// angleZ = xVec.angle(displaySide);
// System.out.println("angles " + Math.toDegrees(angleX) + " " + Math.toDegrees(angleY) + " " + Math.toDegrees(angleZ));
// MathUtility mu = new MathUtility();
// //double[][] mRot = mu.rotateMatrix(null, -angleX, 0, 0);
// double[][] mRot = mu.rotateMatrix(MathUtility.Y_AXIS, null, -angleY);
// //mRot = mu.transpose(mRot);
// pv = new Vector3d(0,0,1);
// ov = new Vector3d(0,0,0);
// rv = mu.rotatePoint(pv, ov, mRot, false);
// System.out.println("rotation vector Y" + rv.toString());
// angleZ = rv.angle(displaySide);
// mRot = mu.rotateMatrix(MathUtility.Z_AXIS, mRot, -angleZ);
// pv = new Vector3d(0,0,1);
// rv = mu.rotatePoint(pv, ov, mRot, false);
// System.out.println("rotation vector Z" + rv.toString());
// angleX = rv.angle(displayNorm);
// mRot = mu.rotateMatrix(MathUtility.X_AXIS, mRot, -angleX);
// pv = new Vector3d(1,0,0);
// rv = mu.rotatePoint(pv, ov, mRot, false);
// System.out.println("rotation vector Y" + rv.toString());
//BL.scaleAdd(height, pv);
//BL.sub(rv);
// System.out.println("BL " + BL.toString());
// BL.add(rv);
// System.out.println("NL " + BL.toString());
// System.out.println("BR " + BR.toString());
return ds;
}
/* (non-Javadoc)
* @see org.squidy.manager.model.AbstractNode#preProcess(org.squidy.manager.data.IDataContainer)
*/
private boolean keyPressed;
public void process(DataDigital dataDigital)
{
if (dataDigital.hasAttribute(Keyboard.KEY_EVENT))
{
Integer key_event = (Integer) dataDigital.getAttribute(Keyboard.KEY_EVENT);
if (KeyStroke.getKeyStroke(this.keyStroke) == KeyStroke.getKeyStroke(key_event.intValue(),0))
{
if (dataDigital.getFlag())
keyPressed = !keyPressed;
dataDigital.killAll();
}
}
}
private MathUtility mu = new MathUtility();
public IData process(DataPosition6D d6d)
{
if (d6d.hasAttribute(TrackingConstant.RIGIDBODYROLE) && !keyPressed)
{
if (Integer.valueOf(d6d.getAttribute(TrackingConstant.RIGIDBODYROLE).toString()) == TrackingConstant.RBROLE_MOBILEDISPLAY)
{
d6d.setAttribute(TrackingConstant.OBJECTHEIGHT, this.objectHeight);
d6d.setAttribute(TrackingConstant.OBJECTWIDHT, this.objectWidth);
d6d.setAttribute(TrackingConstant.OBJECTDEPTH, this.objectDepth);
d6d.setAttribute(TrackingConstant.RIGIDBODYROLE, d6d.getAttribute(TrackingConstant.RIGIDBODYROLE));
d6d.setAttribute(DataConstant.IDENTIFIER, this.objectName);
d6d.setAttribute(DataConstant.IDENTIFIER, this.objectName);
d6d.setAttribute(TrackingConstant.SCREENOVERSIZE, this.overSize/100.0);
d6d.setAttribute(TrackingConstant.REMOTEHOST, this.host);
d6d.setAttribute(TrackingConstant.REMOTEPORT, this.port);
d6d.setAttribute(TrackingConstant.BACKFACETRACKING, this.backFaceTracking);
String[] chunks = this.displayOffset.split(",");
/*d6d = TrackingUtility.Norm2RoomCoordinates(Optitrack.class, d6d);
//Vector3d offsetRot = new Vector3d(Double.parseDouble(chunks[0]),Double.parseDouble(chunks[1]),Double.parseDouble(chunks[2]));
DataPosition3D offsetRot = new DataPosition3D();
offsetRot.setX(Double.parseDouble(chunks[0]));
offsetRot.setY(Double.parseDouble(chunks[1]));
offsetRot.setZ(Double.parseDouble(chunks[2]));
offsetRot = mu.rotatePoint(offsetRot, d6d, d6d, true,false);
//System.out.println(offsetRot.getX() + "\t"+ offsetRot.getY() + "\t"+ offsetRot.getZ());
d6d.setX(d6d.getX() + offsetRot.getX());
d6d.setY(d6d.getY() + offsetRot.getY());
d6d.setZ(d6d.getZ() + offsetRot.getZ());
// d6d.setX(d6d.getX()- Double.parseDouble(chunks[0]));
// d6d.setY(d6d.getY()- Double.parseDouble(chunks[1]));
// d6d.setZ(d6d.getZ()- Double.parseDouble(chunks[2]));
d6d = TrackingUtility.Room2NormCoordinates(Optitrack.class, d6d);*/
// System.out.println("d6dm0 " + d6d.getM00() + " \t " + d6d.getM01() + " \t " + d6d.getM02());
// System.out.println("d6dm1 " + d6d.getM10() + " \t " + d6d.getM11() + " \t " + d6d.getM12());
// System.out.println("d6dm2 " + d6d.getM20() + " \t " + d6d.getM21() + " \t " + d6d.getM22());
// System.out.println("");
//System.out.println(d6d.getM20()+"\t"+d6d.getM22()+"\t"+d6d.getM21()+"\t"+displayNorm.x+"\t"+displayNorm.y+"\t"+displayNorm.z);
// System.out.println(d6d.getAttribute(TrackingConstant.OBJECTHEIGHT));
//System.out.println(d6d.getYaw()+"\t"+d6d.getPitch()+"\t"+d6d.getRoll());
return d6d;
}
}
return null;
}
}
// * m6d = mu.rotateMatrix(MathUtility.Y_AXIS, null, (yVec.angle(displayNorm)));
// m6d = mu.rotateMatrix(MathUtility.Z_AXIS, m6d, (zVec.angle(displayNorm)));
// m6d = mu.rotateMatrix(MathUtility.X_AXIS, m6d, (xVec.angle(displayNorm)));
// m6d = mu.transpose(m6d);
// m6d2 = mu.rotateMatrix(MathUtility.Y_AXIS, null, (yVec.angle(n1)));
// m6d2 = mu.rotateMatrix(MathUtility.Z_AXIS, m6d2, (zVec.angle(n1)));
// m6d2 = mu.rotateMatrix(MathUtility.X_AXIS, m6d2, (xVec.angle(n1)));
//
// /*System.out.println("m6 " + m6d[0][0] +"\t"+ m6d[0][1] + "\t"+ m6d[0][2]);
// System.out.println("m6 " + m6d[1][0] +"\t"+ m6d[1][1] + "\t"+ m6d[1][2]);
// System.out.println("m6 " + m6d[2][0] +"\t"+ m6d[2][1] + "\t"+ m6d[2][2]);
// System.out.println();
// System.out.println("m6 " + m6d2[0][0] +"\t"+ m6d2[0][1] + "\t"+ m6d2[0][2]);
// System.out.println("m6 " + m6d2[1][0] +"\t"+ m6d2[1][1] + "\t"+ m6d2[1][2]);
// System.out.println("m6 " + m6d2[2][0] +"\t"+ m6d2[2][1] + "\t"+ m6d2[2][2]);*/
//
// m6d3[0][0] = m6d[0][0]*m6d2[0][0]+ m6d[0][1]*m6d2[1][0]+ m6d[0][2]*m6d2[2][0];
// m6d3[0][1] = m6d[0][0]*m6d2[0][1]+ m6d[0][1]*m6d2[1][1]+ m6d[0][2]*m6d2[2][1];
// m6d3[0][2] = m6d[0][0]*m6d2[0][2]+ m6d[0][1]*m6d2[1][2]+ m6d[0][2]*m6d2[2][2];
//
// m6d3[1][0] = m6d[1][0]*m6d2[0][0]+ m6d[1][1]*m6d2[1][0]+ m6d[1][2]*m6d2[2][0];
// m6d3[1][1] = m6d[1][0]*m6d2[0][1]+ m6d[1][1]*m6d2[1][1]+ m6d[1][2]*m6d2[2][1];
// m6d3[1][2] = m6d[1][0]*m6d2[0][2]+ m6d[1][1]*m6d2[1][2]+ m6d[1][2]*m6d2[2][2];
//
// m6d3[2][0] = m6d[2][0]*m6d2[0][0]+ m6d[2][1]*m6d2[1][0]+ m6d[2][2]*m6d2[2][0];
// m6d3[2][1] = m6d[2][0]*m6d2[0][1]+ m6d[2][1]*m6d2[1][1]+ m6d[2][2]*m6d2[2][1];
// m6d3[2][2] = m6d[2][0]*m6d2[0][2]+ m6d[2][1]*m6d2[1][2]+ m6d[2][2]*m6d2[2][2];
// m6d3 = mu.transpose(m6d3);
// System.out.println("m6 " + m6d3[0][0] +"\t"+ m6d3[0][1] + "\t"+ m6d3[0][2]);
// System.out.println("m6 " + m6d3[1][0] +"\t"+ m6d3[1][1] + "\t"+ m6d3[1][2]);
// System.out.println("m6 " + m6d3[2][0] +"\t"+ m6d3[2][1] + "\t"+ m6d3[2][2]);
// System.out.println();
// //m6d = mu.rotateMatrix(null, xVec.angle(displayNorm), yVec.angle(displayNorm), zVec.angle(displayNorm));
// //m6d2 = mu.rotateMatrix(null, xVec.angle(n2), yVec.angle(n2), zVec.angle(n2));
// //m6d = mu.rotateMatrix(m6d, xVec.angle(n1), yVec.angle(n1), zVec.angle(n1));
//
//
//
// double[] p1 = {0,0,1};
// double[] p2 = {0,1,0};
// double[] o1 = {0,0,0};
//
//// System.out.println();
//// System.out.println("m6 " + m6d[0][0] +"\t"+ m6d[0][1] + "\t"+ m6d[0][2]);
//// System.out.println("m6 " + m6d[1][0] +"\t"+ m6d[1][1] + "\t"+ m6d[1][2]);
//// System.out.println("m6 " + m6d[2][0] +"\t"+ m6d[2][1] + "\t"+ m6d[2][2]);
//
// //m6d = mu.transpose(m6d);
//
// Matrix3d m3d = new Matrix3d();
// Matrix3d m3d2 = new Matrix3d();
// m3d.m00 = 1;
// m3d.m11 = 1;
// m3d.m22 = 1;
// m3d2 = m3d;
//
// m3d.rotY(yVec.angle(displayNorm));
// m3d.rotZ(zVec.angle(displayNorm));
// //System.out.println("m3d\n " + m3d);
// //m3d.rotX(xVec.angle(displayNorm));
// m3d2.rotZ(zVec.angle(displayNorm));
// //System.out.println("m3d2\n " + m3d2);
// f1 = mu.rotatePoint(p1, o1, m6d3, false);
// //System.out.println("f1 " + (f1[0]) + "\t"+(f1[1])+"\t"+(f1[2]));
// Vector3d out3d = new Vector3d(-f1[2],f1[0],f1[2]);
// System.out.println("displaynorm " + displayNorm.toString());
// System.out.println();
// System.out.println("out3d " + out3d.toString());
//
// System.out.println("");