/* * Also see ThreeD.java */ /* Created/Modified by Håkan Johansson 2000-02-10 */ import java.awt.*; import java.applet.Applet; import java.awt.event.*; import java.awt.Canvas; import java.io.*; import java.net.URL; public class ThreeDCanvas extends Canvas implements Runnable, MouseListener, MouseMotionListener, ActionListener { Model3D md; boolean painted = true; float xfac; int prevx, prevy; float xtheta, ytheta; float scalefudge = 1; Matrix3D amat = new Matrix3D(), tmat = new Matrix3D(); String mdname = null; String message = null; URL docbase; Panel btnPanel; BtnOrText btn[] = new BtnOrText[4]; int paintmethod = -1; Thread initCalc = null; boolean bMayPaint = false; public void init() { //System.out.println ("canvas::init"); amat.yrot(20); amat.xrot(20); if (mdname == null) mdname = "model.obj"; addMouseListener(this); addMouseMotionListener(this); for (int i = 0; i < btn.length; i++) btn[i].btn.addActionListener(this); } public void destroy() { //System.out.println ("canvas::destroy"); removeMouseListener(this); removeMouseMotionListener(this); for (int i = 0; i < btn.length; i++) btn[i].btn.removeActionListener(this); if (md != null) md.killInitCalc = true; } public void actionPerformed(ActionEvent e) { for (int i = 0; i < btn.length; i++) if (e.getSource() == btn[i].btn) { paintmethod = i; dopaint (); } } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { prevx = e.getX(); prevy = e.getY(); e.consume(); } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); tmat.unit(); float xtheta = (prevy - y) * 360.0f / getSize().width; float ytheta = (x - prevx) * 360.0f / getSize().height; tmat.xrot(xtheta); tmat.yrot(ytheta); amat.mult(tmat); dopaint(); prevx = x; prevy = y; e.consume(); } public void mouseMoved(MouseEvent e) { } public void update(Graphics g) { g.setColor (getForeground()); paint(g); } public void paint(Graphics g) { if (bMayPaint && md != null && paintmethod >= 0) { md.mat.unit(); md.matnorm.unit(); md.mat.translate(-(md.xmin + md.xmax) / 2, -(md.ymin + md.ymax) / 2, -(md.zmin + md.zmax) / 2); md.mat.mult(amat); md.matnorm.mult(amat); md.mat.scale(xfac, -xfac, 16 * xfac / getSize().width); md.mat.translate(getSize().width / 2, getSize().height / 2, 8); md.transformed = false; md.transformedhit = false; md.transformedtrinorm = false; md.paint(g,this,paintmethod); setPainted(); } else if (message != null) { g.drawString("Error in model:", 3, 20); g.drawString(message, 10, 40); } } void dopaint() { if (painted) { painted = false; repaint(); } } private synchronized void setPainted() { painted = true; notifyAll(); } public void run() { //System.out.println ("canvas::run"); InputStream is = null; try { btn[0].SetLabelText ("Loading model"); Thread.currentThread().setPriority(Thread.MIN_PRIORITY); md = new Model3D (); is = new URL(docbase, mdname).openStream(); md.ScanFile (is,btn[0]); md.findBB(); md.compress(); float xw = md.xmax - md.xmin; float yw = md.ymax - md.ymin; float zw = md.zmax - md.zmin; if (yw > xw) xw = yw; if (zw > xw) xw = zw; float f1 = getSize().width / xw; float f2 = getSize().height / xw; xfac = 0.7f * (f1 < f2 ? f1 : f2) * scalefudge; bMayPaint = true; if (md.CalcWaitOrKill()) return; btn[0].ShowButton(); paintmethod = 0; dopaint (); if (md.CalcWaitOrKill()) return; md.CreateHit(btn[1]); btn[1].ShowButton(); if (md.CalcWaitOrKill()) return; md.CreateLines(1.5,15,btn[2]); md.compress(); btn[2].ShowButton(); if (md.CalcWaitOrKill()) return; md.CreateTris(btn[3]); btn[3].ShowButton(); if (md.CalcWaitOrKill()) return; } catch(Exception e) { md = null; message = e.toString(); e.printStackTrace (); } try { if (is != null) is.close(); } catch(Exception e) { } repaint(); //System.out.println ("canvas::run /"); initCalc = null; } public void start() { //System.out.println ("canvas::start"); if (initCalc != null) { if (md != null) md.pauseInitCalc = false; System.out.println ("notifying "); initCalc.interrupt(); } if (md == null && message == null) { if (initCalc == null) { initCalc = new Thread(this); initCalc.start(); } } } public void stop() { if (md != null) md.pauseInitCalc = true; } // private synchronized void waitPainted() { // while (!painted) // wait(); // painted = false; // } }