提交 ee28e50f 编写于 作者: M mrkam

7027692: /applets/WireFrame demo needs to be improved

Reviewed-by: alexp
上级 b2f6b311
/*
* 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,6 +211,7 @@ 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
......@@ -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 + ";"
......
/*
* 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,16 +59,16 @@ 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 {
Model3D(InputStream is) throws IOException, FileFormatException {
this();
StreamTokenizer st = new StreamTokenizer(
new BufferedReader(new InputStreamReader(is, "UTF-8")));
......@@ -87,49 +88,61 @@ class Model3D {
x = st.nval;
if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
y = st.nval;
if (st.nextToken() == StreamTokenizer.TT_NUMBER)
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)
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)) {
}
} 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)
while (true) {
if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
n = (int) st.nval;
if (prev >= 0)
if (prev >= 0) {
add(prev - 1, n - 1);
if (start < 0)
}
if (start < 0) {
start = n;
}
prev = n;
} else if (st.ttype == '/')
} else if (st.ttype == '/') {
st.nextToken();
else
} else {
break;
if (start >= 0)
}
}
if (start >= 0) {
add(start - 1, prev - 1);
if (st.ttype != StreamTokenizer.TT_EOL)
}
if (st.ttype != StreamTokenizer.TT_EOL) {
break scan;
}
} else {
while (st.nextToken() != StreamTokenizer.TT_EOL
&& st.ttype != StreamTokenizer.TT_EOF);
&& st.ttype != StreamTokenizer.TT_EOF) {
// no-op
}
}
}
}
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,50 +185,50 @@ 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)
{
private void quickSort(int a[], int left, int right) {
int leftIndex = left;
int rightIndex = right;
int partionElement;
if ( right > left)
{
if (right > left) {
/* Arbitrarily establishing partition element as the midpoint of
* the array.
*/
partionElement = a[ ( left + right ) / 2 ];
partionElement = a[(left + right) / 2];
// loop through the array until indices cross
while( leftIndex <= rightIndex )
{
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 ) )
while ((leftIndex < right) && (a[leftIndex] < partionElement)) {
++leftIndex;
}
/* find an element that is smaller than or equal to
* the partionElement starting from the rightIndex.
*/
while( ( rightIndex > left ) &&
( a[rightIndex] > partionElement ) )
while ((rightIndex > left) && (a[rightIndex] > partionElement)) {
--rightIndex;
}
// if the indexes have not crossed, swap
if( leftIndex <= rightIndex )
{
if (leftIndex <= rightIndex) {
swap(a, leftIndex, rightIndex);
++leftIndex;
--rightIndex;
......@@ -221,27 +238,27 @@ class Model3D {
/* 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 (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 (leftIndex < right) {
quickSort(a, leftIndex, right);
}
}
}
private void swap(int a[], int i, int j)
{
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() {
int limit = ncon;
......@@ -259,7 +276,6 @@ class Model3D {
}
ncon = d;
}
static Color gr[];
/** Paint this model to a graphics context. It uses the matrix associated
......@@ -267,13 +283,14 @@ class Model3D {
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,17 +298,20 @@ 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]);
......@@ -303,128 +323,155 @@ class Model3D {
/** 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;
}
this.xmax = xmax;
this.xmin = xmin;
this.ymax = ymax;
this.ymin = ymin;
this.zmax = zmax;
this.zmin = zmin;
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;
}
}
/** An applet to put a 3D model into a page */
@SuppressWarnings("serial")
public class ThreeD extends Applet
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);
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() {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
prevx = e.getX();
prevy = e.getY();
e.consume();
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
int x = e.getX();
int y = e.getY();
......@@ -444,9 +491,11 @@ public class ThreeD extends Applet
e.consume();
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void paint(Graphics g) {
if (md != null) {
md.mat.unit();
......@@ -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;
}
......
......@@ -6,7 +6,7 @@
<h1>3D Model: Cube</h1>
<hr>
<applet code=ThreeD.class width=100 height=100>
<param name=model value=models/cube.obj>
<param name=model value="models/cube.obj">
alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason."
Your browser is completely ignoring the &lt;APPLET&gt; tag!
</applet>
......
......@@ -6,7 +6,7 @@
<h1>3D Model: Dinosaur</h1>
<hr>
<applet code=ThreeD.class width=300 height=300>
<param name=model value=models/dinasaur.obj>
<param name=model value="models/dinasaur.obj">
alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason."
Your browser is completely ignoring the &lt;APPLET&gt; tag!
</applet>
......
......@@ -6,7 +6,7 @@
<h1>3D Model: Hughes</h1>
<hr>
<applet code=ThreeD.class width=300 height=300>
<param name=model value=models/hughes_500.obj>
<param name=model value="models/hughes_500.obj">
alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason."
Your browser is completely ignoring the &lt;APPLET&gt; tag!
</applet>
......
......@@ -6,7 +6,7 @@
<h1>3D Model: knoxS</h1>
<hr>
<applet code=ThreeD.class width=300 height=300>
<param name=model value=models/knoxS.obj>
<param name=model value="models/knoxS.obj">
alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason."
Your browser is completely ignoring the &lt;APPLET&gt; tag!
</applet>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册