00001 package edu.tum.cs.ias.knowrob.vis.applets;
00002 
00003 import java.awt.event.MouseEvent;
00004 import java.awt.event.MouseListener;
00005 import java.awt.event.MouseMotionListener;
00006 import java.io.Serializable;
00007 import java.util.ArrayList;
00008 import java.util.HashMap;
00009 
00010 import processing.core.PApplet;
00011 import processing.core.PFont;
00012 import processing.core.PGraphics;
00013 import processing.core.PGraphics3D;
00014 import controlP5.ControlEvent;
00015 import controlP5.RadioButton;
00016 
00017 public class ActionVisApplet extends PApplet implements MouseListener, MouseMotionListener {
00018 
00019   static final long serialVersionUID=0;
00020 
00021   PGraphics buffer;
00022   private PrologVisualizationCanvas prologVisCanvas = null;
00023 
00025   
00026   
00027   
00028   
00029   float leftMouseX=-1.0f, leftMouseY=-1.0f, rightMouseX=-1.0f, rightMouseY=-1.0f, centerMouseY=-1.0f;
00030   float xRotDisplay=-2.549f, yRotDisplay=86.79f, xShiftDisplay=410f, yShiftDisplay=15f, zoomDisplay=1f;
00031 
00032   PFont verdana;
00033   PFont verdanaBold;
00034   PFont dejavu;
00035 
00036   ArrayList<String> actionTypes;
00037   ArrayList<String> objectTypes;
00038     
00040   
00041   ArrayList<Integer> colors = new ArrayList<Integer>(12);       
00042 
00043   
00044   private ArrayList<ArrayList<ActionInformation>> leftHandActions = new ArrayList<ArrayList<ActionInformation>>();
00045   private ArrayList<ArrayList<ActionInformation>> rightHandActions = new ArrayList<ArrayList<ActionInformation>>();
00046   
00047   private HashMap<Integer, String> color2id = new HashMap<Integer, String>();
00048   
00050   
00051   
00052   public int actionIndex = 0;                   
00053   private int idColor=0xFFFF0000;
00054 
00056   
00057   
00058   int maxLevel = 1000;
00059   boolean initialize = false;
00060 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079         
00080         
00081   
00082   public void setup() {
00083 
00084     actionTypes= new ArrayList<String>();
00085     objectTypes= new ArrayList<String>();
00086                      
00087                 size(550, 600, PGraphics3D.P3D);
00088                 buffer = createGraphics(width, height, PGraphics3D.P3D);
00089     lights();
00090     
00091     verdana = createFont("Verdana", 11);
00092     verdanaBold = createFont("Verdana-Bold", 18);
00093     dejavu = createFont("DejaVu Sans",13);
00094     
00095     textFont(verdana);
00096     textFont(verdanaBold);
00097     textFont(dejavu);    
00098     hint(ENABLE_ACCURATE_TEXTURES);
00099     
00100     
00101     ellipseMode(RADIUS);
00102     frameRate(20);
00103     
00104     setColors();
00105 
00106     noLoop();
00107     draw();
00108     
00109     if(prologVisCanvas != null) prologVisCanvas.validate();
00110     
00111   }
00112 
00113 
00114   public void draw() {
00115     
00116         background(20, 20, 20);
00117         
00118     cursor(CROSS);
00119     ortho(-width/2, width/2, -height/2, height/2, -10, 10); 
00120 
00121     pushMatrix();
00122 
00123             translate(xShiftDisplay, yShiftDisplay, 0.0f);
00124                 
00125             rotateX( radians(xRotDisplay) );  
00126             rotateY( radians( yRotDisplay) );
00127     
00128         translate(2000f, height, -400.0f);
00129     
00130         
00131 
00132         
00133         lights();
00134         pushMatrix();
00135               
00136                   textFont(verdana);
00137                   textMode(SCREEN);
00138                   textAlign(CENTER);
00139                   fill(0xFFFFFFFF);stroke(0xFFFFFFFF);
00140                   
00141                   text("left hand",  screenX(0, 25, -50), screenY(0, 25, -50));
00142                   text("right hand", screenX(0, 25, 50),  screenY(0, 25, 50));
00143         
00144                   text("abstraction level", screenX(0, -200, 0),  screenY(0, -200, 0));
00145                   
00146           strokeWeight(2);
00147               line(0, 0, 0,   1000, 0, 0);
00148               line(0, 0, 0,   0, -180, 0);
00149                       line(0, -180, 0,   0, -170, -5);
00150                       line(0, -180, 0,   0, -170, 5);
00151               
00152               line(0, 0, -100,   0, 0, 100);
00153 
00154         popMatrix(); 
00155 
00156         pushMatrix();
00157                 drawActionSequence(this.g, false);
00158         popMatrix(); 
00159               
00160     popMatrix();
00161 
00162         
00163  }
00164   
00165   
00169   
00170   
00171   
00172 
00173   public void drawActionSequence(PGraphics g, boolean isBuffer) {
00174 
00175         g.noStroke();
00176         int i=0;
00177         
00178         if(leftHandActions.size()<1) return;
00179         if(rightHandActions.size()<1) return;
00180 
00181         int level=0;
00182         while(level <= maxLevel) {
00183                 
00184                 ArrayList<ArrayList<ActionInformation>> actions;
00185                 for(String side: new String[]{"left", "right"}) {
00186                         
00187                         if(side.equals("left")) actions=leftHandActions;
00188                         else                                    actions=rightHandActions;
00189                 
00190                         
00191                         if(level>=actions.size()) continue; 
00192                         for (i=0; i< actions.get(level).size(); i++) {
00193                                 
00194                                 if(i>=actions.get(level).size()) continue;
00195                                 
00196                                 ActionInformation action  = actions.get(level).get(i);
00197 
00198 
00199                                 float actionLengthFactor = 1.0f;
00200                                 float start = actionLengthFactor*action.getStarttime();
00201                                 float end   = actionLengthFactor*action.getEndtime();
00202                                 if(end==-1) end=start;
00203                                 
00204                                 float yshift = -40 * level;
00205                                 float zshift = (side.equals("left"))?(-40):(40);
00206 
00207                                 g.pushMatrix();
00208                                         g.fill(this.getColor(actions.get(level).get(i), isBuffer));
00209                                         
00210                                         g.translate(100*start   
00211                                                         +50*(end-start) 
00212                                                                         
00213                                                         -(100*actionLengthFactor*actions.get(0).get(actionIndex).getTime()),yshift,zshift);
00214                                         g.box(((end==start)?(1):(100*(end-start))), 20, 40);                    
00215                                 g.popMatrix();
00216 
00217                                 
00218                         }
00219 
00220                 }
00221                 
00222                 level++;
00223         }
00224   }
00225 
00226 
00227   private int getColor(ActionInformation item, boolean isBuffer) {
00228 
00229           
00230           if(isBuffer)
00231                   return(item.getIdColor());
00232           
00233           
00234           if(item.endtime==-1) {
00235                   return (0xFF000000 + (((int)(80*item.starttime++)%200)<< 16));
00236           }
00237           
00238           
00239           if(prologVisCanvas != null && (prologVisCanvas.controlP5.getController("color_radio")!=null) && ((RadioButton) prologVisCanvas.controlP5.getGroup("color_radio")).getValue()==0) {
00240                   
00241                   
00242                   String[] act = item.getTypes();
00243                   if(!actionTypes.contains(act[0])) {actionTypes.add(act[0]);}
00244                   int idx = actionTypes.indexOf(act[0]);
00245                   if(idx<0 || idx>this.colors.size()) {System.out.println("Missing color for " + act[0]); return 0;}
00246                   return this.colors.get(idx);
00247           
00248           } else if(prologVisCanvas != null && (prologVisCanvas.controlP5.getController("color_radio")!=null) && ((RadioButton) prologVisCanvas.controlP5.getGroup("color_radio")).getValue()==1) {
00249                   
00250                   
00251                   String obj = item.getObjecttype();
00252                   if(!objectTypes.contains(obj)) {objectTypes.add(obj);}
00253                   int idx = objectTypes.indexOf(obj);
00254                   
00255                   if(idx<0 || idx>this.colors.size()) {System.out.println("Missing color for " + obj);  return 0;}
00256                   
00257                   return this.colors.get(idx);
00258                   
00259           } else if(prologVisCanvas != null && (prologVisCanvas.controlP5.getController("color_radio")!=null) && ((RadioButton) prologVisCanvas.controlP5.getGroup("color_radio")).getValue()==2) {
00260                   
00261                   
00262                   if(item.isInActivity()) {
00263                           return 0xFF00CC00;
00264                   }
00265                   else return 0xFFCC0000;
00266           }
00267           return 0;
00268   }
00269   
00270   
00271 
00272   
00273   
00277   
00278   
00279   
00280 
00281   public void setActionInformation(String[][][] pl_list, String hand, int level) {
00282         
00283           try{
00284           
00285         
00286         ArrayList<ActionInformation> actionlist = new ArrayList<ActionInformation>();
00287         for(String[][] infos : pl_list) {
00288                 
00289                 String label = infos[0][0];
00290                 
00291                 float starttime=0.0f;
00292                 try{
00293                         starttime=Float.valueOf(infos[1][0]);
00294                 } catch(NumberFormatException e) {
00295                         starttime=Float.valueOf((infos[1][0].split("#"))[1]);
00296                 }
00297                 
00298                 float endtime=0.0f;
00299                 try{
00300                         endtime=Float.valueOf(infos[2][0]);
00301                 } catch(NumberFormatException e) {
00302                         endtime=Float.valueOf((infos[2][0].split("#"))[1]);
00303                 }
00304 
00305                 String[] types = infos[3];
00306                 String objecttype = infos[4][0];
00307                 
00308                 color2id.put(idColor, label);
00309                 actionlist.add(new ActionInformation(label, starttime, endtime, types, objecttype, idColor++));
00310                 
00311         }
00312         
00313         int l = Integer.valueOf(level);
00314         
00315         while(l>=leftHandActions.size()) {
00316                 leftHandActions.add(new ArrayList<ActionInformation>());
00317         }
00318 
00319         while(l>=rightHandActions.size()) {
00320                 rightHandActions.add(new ArrayList<ActionInformation>());
00321         }
00322         
00323         if(hand.equals("left"))
00324                 this.leftHandActions.set(l, actionlist);
00325         else
00326                 this.rightHandActions.set(l, actionlist);
00327         
00328           } catch(Exception e) {
00329                   e.printStackTrace();
00330           }
00331         
00332         this.redraw();
00333   }
00334 
00335 
00336   public void setActionsInActivity(Object[] actions) {
00337           System.out.println(actions.toString());
00338           for(Object act : actions) {
00339                   System.out.println(act.toString());
00340                   for(ArrayList<ActionInformation> alist : this.leftHandActions) {
00341                           for(ActionInformation ainfo : alist) {
00342                                   if(("'"+ainfo.getLabel()+"'").equals(act.toString())) {
00343                                           ainfo.setInActivity(true);
00344                                   }
00345                           }
00346                   }
00347           }       
00348           for(Object act : actions) {
00349                   for(ArrayList<ActionInformation> alist : this.rightHandActions) {
00350                           for(ActionInformation ainfo : alist) {
00351                                   if(("'"+ainfo.getLabel()+"'").equals(act.toString())) {
00352                                           ainfo.setInActivity(true);
00353                                   }
00354                           }
00355                   }
00356           }
00357   }
00358         
00359     
00360     
00364     
00365     
00366     
00367 
00368         
00369   public void mousePressed(MouseEvent e) {
00370           
00371           
00372           if(e.getButton()==MouseEvent.BUTTON1) {
00373                         leftMouseX = e.getX();
00374                         leftMouseY = e.getY();
00375           } else if(e.getButton()==MouseEvent.BUTTON3) {
00376                         rightMouseX = e.getX();
00377                         rightMouseY = e.getY();
00378           } else if (e.getButton()==MouseEvent.BUTTON2) {
00379                         centerMouseY = e.getY();
00380           }
00381 
00382                                  
00383         }
00384   
00385   
00386         public void mouseReleased(MouseEvent e) {
00387                 
00388                 if(e.getButton()==MouseEvent.BUTTON1) { 
00389                         leftMouseX = -1.0f;
00390                         leftMouseY = -1.0f;
00391                 } else if(e.getButton()==MouseEvent.BUTTON3) {  
00392                         rightMouseX = -1.0f;
00393                         rightMouseY = -1.0f;
00394                 } else if (e.getButton()==MouseEvent.BUTTON2) {
00395                         centerMouseY = -1.0f;
00396                 }
00397         
00398         }
00399 
00400     public void mouseDragged(MouseEvent e) {
00401 
00402 
00403         if(leftMouseX != -1.0f) {       
00404                   xRotDisplay+= (e.getY()-leftMouseY) * 0.05;
00405                   yRotDisplay-= (e.getX()-leftMouseX) * 0.05;
00406                         leftMouseX = e.getX();
00407                         leftMouseY = e.getY();
00408                 
00409                 }else if(rightMouseX != -1.0f) {        
00410                   yShiftDisplay+= (e.getY()-rightMouseY) * 0.5;
00411                   xShiftDisplay+= (e.getX()-rightMouseX) * 0.5;
00412                         rightMouseX = e.getX();
00413                         rightMouseY = e.getY();
00414                 
00415                 } else if (centerMouseY != -1.0f) {     
00416                           zoomDisplay+= (e.getY()-centerMouseY) * 0.02;
00417                           if(zoomDisplay<0.01){zoomDisplay=0.01f;}
00418                           centerMouseY = e.getY();
00419                 }
00420         
00421         redraw();
00422     }
00423     
00424     public void mouseClicked() {
00425 
00426           
00427           buffer.beginDraw();
00428           buffer.background(0); 
00429           
00430             buffer.ortho(-width/2, width/2, -height/2, height/2, -10, 10); 
00431 
00432             buffer.pushMatrix();
00433 
00434                     buffer.translate(xShiftDisplay, yShiftDisplay, 0.0f);
00435                         
00436                     buffer.rotateX( radians(xRotDisplay) );  
00437                     buffer.rotateY( radians( yRotDisplay) );
00438             
00439                     buffer.translate(2000f, height, -400.0f);
00440                 drawActionSequence(buffer, true);
00441                 
00442             buffer.popMatrix();
00443           buffer.endDraw();
00444          
00445           
00446           int pick = buffer.get(mouseX, mouseY);
00447           
00448           String id = this.color2id.get(pick);
00449           if(id!=null && prologVisCanvas != null) {
00450                           prologVisCanvas.displayAction(id);
00451                           prologVisCanvas.mapObjectClicked(id);
00452           }
00453     }
00454     
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484     
00485     
00486     public      void controlEvent(ControlEvent theEvent) {
00487         if(prologVisCanvas != null && theEvent.isGroup() && theEvent.getGroup().getId()==100) {
00488                 
00489                 this.maxLevel =(int)prologVisCanvas.controlP5.getGroup("act_radio").getValue();
00490 
00491         } else if(theEvent.isGroup() && theEvent.getGroup().getId()==101) {
00492                 
00493         }
00494         redraw();
00495     }
00496     
00497 
00498   public int makeColor(int r,int g,int b){
00499           int col = 0xFF000000 + 0x0000FF00 * r + 0x000000FF * g + b;
00500           return col;
00501     }
00502   
00503   public void setPrologVisCanvas(PrologVisualizationCanvas c){
00504           prologVisCanvas = c;
00505   }
00506     
00507     
00508     public void setColors(){
00509 
00510         for(int[] c : new int[][]{      
00511                                                         
00512                                                         {255,255,153},  {255,153,153},          {153,0,102},
00513                                                         {51,0,51},      {102,102,102},          {102,51,153},
00514                                                         {255,204,0},    {255,51,0},             {153,204,0},
00515                                                         {204,153,0},    {255,255,255},          {255,153,102},
00516                                                         {102,0,0},      {204,255,102},          {102,102,51},
00517                                                         {204,204,204},  {255,255,51},           {153,102,102},
00518                                                         {153,0,51},     {153,153,153},          {51,153,0},
00519                                                         {102,153,204},  {51,51,204},            {0,153,102},
00520                                                         {102,255,204},  {0,0,204},
00521                                                         {102,153,204},  {51,51,204},            {0,153,102},
00522                                                         {255,255,153},  {255,153,153},          {153,0,102},
00523                                                         {153,0,51},     {153,153,153},          {51,153,0},
00524                                                         {51,0,51},      {102,102,102},          {102,51,153},
00525                                                         {204,204,204},  {255,255,51},           {153,102,102},
00526                                                         {102,0,0},      {204,255,102},          {102,102,51},
00527                                                         {204,153,0},    {255,255,255},          {255,153,102},
00528                                                         {255,204,0},    {255,51,0},             {153,204,0},
00529                                                         {102,255,204},  {0,0,204}}) {
00530                 colors.add(makeColor(c[0], c[1], c[2]));
00531         }
00532         
00533 
00534     }       
00535 
00536     
00537         private class ActionInformation implements Serializable {
00538                 
00539                 private static final long serialVersionUID = -1005928838950117046L;
00540                 private String label;
00541                 private float starttime;
00542                 private float endtime=-1;
00543                 private String[] types;
00544                 private String objecttype;
00545                 private int idColor;
00546                 private boolean inActivity;
00547 
00548 
00549                 public ActionInformation(String label, float starttime, float endtime, String[] types, String objecttype, int idColor) {
00550                         super();
00551                         this.label = label;
00552                         this.starttime = starttime;
00553                         this.endtime = endtime;
00554                         this.types = types;
00555                         this.objecttype = objecttype;
00556                         this.idColor = idColor;
00557                         this.inActivity = false;
00558                 }
00559 
00560 
00561                 @SuppressWarnings("unused")
00562                 public ActionInformation(String label, float time, String[] types, String objecttype, int idColor) {
00563                         super();
00564                         this.label = label;
00565                         this.starttime = time;
00566                         this.types = types;
00567                         this.objecttype = objecttype;
00568                         this.idColor = idColor;
00569                         this.inActivity = false;
00570                 }
00571 
00572 
00573                 public String getLabel() {
00574                         return label;
00575                 }
00576 
00577 
00578                 @SuppressWarnings("unused")
00579                 public void setLabel(String label) {
00580                         this.label = label;
00581                 }
00582 
00583 
00584                 public String getObjecttype() {
00585                         return objecttype;
00586                 }
00587 
00588 
00589                 @SuppressWarnings("unused")
00590                 public void setObjecttype(String objecttype) {
00591                         this.objecttype = objecttype;
00592                 }
00593 
00594 
00595                 public float getTime() {
00596                         return starttime;
00597                 }
00598 
00599 
00600                 public int getIdColor() {
00601                         return idColor;
00602                 }
00603 
00604 
00605                 @SuppressWarnings("unused")
00606                 public void setIdColor(int idColor) {
00607                         this.idColor = idColor;
00608                 }
00609 
00610 
00611                 @SuppressWarnings("unused")
00612                 public void setTime(float time) {
00613                         this.starttime = time;
00614                 }
00615 
00616 
00617                 public String[] getTypes() {
00618                         return types;
00619                 }
00620 
00621 
00622                 @SuppressWarnings("unused")
00623                 public void setTypes(String[] types) {
00624                         this.types = types;
00625                 }
00626 
00627 
00628                 public float getEndtime() {
00629                         return endtime;
00630                 }
00631 
00632 
00633                 @SuppressWarnings("unused")
00634                 public void setEndtime(float endtime) {
00635                         this.endtime = endtime;
00636                 }
00637 
00638 
00639                 public float getStarttime() {
00640                         return starttime;
00641                 }
00642 
00643 
00644                 @SuppressWarnings("unused")
00645                 public void setStarttime(float starttime) {
00646                         this.starttime = starttime;
00647                 }
00648                 
00649                 public boolean isInActivity() {
00650                         return inActivity;
00651                 }
00652 
00653 
00654                 public void setInActivity(boolean inActivity) {
00655                         this.inActivity = inActivity;
00656                 }
00657 
00658         }
00659 
00660         
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 
00679 
00680         
00681         public static void main(String args[]) {
00682                 PApplet.main(new String[] { "de.tum.in.fipm.kipm.gui.visualisation.applets.ActionVisApplet" });
00683         }
00684 }
00685