$search
00001 package edu.tum.cs.ias.knowrob.vis; 00002 00003 import java.awt.Color; 00004 import java.awt.Dimension; 00005 import java.awt.Frame; 00006 import java.awt.GraphicsDevice; 00007 import java.awt.GraphicsEnvironment; 00008 import java.awt.Insets; 00009 import java.awt.Label; 00010 import java.awt.SystemColor; 00011 import java.awt.event.MouseAdapter; 00012 import java.awt.event.MouseEvent; 00013 import java.awt.event.MouseListener; 00014 import java.awt.event.MouseMotionListener; 00015 import java.awt.event.WindowAdapter; 00016 import java.awt.event.WindowEvent; 00017 import java.util.Vector; 00018 import javax.vecmath.Matrix4f; 00019 00020 import javax.vecmath.Vector3f; 00021 00022 import processing.core.PApplet; 00023 import processing.core.PFont; 00024 import processing.core.PGraphics3D; 00025 00026 00027 public class Canvas extends PApplet implements MouseListener, MouseMotionListener { 00028 static final long serialVersionUID = 0; 00029 00033 protected int width = 800, height = 600; 00034 00038 protected boolean useCamera; 00039 00043 protected float leftMouseX = -1.0f, leftMouseY = -1.0f, rightMouseX = -1.0f, rightMouseY = -1.0f, centerMouseY = -1.0f; 00044 00048 protected float xRotDisplay, yRotDisplay, xShiftDisplay, yShiftDisplay, zShiftDisplay, zoomDisplay; 00049 00053 protected Vector3f eye, eyeTarget, eyeUp; 00054 00058 protected float sceneSize = 4000; 00059 00060 public boolean debugCamera; 00061 00065 Vector<Drawable> items = new Vector<Drawable>(); 00066 Vector<Drawable> items2D = new Vector<Drawable>(); 00067 00072 public void setWidth(int width) { 00073 this.width = width; 00074 } 00075 00080 public void setHeight(int height) { 00081 this.height = height; 00082 } 00083 00084 public int getHeight() { 00085 return height; 00086 } 00087 00088 public int getWidth() { 00089 return width; 00090 } 00091 00092 public void setSceneSize(float size) { 00093 this.sceneSize = size; 00094 this.zoomDisplay = 400 / sceneSize; 00095 } 00096 00097 public Canvas() { 00098 useCamera = false; 00099 debugCamera = false; 00100 eye = new Vector3f(50.0f,50f,20f); 00101 eyeUp = new Vector3f(0,0,500); 00102 eyeTarget = new Vector3f(0,0,0); 00103 setStandardViewParams(); 00104 } 00105 00109 public void setStandardViewParams() { 00110 xRotDisplay = -106.25027f; 00111 yRotDisplay = 0.020062504f; 00112 xShiftDisplay = 103f; 00113 zShiftDisplay = 162f; 00114 setSceneSize(this.sceneSize); 00115 } 00116 00117 public void setEyeTarget(Vector3f v) { 00118 this.eyeTarget.set(v); 00119 } 00120 00121 public void setup() { 00122 size(width, height, PGraphics3D.P3D); 00123 lights(); 00124 00125 PFont font = createFont("Verdana", 12); 00126 textFont(font); 00127 00128 ellipseMode(RADIUS); 00129 frameRate(20); 00130 00131 noLoop(); 00132 draw(); 00133 } 00134 00135 public void draw() { 00136 00137 background(60, 60, 60); 00138 cursor(CROSS); 00139 00140 if(!useCamera) { 00141 camera(); 00142 00143 pushMatrix(); 00144 translate(width / 4.0f, height / 1.5f, -400.0f); 00145 00146 lights(); 00147 00148 rotateZ(PI / 2); 00149 rotateY(-PI / 2); 00150 translate(0.0f, zShiftDisplay, xShiftDisplay); 00151 00152 rotateZ(radians(xRotDisplay)); 00153 rotateX(radians(yRotDisplay)); 00154 00155 scale(zoomDisplay); 00156 00157 //System.out.println("zoom: " + zoomDisplay + " zShift: " + zShiftDisplay + " xShift: " + xShiftDisplay + " xRot: " + xRotDisplay + " yRot: " + yRotDisplay); 00158 } 00159 else { 00160 lights(); 00161 //beginCamera(); 00162 setCamera(); 00163 } 00164 00165 preDrawItems(); 00166 00167 drawItems(); 00168 00169 // draw camera vectors 00170 if(debugCamera) { 00171 float coordlength = sceneSize / 8; 00172 Vector3f up = new Vector3f(eyeUp); 00173 up.scale(coordlength); 00174 up.add(eyeTarget); 00175 this.drawLine(eyeTarget, up, 0xff0000ff); 00176 Vector3f dir = new Vector3f(eyeTarget); 00177 dir.sub(eye); 00178 Vector3f third = new Vector3f(); 00179 third.cross(dir, up); 00180 third.normalize(); 00181 third.scale(coordlength); 00182 third.add(eyeTarget); 00183 this.drawLine(eyeTarget, third, 0xff00ff00); 00184 this.drawLine(eye, eyeTarget, 0xffff0000); 00185 } 00186 00187 if(!useCamera) 00188 popMatrix(); 00189 else { 00190 //endCamera(); 00191 } 00192 00193 for(Drawable d : items2D) 00194 d.draw(this); 00195 } 00196 00197 protected void preDrawItems() { 00198 00199 } 00200 00201 protected void setCamera() { 00202 //beginCamera(); 00203 camera(eye.x, eye.y, eye.z, eyeTarget.x, eyeTarget.y, eyeTarget.z, eyeUp.x, eyeUp.y, eyeUp.z); 00204 //camera(eye.x, eye.y, eye.z, eyeTarget.x, eyeTarget.y, eyeTarget.z, eye.x+eyeUp.x, eye.y+eyeUp.y, eye.z+eyeUp.z); 00205 //endCamera(); 00206 00207 //System.out.println("eye: " + eye + " -> " + eyeTarget + " up: " + eyeUp); 00208 } 00209 00210 public synchronized void drawItems() { 00211 for(Drawable d : items) 00212 d.draw(this); 00213 } 00214 00215 public void drawLine(Vector3f p1, Vector3f p2, int color) { 00216 //pushMatrix(); 00217 drawLine(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color); 00218 //popMatrix(); 00219 } 00220 00221 public void drawLine(float x1, float y1, float z1, float x2, float y2, float z2, int color) { 00222 stroke(color); 00223 line(x1,y1,z1,x2,y2,z2); 00224 } 00225 00226 public synchronized void add(Drawable d) { 00227 this.items.add(d); 00228 } 00229 00230 public synchronized void add2D(Drawable d) { 00231 this.items2D.add(d); 00232 } 00233 00234 public void rotateAxis(double theta, Vector3f rotAxis){ 00235 Matrix4f mat = edu.tum.cs.ias.knowrob.util.datastructures.Vector3f.getRotationMatrix(theta,rotAxis); 00236 applyMatrix(mat.m00, mat.m01, mat.m02, mat.m03, 00237 mat.m10, mat.m11, mat.m12, mat.m13, 00238 mat.m20, mat.m21, mat.m22, mat.m23, 00239 mat.m30, mat.m31, mat.m32, mat.m33); 00240 } 00241 00245 // 00246 // EVENT HANDLERS 00247 // 00248 00249 @Override 00250 public void keyPressed() { 00251 switch(keyCode) { 00252 case java.awt.event.KeyEvent.VK_C: 00253 useCamera = !useCamera; 00254 //setStandardViewParams(); 00255 redraw(); 00256 System.out.println("Turned camera " + (useCamera ? "on" : "off")); 00257 break; 00258 } 00259 // switch(key) { 00260 // case '+': 00261 // zoom(-2); 00262 // redraw(); 00263 // break; 00264 // case '-': 00265 // zoom(2); 00266 // redraw(); 00267 // break; 00268 // } 00269 } 00270 // 00271 // public void mousePressed(MouseEvent e) { 00272 // 00273 // // general: save mouse positions for calculating rotation and translation 00274 // if (e.getButton() == MouseEvent.BUTTON1) { 00275 // leftMouseX = e.getX(); 00276 // leftMouseY = e.getY(); 00277 // } 00278 // else if (e.getButton() == MouseEvent.BUTTON3) { 00279 // rightMouseX = e.getX(); 00280 // rightMouseY = e.getY(); 00281 // } 00282 // else if (e.getButton() == MouseEvent.BUTTON2) { 00283 // centerMouseY = e.getY(); 00284 // } 00285 // 00286 // } 00287 // 00288 // public void mouseReleased(MouseEvent e) { 00289 // 00290 // if (e.getButton() == MouseEvent.BUTTON1) { // reset the buffers 00291 // leftMouseX = -1.0f; 00292 // leftMouseY = -1.0f; 00293 // } 00294 // else if (e.getButton() == MouseEvent.BUTTON3) { // reset the buffers 00295 // rightMouseX = -1.0f; 00296 // rightMouseY = -1.0f; 00297 // } 00298 // else if (e.getButton() == MouseEvent.BUTTON2) { 00299 // centerMouseY = -1.0f; 00300 // } 00301 // 00302 // } 00303 // 00304 // public void mouseDragged(MouseEvent e) { 00305 // 00306 // if (leftMouseX != -1.0f) { // change rotation 00307 // if(!useCamera) { 00308 // yRotDisplay += (e.getY() - leftMouseY) * 0.03; 00309 // xRotDisplay += (e.getX() - leftMouseX) * 0.05; 00310 // } 00311 // else { 00312 // float dx = (e.getX() - leftMouseX) * 0.02f; 00313 // float dy = (e.getY() - leftMouseY) * 0.02f; 00314 // 00315 // // translate eye, so that the origin is its target 00316 // Vector3f negTarget = new Vector3f(eyeTarget); 00317 // negTarget.negate(); 00318 // eye.add(negTarget); 00319 // 00320 // // rotation around vertical axis 00321 // eye.rotate(dx, eyeUp); 00322 // 00323 // // rotation around horizontal axis 00324 // Vector3f dir = new Vector3f(eyeTarget); 00325 // dir.subtract(eye); 00326 // Vector3f horDir = new Vector3f(); 00327 // horDir.cross(eyeUp, dir); 00328 // eye.rotate(dy, horDir); 00329 // //eyeUp.rotate(dy, horDir); 00330 // //eyeUp.normalize(); 00331 // 00332 // // reverse translation 00333 // eye.add(eyeTarget); 00334 // } 00335 // 00336 // leftMouseX = e.getX(); 00337 // leftMouseY = e.getY(); 00338 // } 00339 // else if (rightMouseX != -1.0f) { // change translation 00340 // if(!useCamera) { 00341 // xShiftDisplay += -(e.getY() - rightMouseY) * 0.5; 00342 // zShiftDisplay += -(e.getX() - rightMouseX) * 0.5; 00343 // } 00344 // else { 00345 // float dx = (e.getX() - rightMouseX) * sceneSize / 1000; 00346 // float dy = (e.getY() - rightMouseY) * sceneSize / 1000; 00347 // 00348 // // horizontal translation 00349 // Vector3f dir = new Vector3f(eyeTarget); 00350 // dir.subtract(eye); 00351 // Vector3f horDir = new Vector3f(); 00352 // horDir.cross(eyeUp, dir); 00353 // horDir.normalize(); 00354 // horDir.scale(dx); 00355 // 00356 // // vertical translation 00357 // Vector3f vertDir = new Vector3f(eyeUp); 00358 // vertDir.normalize(); 00359 // vertDir.scale(dy); 00360 // vertDir.negate(); 00361 // //System.out.println("hor move: " + horDir); 00362 // //System.out.println("vert mode: " + vertDir); 00363 // 00364 // eye.add(horDir); 00365 // eye.add(vertDir); 00366 // eyeTarget.add(horDir); 00367 // eyeTarget.add(vertDir); 00368 // } 00369 // 00370 // rightMouseX = e.getX(); 00371 // rightMouseY = e.getY(); 00372 // } 00373 // else if (centerMouseY != -1.0f) { // zoom 00374 // zoom(e.getY() - (int)centerMouseY); 00375 // centerMouseY = e.getY(); 00376 // } 00377 // 00378 // redraw(); 00379 // } 00380 // 00381 // public void zoom(int delta) { 00382 // if(!useCamera) { 00383 // zoomDisplay += -(delta) * 10 / sceneSize; 00384 // if (zoomDisplay < 0.01) { 00385 // zoomDisplay = 0.01f; 00386 // } 00387 // } 00388 // else { 00389 // float dy = -(delta) * sceneSize / 1000; 00390 // 00391 // Vector3f dir = new Vector3f(eyeTarget); 00392 // dir.subtract(eye); 00393 // dir.normalize(); 00394 // dir.scale(dy); 00395 // eye.add(dir); 00396 // } 00397 // } 00398 00399 00404 public void runMain() { 00405 // Disable abyssmally slow Sun renderer on OS X 10.5. 00406 if(platform == MACOSX) { 00407 // Only run this on OS X otherwise it can cause a permissions error. 00408 // http://dev.processing.org/bugs/show_bug.cgi?id=976 00409 System.setProperty("apple.awt.graphics.UseQuartz", "true"); 00410 } 00411 00412 try { 00413 boolean external = false; 00414 00415 String name = null; 00416 boolean present = false; 00417 Color backgroundColor = Color.black; //BLACK; 00418 Color stopColor = Color.gray; //GRAY; 00419 GraphicsDevice displayDevice = null; 00420 boolean hideStop = false; 00421 00422 // try to get the user folder. if running under java web start, 00423 // this may cause a security exception if the code is not signed. 00424 // http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Integrate;action=display;num=1159386274 00425 String folder = null; 00426 try { 00427 folder = System.getProperty("user.dir"); 00428 } 00429 catch (Exception e) { 00430 } 00431 00432 // Set this property before getting into any GUI init code 00433 //System.setProperty("com.apple.mrj.application.apple.menu.about.name", name); 00434 // This )*)(*@#$ Apple crap don't work no matter where you put it 00435 // (static method of the class, at the top of main, wherever) 00436 00437 if(displayDevice == null) { 00438 GraphicsEnvironment environment = GraphicsEnvironment 00439 .getLocalGraphicsEnvironment(); 00440 displayDevice = environment.getDefaultScreenDevice(); 00441 } 00442 00443 Frame frame = new Frame(displayDevice.getDefaultConfiguration()); 00444 00445 //Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); 00446 // remove the grow box by default 00447 // users who want it back can call frame.setResizable(true) 00448 frame.setResizable(false); 00449 00450 // Set the trimmings around the image 00452 //frame.setIconImage(image); 00453 frame.setTitle(name); 00454 00455 // Class c = Class.forName(name); 00456 //Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(name); 00457 //PApplet applet = (PApplet) c.newInstance(); 00458 PApplet applet = this; 00459 00460 // these are needed before init/start 00461 applet.frame = frame; 00462 applet.sketchPath = folder; 00463 //applet.args = PApplet.subset(args, 1); 00465 00466 // For 0149, moving this code (up to the pack() method) before init(). 00467 // For OpenGL (and perhaps other renderers in the future), a peer is 00468 // needed before a GLDrawable can be created. So pack() needs to be 00469 // called on the Frame before applet.init(), which itself calls size(), 00470 // and launches the Thread that will kick off setup(). 00471 // http://dev.processing.org/bugs/show_bug.cgi?id=891 00472 // http://dev.processing.org/bugs/show_bug.cgi?id=908 00473 if(present) { 00474 frame.setUndecorated(true); 00475 frame.setBackground(backgroundColor); 00476 displayDevice.setFullScreenWindow(frame); 00477 } 00478 frame.setLayout(null); 00479 frame.add(applet); 00480 frame.pack(); 00481 00482 applet.init(); 00483 00484 // Wait until the applet has figured out its width. 00485 // In a static mode app, this will be after setup() has completed, 00486 // and the empty draw() has set "finished" to true. 00487 // TODO make sure this won't hang if the applet has an exception. 00488 while(applet.defaultSize && !applet.finished) { 00489 //System.out.println("default size"); 00490 try { 00491 Thread.sleep(5); 00492 00493 } 00494 catch (InterruptedException e) { 00495 //System.out.println("interrupt"); 00496 } 00497 } 00498 //println("not default size " + applet.width + " " + applet.height); 00499 //println(" (g width/height is " + applet.g.width + "x" + applet.g.height + ")"); 00500 00501 if(present) { 00502 // frame.setUndecorated(true); 00503 // frame.setBackground(backgroundColor); 00504 // displayDevice.setFullScreenWindow(frame); 00505 00506 // frame.add(applet); 00507 Dimension fullscreen = frame.getSize(); 00508 applet.setBounds((fullscreen.width - applet.width) / 2, 00509 (fullscreen.height - applet.height) / 2, applet.width, 00510 applet.height); 00511 00512 if(!hideStop) { 00513 Label label = new Label("stop"); 00514 label.setForeground(stopColor); 00515 label.addMouseListener(new MouseAdapter() { 00516 public void mousePressed(MouseEvent e) { 00517 System.exit(0); 00518 } 00519 }); 00520 frame.add(label); 00521 00522 Dimension labelSize = label.getPreferredSize(); 00523 // sometimes shows up truncated on mac 00524 //System.out.println("label width is " + labelSize.width); 00525 labelSize = new Dimension(100, labelSize.height); 00526 label.setSize(labelSize); 00527 label.setLocation(20, fullscreen.height - labelSize.height 00528 - 20); 00529 } 00530 00531 // not always running externally when in present mode 00532 if(external) { 00533 applet.setupExternalMessages(); 00534 } 00535 00536 } 00537 else { // if not presenting 00538 // can't do pack earlier cuz present mode don't like it 00539 // (can't go full screen with a frame after calling pack) 00540 // frame.pack(); // get insets. get more. 00541 Insets insets = frame.getInsets(); 00542 00543 int windowW = Math.max(applet.width, MIN_WINDOW_WIDTH) 00544 + insets.left + insets.right; 00545 int windowH = Math.max(applet.height, MIN_WINDOW_HEIGHT) 00546 + insets.top + insets.bottom; 00547 00548 frame.setSize(windowW, windowH); 00549 00550 if(external) { 00551 // int locationX = editorLocation[0] - 20; 00552 // int locationY = editorLocation[1]; 00553 // 00554 // if(locationX - windowW > 10) { 00555 // // if it fits to the left of the window 00556 // frame.setLocation(locationX - windowW, locationY); 00557 // 00558 // } 00559 // else { // doesn't fit 00560 // // if it fits inside the editor window, 00561 // // offset slightly from upper lefthand corner 00562 // // so that it's plunked inside the text area 00563 // locationX = editorLocation[0] + 66; 00564 // locationY = editorLocation[1] + 66; 00565 // 00566 // if((locationX + windowW > applet.screenWidth - 33) 00567 // || (locationY + windowH > applet.screenHeight - 33)) { 00568 // // otherwise center on screen 00569 // locationX = (applet.screenWidth - windowW) / 2; 00570 // locationY = (applet.screenHeight - windowH) / 2; 00571 // } 00572 // frame.setLocation(locationX, locationY); 00573 // } 00574 } 00575 else { // just center on screen 00576 frame.setLocation((applet.screenWidth - applet.width) / 2, 00577 (applet.screenHeight - applet.height) / 2); 00578 } 00579 00580 // frame.setLayout(null); 00581 // frame.add(applet); 00582 00583 if(backgroundColor == Color.black) { //BLACK) { 00584 // this means no bg color unless specified 00585 backgroundColor = SystemColor.control; 00586 } 00587 frame.setBackground(backgroundColor); 00588 00589 int usableWindowH = windowH - insets.top - insets.bottom; 00590 applet.setBounds((windowW - applet.width) / 2, insets.top 00591 + (usableWindowH - applet.height) / 2, applet.width, 00592 applet.height); 00593 00594 if(external) { 00595 applet.setupExternalMessages(); 00596 00597 } 00598 else { // !external 00599 frame.addWindowListener(new WindowAdapter() { 00600 public void windowClosing(WindowEvent e) { 00601 System.exit(0); 00602 } 00603 }); 00604 } 00605 00606 // handle frame resizing events 00607 applet.setupFrameResizeListener(); 00608 00609 // all set for rockin 00610 if(applet.displayable()) { 00611 frame.setVisible(true); 00612 } 00613 } 00614 00615 //System.out.println("showing frame"); 00616 //System.out.println("applet requesting focus"); 00617 applet.requestFocus(); // ask for keydowns 00618 //System.out.println("exiting main()"); 00619 00620 } 00621 catch (Exception e) { 00622 e.printStackTrace(); 00623 System.exit(1); 00624 } 00625 } 00626 }