import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.lang.*;
import java.io.StreamTokenizer;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
/**
* class Face: your basic storage class for polygonal face information.
*/
class Face {
public int nverts; // number of vertices
public int index[]; // array of indices
public int cr, cg, cb; // face color in RGB
public int zdepth; // z depth of furthest vertex
Face () {
nverts = 0;
index = null;
cr = 255; cg = 255; cb = 255;
}
Face (int nv) {
nverts = nv;
index = new int[nv];
cr = 255; cg = 255; cb = 255;
}
public void numVerts(int nv) {
nverts = nv;
index = new int[nv];
}
}
/**
* class OOGL_OFF: a class for parsing, storing and rendering OFF 3D models
*
* For more information about OFF files and other OOGL (Object Oriented
* Graphics Library) file formats, check the following URL:
*
* http://www.geom.umn.edu/software/geomview/docs/oogltour.html
*/
public class OOGL_OFF {
Face face[]; // array of faces
boolean transformed, gothead;
Matrix3D mat; // applied 3D transformation
public float xmin, xmax, // bounding box parameters
ymin, ymax,
zmin, zmax;
float vert[]; // array of vertex coordinates
int nverts, nfaces, nedges, // # of vertices, faces, edges
vx[], vy[], // coords for rendering faces
tvert[], // transformed vertices
findex[]; // indices into face list
Color gr[]; // face colors
final int MAX_VERTS = 100; // assume each polygonal face
// has less than 100 vertices.
OOGL_OFF () {
mat = new Matrix3D();
vx = new int[MAX_VERTS];
vy = new int[MAX_VERTS];
nverts = 0;
nedges = 0;
nfaces = 0;
vert = null;
gr = null;
mat.xrot(0); mat.yrot(0);
}
OOGL_OFF (URL loc) { // read object from any URL
this();
try {
readObject(loc.openStream());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
OOGL_OFF (InputStream is) { // read object from a stream
this();
try {
readObject(is);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
/* This method parses an OFF file. */
void readObject(InputStream is) throws IOException {
StreamTokenizer stream = new StreamTokenizer (is);
stream.eolIsSignificant(true);
stream.commentChar('#');
gothead = false;
scanhead: // read the header
while (!gothead) {
switch (stream.nextToken()) {
default:
break scanhead;
case StreamTokenizer.TT_EOL:
break;
case StreamTokenizer.TT_WORD:
if ("OFF".equals(stream.sval)) {
System.out.println(stream.sval);
nverts = 0; nfaces = 0; nedges = 0;
while (stream.nextToken() == StreamTokenizer.TT_EOL) {};
if (stream.ttype == StreamTokenizer.TT_NUMBER) {
nverts = (int)stream.nval;
if (stream.nextToken() == StreamTokenizer.TT_NUMBER) {
nfaces = (int)stream.nval;
if (stream.nextToken() == StreamTokenizer.TT_NUMBER) {
nedges = (int)stream.nval;
gothead = true;
} else throw new IOException("Can't read OFF file");
} else throw new IOException("Can't read OFF file");
} else throw new IOException("Can't read OFF file");
}
break;
case StreamTokenizer.TT_NUMBER:
break;
}
}
vert = new float[nverts * 3];
face = new Face[nfaces]; findex = new int[nfaces];
for (int i = 0; i < nfaces; i++) { findex[i] = i; }
int num = 0;
int coordnum = 0;
scanverts: // read the vertices
while (num < nverts) {
switch (stream.nextToken()) {
default:
break;
case StreamTokenizer.TT_EOL:
if (coordnum > 2) {
coordnum = 0; num++;
}
break;
case StreamTokenizer.TT_NUMBER:
if (coordnum < 3) {
vert[num*3 + coordnum] = (float)stream.nval;
coordnum++;
}
}
}
num = 0; coordnum = 0;
boolean gotnum = false;
scanfaces: // read the faces
while (num < nfaces) {
switch (stream.nextToken()) {
default:
break;
case StreamTokenizer.TT_EOL:
if (gotnum) { num++; }
gotnum = false;
break;
case StreamTokenizer.TT_NUMBER:
if (!gotnum) {
face[num] = new Face();
face[num].numVerts((int)stream.nval);
gotnum = true; coordnum = 0;
} else if (coordnum < face[num].nverts) {
face[num].index[coordnum] = 3 * (int)stream.nval;
coordnum++;
} else {
face[num].cr = 255; face[num].cg = 255; face[num].cb = 255;
float val = (float)stream.nval;
if (val <= 1) { val *= 255; }
face[num].cr = (int)val;
if (stream.nextToken() != StreamTokenizer.TT_EOL) {
val = (float)stream.nval;
if (val <= 1) { val *= 255; }
face[num].cg = (int)val;
if (stream.nextToken() != StreamTokenizer.TT_EOL) {
val = (float)stream.nval;
if (val <= 1) { val *= 255; }
face[num].cb = (int)val;
} else {
face[num].cr = 255; face[num].cg = 255; face[num].cb = 255;
num++; gotnum = false;
}
} else {
face[num].cr = 255; face[num].cg = 255; face[num].cb = 255;
num++; gotnum = false;
}
}
break;
}
}
}
/* transform all points in model */
void transform() {
if (transformed || nverts <= 0)
return;
if (tvert == null)
tvert = new int[nverts*3];
mat.transform(vert, tvert, nverts);
transformed = true;
}
/**
* The quick sort algorithm in this method is used for sorting faces
* from back to front by z depth values.
*/
void qs(int left, int right) {
int i, j, x, y;
i = left; j = right;
x = face[findex[(left+right)/2]].zdepth;
do {
while (face[findex[i]].zdepth > x && i < right) i++;
while (x > face[findex[j]].zdepth && j > left) j--;
if (i <= j) {
y = findex[i];
findex[i] = findex[j];
findex[j] = y;
i++; j--;
}
} while (i <= j);
if (left < j) qs(left, j);
if (i < right) qs(i, right);
}
/* Paint myself to the graphics context. */
void paint(Graphics g) {
if (vert == null || nverts <= 0)
return;
transform();
if (gr == null) { // allocate colors if
// they haven't been
gr = new Color[nfaces]; // allocated already
for (int i = 0; i < nfaces; i++) {
gr[i] = new Color(face[i].cr, face[i].cg, face[i].cb);
}
}
/**
* Calculate the average z depth of faces and use this to sort them.
* This is called the "Painter's algorithm" and although it works in
* some case, does *not* always provide a correct ordering. Sometimes
* a correct ordering is impossible, especially in the case of mutually
* overlapping polygons.
*/
for (int i = 0; i < nfaces; i++) {
face[i].zdepth = 0;
for (int c = 0; c < face[i].nverts; c++) {
if (face[i].zdepth < tvert[face[i].index[c]+2])
face[i].zdepth = tvert[face[i].index[c]+2];
}
}
qs(0, nfaces-1); // quick sort the faces
for (int f = 0; f < nfaces; f++) {
int i = findex[f];
int v =
用JAVA编程画3D的一张动画人物的脸.rar_JAVA画人_java 3d_java画动漫人物
版权申诉
33 浏览量
2022-09-20
13:31:29
上传
评论
收藏 3KB RAR 举报
Kinonoyomeo
- 粉丝: 77
- 资源: 1万+
最新资源
- 2331308JS课堂案例.zip
- STM32H750VBT6单片机最小系统开发板AD设计硬件(原理图+PCB+3D封装库)工程文件.zip
- 基于74LS161+ 74LS192芯片实现倒计时定时器Multisim仿真源文件,Multisim10以上版本可打开运行
- 科大讯飞语音引擎 jar包 demo,科大讯飞语音合成引擎3.0,支持4.0系统以上,文字转语音输出.zip
- Java架构面试笔试专题资料及经验(含答案)SpringBoot面试Linux面试专题及答案 合集.zip
- 头歌c语言实验答案tion-model-for-ne开发笔记
- docker配置使用-model-for-networK开发demo
- docker配置使用vaWeb-mas笔记
- c语言连接两个字符串-mas开发笔记
- 俄罗斯引擎yandex进入x-master 笔记
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0