From e2d98d99c3d95b3451316f05f2798193fbf016a6 Mon Sep 17 00:00:00 2001 From: Alexander Kouznetsov Date: Fri, 25 Mar 2011 17:59:02 +0100 Subject: [PATCH] 7027692: /applets/WireFrame demo needs to be improved Reviewed-by: alexp --- .../demo/applets/WireFrame/Matrix3D.java | 28 +- .../share/demo/applets/WireFrame/ThreeD.java | 407 ++++++++++-------- .../demo/applets/WireFrame/example1.html | 2 +- .../demo/applets/WireFrame/example2.html | 2 +- .../demo/applets/WireFrame/example3.html | 2 +- .../demo/applets/WireFrame/example4.html | 2 +- 6 files changed, 250 insertions(+), 193 deletions(-) diff --git a/jdk/src/share/demo/applets/WireFrame/Matrix3D.java b/jdk/src/share/demo/applets/WireFrame/Matrix3D.java index bc5939d54bd..0dda042c3c9 100644 --- a/jdk/src/share/demo/applets/WireFrame/Matrix3D.java +++ b/jdk/src/share/demo/applets/WireFrame/Matrix3D.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,22 +29,23 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - */ /** A fairly conventional 3D matrix object that can transform sets of - 3D points and perform a variety of manipulations on the transform */ +3D points and perform a variety of manipulations on the transform */ class Matrix3D { + float xx, xy, xz, xo; float yx, yy, yz, yo; float zx, zy, zz, zo; static final double pi = 3.14159265; + /** Create a new unit matrix */ - Matrix3D () { + Matrix3D() { xx = 1.0f; yy = 1.0f; zz = 1.0f; } + /** Scale by f in all dimensions */ void scale(float f) { xx *= f; @@ -60,6 +61,7 @@ class Matrix3D { zz *= f; zo *= f; } + /** Scale along each axis independently */ void scale(float xf, float yf, float zf) { xx *= xf; @@ -75,12 +77,14 @@ class Matrix3D { zz *= zf; zo *= zf; } + /** Translate the origin */ void translate(float x, float y, float z) { xo += x; yo += y; zo += z; } + /** rotate theta degrees about the y axis */ void yrot(double theta) { theta *= (pi / 180); @@ -106,6 +110,7 @@ class Matrix3D { zy = Nzy; zz = Nzz; } + /** rotate theta degrees about the x axis */ void xrot(double theta) { theta *= (pi / 180); @@ -131,6 +136,7 @@ class Matrix3D { zy = Nzy; zz = Nzz; } + /** rotate theta degrees about the z axis */ void zrot(double theta) { theta *= (pi / 180); @@ -156,6 +162,7 @@ class Matrix3D { xy = Nxy; xz = Nxz; } + /** Multiply this matrix by a second: M = M*R */ void mult(Matrix3D rhs) { float lxx = xx * rhs.xx + yx * rhs.xy + zx * rhs.xz; @@ -204,10 +211,11 @@ class Matrix3D { zy = 0; zz = 1; } + /** Transform nvert points from v into tv. v contains the input - coordinates in floating point. Three successive entries in - the array constitute a point. tv ends up holding the transformed - points as integers; three successive entries per point */ + coordinates in floating point. Three successive entries in + the array constitute a point. tv ends up holding the transformed + points as integers; three successive entries per point */ void transform(float v[], int tv[], int nvert) { float lxx = xx, lxy = xy, lxz = xz, lxo = xo; float lyx = yx, lyy = yy, lyz = yz, lyo = yo; @@ -216,11 +224,13 @@ class Matrix3D { float x = v[i]; float y = v[i + 1]; float z = v[i + 2]; - tv[i ] = (int) (x * lxx + y * lxy + z * lxz + lxo); + tv[i] = (int) (x * lxx + y * lxy + z * lxz + lxo); tv[i + 1] = (int) (x * lyx + y * lyy + z * lyz + lyo); tv[i + 2] = (int) (x * lzx + y * lzy + z * lzz + lzo); } } + + @Override public String toString() { return ("[" + xo + "," + xx + "," + xy + "," + xz + ";" + yo + "," + yx + "," + yy + "," + yz + ";" diff --git a/jdk/src/share/demo/applets/WireFrame/ThreeD.java b/jdk/src/share/demo/applets/WireFrame/ThreeD.java index 81aa0d04c6e..7f228331f7e 100644 --- a/jdk/src/share/demo/applets/WireFrame/ThreeD.java +++ b/jdk/src/share/demo/applets/WireFrame/ThreeD.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,28 +29,29 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - */ - -/* A set of classes to parse, represent and display 3D wireframe models - represented in Wavefront .obj format. */ import java.applet.Applet; import java.awt.Graphics; import java.awt.Color; -import java.awt.Event; import java.awt.event.*; import java.io.*; import java.net.URL; + +/* A set of classes to parse, represent and display 3D wireframe models +represented in Wavefront .obj format. */ +@SuppressWarnings("serial") class FileFormatException extends Exception { + public FileFormatException(String s) { super(s); } } + /** The representation of a 3D model */ -class Model3D { +final class Model3D { + float vert[]; int tvert[]; int nvert, maxvert; @@ -58,78 +59,90 @@ class Model3D { int ncon, maxcon; boolean transformed; Matrix3D mat; - float xmin, xmax, ymin, ymax, zmin, zmax; - Model3D () { - mat = new Matrix3D (); + Model3D() { + mat = new Matrix3D(); mat.xrot(20); mat.yrot(30); } + /** Create a 3D model by parsing an input stream */ - Model3D (InputStream is) throws IOException, FileFormatException { - this(); - StreamTokenizer st = new StreamTokenizer( - new BufferedReader(new InputStreamReader(is, "UTF-8"))); - st.eolIsSignificant(true); - st.commentChar('#'); - scan: + Model3D(InputStream is) throws IOException, FileFormatException { + this(); + StreamTokenizer st = new StreamTokenizer( + new BufferedReader(new InputStreamReader(is, "UTF-8"))); + st.eolIsSignificant(true); + st.commentChar('#'); + scan: while (true) { switch (st.nextToken()) { - default: - break scan; - case StreamTokenizer.TT_EOL: - break; - case StreamTokenizer.TT_WORD: - if ("v".equals(st.sval)) { - double x = 0, y = 0, z = 0; - if (st.nextToken() == StreamTokenizer.TT_NUMBER) { - x = st.nval; + default: + break scan; + case StreamTokenizer.TT_EOL: + break; + case StreamTokenizer.TT_WORD: + if ("v".equals(st.sval)) { + double x = 0, y = 0, z = 0; if (st.nextToken() == StreamTokenizer.TT_NUMBER) { - y = st.nval; - if (st.nextToken() == StreamTokenizer.TT_NUMBER) - z = st.nval; + x = st.nval; + if (st.nextToken() == StreamTokenizer.TT_NUMBER) { + y = st.nval; + if (st.nextToken() == StreamTokenizer.TT_NUMBER) { + z = st.nval; + } + } + } + addVert((float) x, (float) y, (float) z); + while (st.ttype != StreamTokenizer.TT_EOL && st.ttype + != StreamTokenizer.TT_EOF) { + st.nextToken(); + } + } else if ("f".equals(st.sval) || "fo".equals(st.sval) || "l". + equals(st.sval)) { + int start = -1; + int prev = -1; + int n = -1; + while (true) { + if (st.nextToken() == StreamTokenizer.TT_NUMBER) { + n = (int) st.nval; + if (prev >= 0) { + add(prev - 1, n - 1); + } + if (start < 0) { + start = n; + } + prev = n; + } else if (st.ttype == '/') { + st.nextToken(); + } else { + break; + } + } + if (start >= 0) { + add(start - 1, prev - 1); + } + if (st.ttype != StreamTokenizer.TT_EOL) { + break scan; + } + } else { + while (st.nextToken() != StreamTokenizer.TT_EOL + && st.ttype != StreamTokenizer.TT_EOF) { + // no-op } } - addVert((float) x, (float) y, (float) z); - while (st.ttype != StreamTokenizer.TT_EOL && - st.ttype != StreamTokenizer.TT_EOF) - st.nextToken(); - } else if ("f".equals(st.sval) || "fo".equals(st.sval) || "l".equals(st.sval)) { - int start = -1; - int prev = -1; - int n = -1; - while (true) - if (st.nextToken() == StreamTokenizer.TT_NUMBER) { - n = (int) st.nval; - if (prev >= 0) - add(prev - 1, n - 1); - if (start < 0) - start = n; - prev = n; - } else if (st.ttype == '/') - st.nextToken(); - else - break; - if (start >= 0) - add(start - 1, prev - 1); - if (st.ttype != StreamTokenizer.TT_EOL) - break scan; - } else { - while (st.nextToken() != StreamTokenizer.TT_EOL - && st.ttype != StreamTokenizer.TT_EOF); - } } } is.close(); - if (st.ttype != StreamTokenizer.TT_EOF) + if (st.ttype != StreamTokenizer.TT_EOF) { throw new FileFormatException(st.toString()); + } } /** Add a vertex to this model */ int addVert(float x, float y, float z) { int i = nvert; - if (i >= maxvert) + if (i >= maxvert) { if (vert == null) { maxvert = 100; vert = new float[maxvert * 3]; @@ -139,18 +152,21 @@ class Model3D { System.arraycopy(vert, 0, nv, 0, vert.length); vert = nv; } + } i *= 3; vert[i] = x; vert[i + 1] = y; vert[i + 2] = z; return nvert++; } + /** Add a line from vertex p1 to vertex p2 */ void add(int p1, int p2) { int i = ncon; - if (p1 >= nvert || p2 >= nvert) + if (p1 >= nvert || p2 >= nvert) { return; - if (i >= maxcon) + } + if (i >= maxcon) { if (con == null) { maxcon = 100; con = new int[maxcon]; @@ -160,6 +176,7 @@ class Model3D { System.arraycopy(con, 0, nv, 0, con.length); con = nv; } + } if (p1 > p2) { int t = p1; p1 = p2; @@ -168,79 +185,79 @@ class Model3D { con[i] = (p1 << 16) | p2; ncon = i + 1; } + /** Transform all the points in this model */ void transform() { - if (transformed || nvert <= 0) + if (transformed || nvert <= 0) { return; - if (tvert == null || tvert.length < nvert * 3) - tvert = new int[nvert*3]; + } + if (tvert == null || tvert.length < nvert * 3) { + tvert = new int[nvert * 3]; + } mat.transform(vert, tvert, nvert); transformed = true; } - /* Quick Sort implementation - */ - private void quickSort(int a[], int left, int right) - { - int leftIndex = left; - int rightIndex = right; - int partionElement; - if ( right > left) - { + /* Quick Sort implementation + */ + private void quickSort(int a[], int left, int right) { + int leftIndex = left; + int rightIndex = right; + int partionElement; + if (right > left) { - /* Arbitrarily establishing partition element as the midpoint of - * the array. - */ - partionElement = a[ ( left + right ) / 2 ]; - - // loop through the array until indices cross - while( leftIndex <= rightIndex ) - { - /* find the first element that is greater than or equal to - * the partionElement starting from the leftIndex. + /* Arbitrarily establishing partition element as the midpoint of + * the array. */ - while( ( leftIndex < right ) && ( a[leftIndex] < partionElement ) ) - ++leftIndex; + partionElement = a[(left + right) / 2]; - /* find an element that is smaller than or equal to - * the partionElement starting from the rightIndex. - */ - while( ( rightIndex > left ) && - ( a[rightIndex] > partionElement ) ) - --rightIndex; + // loop through the array until indices cross + while (leftIndex <= rightIndex) { + /* find the first element that is greater than or equal to + * the partionElement starting from the leftIndex. + */ + while ((leftIndex < right) && (a[leftIndex] < partionElement)) { + ++leftIndex; + } - // if the indexes have not crossed, swap - if( leftIndex <= rightIndex ) - { - swap(a, leftIndex, rightIndex); - ++leftIndex; - --rightIndex; + /* find an element that is smaller than or equal to + * the partionElement starting from the rightIndex. + */ + while ((rightIndex > left) && (a[rightIndex] > partionElement)) { + --rightIndex; + } + + // if the indexes have not crossed, swap + if (leftIndex <= rightIndex) { + swap(a, leftIndex, rightIndex); + ++leftIndex; + --rightIndex; + } } - } - /* If the right index has not reached the left side of array - * must now sort the left partition. - */ - if( left < rightIndex ) - quickSort( a, left, rightIndex ); + /* If the right index has not reached the left side of array + * must now sort the left partition. + */ + if (left < rightIndex) { + quickSort(a, left, rightIndex); + } - /* If the left index has not reached the right side of array - * must now sort the right partition. - */ - if( leftIndex < right ) - quickSort( a, leftIndex, right ); + /* If the left index has not reached the right side of array + * must now sort the right partition. + */ + if (leftIndex < right) { + quickSort(a, leftIndex, right); + } - } - } - - private void swap(int a[], int i, int j) - { - int T; - T = a[i]; - a[i] = a[j]; - a[j] = T; - } + } + } + private void swap(int a[], int i, int j) { + int T; + T = a[i]; + a[i] = a[j]; + a[j] = T; + } /** eliminate duplicate lines */ void compress() { @@ -259,21 +276,21 @@ class Model3D { } ncon = d; } - static Color gr[]; /** Paint this model to a graphics context. It uses the matrix associated - with this model to map from model space to screen space. - The next version of the browser should have double buffering, - which will make this *much* nicer */ + with this model to map from model space to screen space. + The next version of the browser should have double buffering, + which will make this *much* nicer */ void paint(Graphics g) { - if (vert == null || nvert <= 0) + if (vert == null || nvert <= 0) { return; + } transform(); if (gr == null) { gr = new Color[16]; for (int i = 0; i < 16; i++) { - int grey = (int) (170*(1-Math.pow(i/15.0, 2.3))); + int grey = (int) (170 * (1 - Math.pow(i / 15.0, 2.3))); gr[i] = new Color(grey, grey, grey); } } @@ -281,151 +298,181 @@ class Model3D { int lim = ncon; int c[] = con; int v[] = tvert; - if (lim <= 0 || nvert <= 0) + if (lim <= 0 || nvert <= 0) { return; + } for (int i = 0; i < lim; i++) { int T = c[i]; int p1 = ((T >> 16) & 0xFFFF) * 3; int p2 = (T & 0xFFFF) * 3; int grey = v[p1 + 2] + v[p2 + 2]; - if (grey < 0) + if (grey < 0) { grey = 0; - if (grey > 15) + } + if (grey > 15) { grey = 15; + } if (grey != lg) { lg = grey; g.setColor(gr[grey]); } g.drawLine(v[p1], v[p1 + 1], - v[p2], v[p2 + 1]); + v[p2], v[p2 + 1]); } } /** Find the bounding box of this model */ void findBB() { - if (nvert <= 0) + if (nvert <= 0) { return; + } float v[] = vert; - float xmin = v[0], xmax = xmin; - float ymin = v[1], ymax = ymin; - float zmin = v[2], zmax = zmin; + float _xmin = v[0], _xmax = _xmin; + float _ymin = v[1], _ymax = _ymin; + float _zmin = v[2], _zmax = _zmin; for (int i = nvert * 3; (i -= 3) > 0;) { float x = v[i]; - if (x < xmin) - xmin = x; - if (x > xmax) - xmax = x; + if (x < _xmin) { + _xmin = x; + } + if (x > _xmax) { + _xmax = x; + } float y = v[i + 1]; - if (y < ymin) - ymin = y; - if (y > ymax) - ymax = y; + if (y < _ymin) { + _ymin = y; + } + if (y > _ymax) { + _ymax = y; + } float z = v[i + 2]; - if (z < zmin) - zmin = z; - if (z > zmax) - zmax = z; + if (z < _zmin) { + _zmin = z; + } + if (z > _zmax) { + _zmax = z; + } } - this.xmax = xmax; - this.xmin = xmin; - this.ymax = ymax; - this.ymin = ymin; - this.zmax = zmax; - this.zmin = zmin; + this.xmax = _xmax; + this.xmin = _xmin; + this.ymax = _ymax; + this.ymin = _ymin; + this.zmax = _zmax; + this.zmin = _zmin; } } + /** An applet to put a 3D model into a page */ +@SuppressWarnings("serial") public class ThreeD extends Applet - implements Runnable, MouseListener, MouseMotionListener { + implements Runnable, MouseListener, MouseMotionListener { + 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; + @Override public void init() { mdname = getParameter("model"); try { scalefudge = Float.valueOf(getParameter("scale")).floatValue(); - }catch(Exception e){}; + } catch (Exception ignored) { + // fall back to default scalefudge = 1 + } amat.yrot(20); amat.xrot(20); - if (mdname == null) + if (mdname == null) { mdname = "model.obj"; + } resize(getSize().width <= 20 ? 400 : getSize().width, - getSize().height <= 20 ? 400 : getSize().height); + getSize().height <= 20 ? 400 : getSize().height); addMouseListener(this); addMouseMotionListener(this); } + @Override public void destroy() { removeMouseListener(this); removeMouseMotionListener(this); } + @Override public void run() { InputStream is = null; try { Thread.currentThread().setPriority(Thread.MIN_PRIORITY); is = new URL(getDocumentBase(), mdname).openStream(); - Model3D m = new Model3D (is); + Model3D m = new Model3D(is); md = m; m.findBB(); m.compress(); float xw = m.xmax - m.xmin; float yw = m.ymax - m.ymin; float zw = m.zmax - m.zmin; - if (yw > xw) + if (yw > xw) { xw = yw; - if (zw > xw) + } + if (zw > xw) { xw = zw; + } float f1 = getSize().width / xw; float f2 = getSize().height / xw; xfac = 0.7f * (f1 < f2 ? f1 : f2) * scalefudge; - } catch(Exception e) { + } catch (Exception e) { md = null; message = e.toString(); } try { - if (is != null) + if (is != null) { is.close(); - } catch(Exception e) { + } + } catch (Exception e) { } repaint(); } + @Override public void start() { - if (md == null && message == null) + if (md == null && message == null) { new Thread(this).start(); + } } + @Override public void stop() { } - public void mouseClicked(MouseEvent e) { + @Override + public void mouseClicked(MouseEvent e) { } - public void mousePressed(MouseEvent e) { + @Override + public void mousePressed(MouseEvent e) { prevx = e.getX(); prevy = e.getY(); e.consume(); } - public void mouseReleased(MouseEvent e) { + @Override + public void mouseReleased(MouseEvent e) { } - public void mouseEntered(MouseEvent e) { + @Override + public void mouseEntered(MouseEvent e) { } - public void mouseExited(MouseEvent e) { + @Override + public void mouseExited(MouseEvent e) { } - public void mouseDragged(MouseEvent e) { + @Override + public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); @@ -444,15 +491,17 @@ public class ThreeD extends Applet e.consume(); } - public void mouseMoved(MouseEvent e) { + @Override + public void mouseMoved(MouseEvent e) { } + @Override public void paint(Graphics g) { if (md != null) { md.mat.unit(); md.mat.translate(-(md.xmin + md.xmax) / 2, - -(md.ymin + md.ymax) / 2, - -(md.zmin + md.zmax) / 2); + -(md.ymin + md.ymax) / 2, + -(md.zmin + md.zmax) / 2); md.mat.mult(amat); md.mat.scale(xfac, -xfac, 16 * xfac / getSize().width); md.mat.translate(getSize().width / 2, getSize().height / 2, 8); @@ -469,20 +518,18 @@ public class ThreeD extends Applet painted = true; notifyAll(); } -// private synchronized void waitPainted() { -// while (!painted) -// wait(); -// painted = false; -// } + @Override public String getAppletInfo() { - return "Title: ThreeD \nAuthor: James Gosling? \nAn applet to put a 3D model into a page."; + return "Title: ThreeD \nAuthor: James Gosling? \n" + + "An applet to put a 3D model into a page."; } + @Override public String[][] getParameterInfo() { String[][] info = { - {"model", "path string", "The path to the model to be displayed."}, - {"scale", "float", "The scale of the model. Default is 1."} + { "model", "path string", "The path to the model to be displayed." }, + { "scale", "float", "The scale of the model. Default is 1." } }; return info; } diff --git a/jdk/src/share/demo/applets/WireFrame/example1.html b/jdk/src/share/demo/applets/WireFrame/example1.html index bd909f46c2a..1992ee53a26 100644 --- a/jdk/src/share/demo/applets/WireFrame/example1.html +++ b/jdk/src/share/demo/applets/WireFrame/example1.html @@ -6,7 +6,7 @@

3D Model: Cube


- + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! diff --git a/jdk/src/share/demo/applets/WireFrame/example2.html b/jdk/src/share/demo/applets/WireFrame/example2.html index 7e5fd621523..eec2b1d429f 100644 --- a/jdk/src/share/demo/applets/WireFrame/example2.html +++ b/jdk/src/share/demo/applets/WireFrame/example2.html @@ -6,7 +6,7 @@

3D Model: Dinosaur


- + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! diff --git a/jdk/src/share/demo/applets/WireFrame/example3.html b/jdk/src/share/demo/applets/WireFrame/example3.html index 9fdd0a57305..2b49d118ec7 100644 --- a/jdk/src/share/demo/applets/WireFrame/example3.html +++ b/jdk/src/share/demo/applets/WireFrame/example3.html @@ -6,7 +6,7 @@

3D Model: Hughes


- + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag! diff --git a/jdk/src/share/demo/applets/WireFrame/example4.html b/jdk/src/share/demo/applets/WireFrame/example4.html index e8db8830773..faf409254a1 100644 --- a/jdk/src/share/demo/applets/WireFrame/example4.html +++ b/jdk/src/share/demo/applets/WireFrame/example4.html @@ -6,7 +6,7 @@

3D Model: knoxS


- + alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason." Your browser is completely ignoring the <APPLET> tag!