42 import java.applet.Applet;
43 import java.awt.Graphics;
44 import java.awt.Color;
45 import java.awt.event.*;
52 @SuppressWarnings(
"serial")
82 StreamTokenizer st =
new StreamTokenizer(
83 new BufferedReader(
new InputStreamReader(is,
"UTF-8")));
84 st.eolIsSignificant(
true);
88 switch (st.nextToken()) {
91 case StreamTokenizer.TT_EOL:
93 case StreamTokenizer.TT_WORD:
94 if (
"v".equals(st.sval)) {
95 double x = 0, y = 0, z = 0;
96 if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
98 if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
100 if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
105 addVert((
float) x, (
float) y, (
float) z);
106 while (st.ttype != StreamTokenizer.TT_EOL && st.ttype
107 != StreamTokenizer.TT_EOF) {
110 }
else if (
"f".equals(st.sval) ||
"fo".equals(st.sval) ||
"l".
116 if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
119 add(prev - 1, n - 1);
125 }
else if (st.ttype ==
'/') {
132 add(start - 1, prev - 1);
134 if (st.ttype != StreamTokenizer.TT_EOL) {
138 while (st.nextToken() != StreamTokenizer.TT_EOL
139 && st.ttype != StreamTokenizer.TT_EOF) {
146 if (st.ttype != StreamTokenizer.TT_EOF) {
160 float nv[] =
new float[
maxvert * 3];
161 System.arraycopy(
vert, 0, nv, 0,
vert.length);
173 void add(
int p1,
int p2) {
184 int nv[] =
new int[
maxcon];
185 System.arraycopy(
con, 0, nv, 0,
con.length);
194 con[i] = (p1 << 16) | p2;
213 int leftIndex = left;
214 int rightIndex = right;
221 partionElement =
a[(left + right) / 2];
224 while (leftIndex <= rightIndex) {
228 while ((leftIndex < right) && (
a[leftIndex] < partionElement)) {
235 while ((rightIndex > left) && (
a[rightIndex] > partionElement)) {
240 if (leftIndex <= rightIndex) {
241 swap(
a, leftIndex, rightIndex);
250 if (left < rightIndex) {
257 if (leftIndex < right) {
264 private void swap(
int a[],
int i,
int j) {
278 for (
int i = 0; i < limit; i++) {
301 for (
int i = 0; i < 16; i++) {
302 int grey = (int) (170 * (1 - Math.pow(i / 15.0, 2.3)));
303 gr[i] =
new Color(grey, grey, grey);
310 if (lim <= 0 ||
nvert <= 0) {
313 for (
int i = 0; i < lim; i++) {
315 int p1 = ((T >> 16) & 0xFFFF) * 3;
316 int p2 = (T & 0xFFFF) * 3;
317 int grey = v[p1 + 2] + v[p2 + 2];
326 g.setColor(
gr[grey]);
328 g.drawLine(v[p1], v[p1 + 1],
339 float _xmin = v[0], _xmax = _xmin;
340 float _ymin = v[1], _ymax = _ymin;
341 float _zmin = v[2], _zmax = _zmin;
342 for (
int i =
nvert * 3; (i -= 3) > 0;) {
376 @SuppressWarnings(
"serial")
378 implements Runnable, MouseListener, MouseMotionListener {
381 boolean painted =
true;
384 float scalefudge = 1;
386 String mdname =
null;
387 String message =
null;
391 mdname = getParameter(
"model");
393 scalefudge = Float.valueOf(getParameter(
"scale")).floatValue();
394 }
catch (Exception ignored) {
399 if (mdname ==
null) {
400 mdname =
"model.obj";
402 resize(getSize().width <= 20 ? 400 : getSize().width,
403 getSize().height <= 20 ? 400 : getSize().height);
404 addMouseListener(
this);
405 addMouseMotionListener(
this);
410 removeMouseListener(
this);
411 removeMouseMotionListener(
this);
416 InputStream is =
null;
418 Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
419 is = getClass().getResourceAsStream(mdname);
433 float f1 = getSize().width / xw;
434 float f2 = getSize().height / xw;
435 xfac = 0.7f * (f1 < f2 ? f1 : f2) * scalefudge;
436 }
catch (Exception e) {
438 message = e.toString();
444 }
catch (Exception e) {
451 if (md ==
null && message ==
null) {
452 new Thread(
this).start();
489 float xtheta = (prevy - y) * 360.0f / getSize().width;
490 float ytheta = (x - prevx) * 360.0f / getSize().height;
515 md.
mat.
scale(xfac, -xfac, 16 * xfac / getSize().width);
516 md.
mat.
translate(getSize().width / 2, getSize().height / 2, 8);
520 }
else if (message !=
null) {
521 g.drawString(
"Error in model:", 3, 20);
522 g.drawString(message, 10, 40);
533 return "Title: ThreeD \nAuthor: James Gosling? \n"
534 +
"An applet to put a 3D model into a page.";
540 {
"model",
"path string",
"The path to the model to be displayed." },
541 {
"scale",
"float",
"The scale of the model. Default is 1." }