[Arbaro自学笔记]Wafefront OBJ文件导出和基于LWJGL的可视化
程序员文章站
2022-03-26 16:02:56
...
最近在自学arbaro创建树模型,刚开了个头,把经验记录下
基本操作
Arbaro在国内感觉基本看不到人提,搜的人也少,我又不想翻外网,所以一开始完全是摸着石头过河,感觉好难。这玩意开放源代码,我下好之后还把它导入IDEA以为要编译,鼓捣半天发现给的下载里已经包括了JAR打包可执行文件(arbaro.jar),直接点开就能用。
树的参数方面还是非常简单的,有点数学基础的话看下给的tips就能大致弄懂参数设置。就不多写了(其实就是懒)
可视化
这里其实也偷懒了,我参照了 *上老哥的贴子做了两个简单的、没有实现光滑面的OBJ文件可视化类。放代码:
import GraphicsObjects.Point4f;
import GraphicsObjects.Vector4f;
import org.lwjgl.opengl.GL11;
public class Model {
//OBJ data storage and draw
public Point4f[] vertices = new Point4f[20000];
//public Vector4f[] normals = new Vector4f[];
public static int[][] faces = new int[20000][4];
//obj虽然最简单,但是导出文件体积太大,动辄上万个点和面,所以分配了[20000]
//但这也只能拿来可视化比较小的树模型
static int i=0;
static int j=0;
public Model(){
}
public static void DrawModel(Model m){
GL11.glBegin(GL11.GL_QUADS);
for (int face = 0;face<j+1; face++) { // per face
Vector4f v = m.vertices[m.faces[face][1]].MinusPoint(m.vertices[m.faces[face][0]]);
Vector4f w = m.vertices[m.faces[face][3]].MinusPoint(m.vertices[m.faces[face][0]]);
Vector4f normal = v.cross(w).Normal();
GL11.glNormal3f(normal.x, normal.y, normal.z);
GL11.glVertex3f(m.vertices[faces[face][0]].x, m.vertices[faces[face][0]].y, m.vertices[faces[face][0]].z);
GL11.glVertex3f(m.vertices[faces[face][1]].x, m.vertices[faces[face][1]].y, m.vertices[faces[face][1]].z);
GL11.glVertex3f(m.vertices[faces[face][2]].x, m.vertices[faces[face][2]].y, m.vertices[faces[face][2]].z);
GL11.glVertex3f(m.vertices[faces[face][3]].x, m.vertices[faces[face][3]].y, m.vertices[faces[face][3]].z);
}
GL11.glEnd();
}
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import GraphicsObjects.Point4f;
public class OBJLoader {
// Load OBJ files
public static Model loadModel(File f) throws IOException {
Model.i=0;
Model.j=0;
Point4f[] vertices = new Point4f[20000];
int[][] faces = new int[20000][4];
BufferedReader reader = new BufferedReader(new FileReader(f));
Model m = new Model();
String line;
while((line = reader.readLine()) != null){
//parse object
if (line.startsWith("v ")){
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.vertices[Model.i] =new Point4f(x*1.0f,y*1.0f,z*1.0f,0.0f);
Model.i++;
} /*else if (line.startsWith("vn ")) {
//我normals跟原版思路不一样,并且Arbaro导出的OBJ只使用v f s;
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.normals.add(new Vector3f(x,y,z));
} */else if (line.startsWith("f ")) {
//return the pointID of faces
int a = Integer.valueOf(line.split(" ")[1]).intValue();
int b = Integer.valueOf(line.split(" ")[2]).intValue();
int c = Integer.valueOf(line.split(" ")[3]).intValue();
int d = Integer.valueOf(line.split(" ")[line.split(" ").length-1]).intValue();
//Arbaro提供的OBJ faces 有时用三个点定义有时用四个点
//只有三个点时用split("")标[4]就会报错,因为没有第五段
m.faces[Model.j][0]=a-1;
m.faces[Model.j][1]=b-1;
m.faces[Model.j][2]=c-1;
m.faces[Model.j][3]=d-1;
Model.j++;
} else if (line.startsWith("s ")){
//光滑面我还没想好怎么做
}
}
reader.close();
return m;
}
}
上一篇: Linux修改主机名命令