Java读取Obj模型

Java写OpenGL项目时总要去加载一个Obj模型,或者导出导入操作,没必要用一大堆第三方包,一个类完事,兼容Window和Android

测试可以打开3DMax导出的Obj格式
导出的Obj也可以在3DMax打开

该类仅满足我个人的需求,不是完整的Obj标准

使用方法:

YSOBJModel ysom=new YSOBJModel("OBJ模型数据"/*不填则为自己建造模型*/);
ysom.toModelString();//模型数据转换成字符串
ysom.writeModelString(new FileOutputStream("路径"));//跟上述一样,直接写入文件可以支持大文本。
ysom.vertex;//顶点坐标,三个一组
ysom.vertexTexture;//纹理坐标,两个一组
ysom.vertexNormal;//法线坐标,三个一组
YSOBJModel.Group group=ysom.group[0];//多个面构成的的组
group.name;//组的名字
YSOBJModel.Face face=group.face[0];//获取一个组里的面,对应f xxx
//OBJ模型索引由1开始,而下面解析的索引从0开始。
face.vertexIndex;//顶点的索引
face.textureIndex;//纹理的索引
face.normalIndex;//法线的索引
face.length;//几个索引构成一个面,常规由3或4个顶点构成。一组面可以混合

使用示例

加载OBJ读取数据

YSOBJModel ysom=new YSOBJModel("OBJ模型数据");
YSOBJModel.Group group=ysom.group[0];//多个组需要遍历
YSOBJModel.Face face=group.face[0];//多个面需要遍历
ysom.vertex[face.vertexIndex[0]*3];//获取一个顶点坐标,顶点数据三个一组
ysom.vertexTexture[face.textureIndex[0]*2];//获取一个纹理坐标,纹理数据两个一组

数据输出OBJ
容错机制足够,可以不用纹理、法线坐标

YSOBJModel ysom=new YSOBJModel();
ysom.vertex=new float[]{
   -1,0,0,0,1,0,-1,0,0};//三角形坐标
YSOBJModel.Group group=new YSOBJModel.Group();
group.name="测试";
YSOBJModel.Face face=new YSOBJModel.Face();
face.vertexIndex=new int[]{
   0,1,2};//添加索引
face.length=3;
group.face=new YSOBJModel.Face[]{
   face};
ysom.group=new YSOBJModel.Group[]{
   group};
ysom.toModelString();//输出字符串

类代码,可以直接复制到自己工程使用

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
public class YSOBJModel
{
   
	private String lineSeparator;
	public float vertex[]=new float[0];//顶点每3个一组
	public float vertexTexture[]=new float[0];//纹理坐标每2个一组
	public float vertexNormal[]=new float[0];//法线每3个一组
	public Group group[]=new Group[0];//每一组obj
	public YSOBJModel()
	{
   
		lineSeparator=System.getProperty("line.separator");
	}
	public YSOBJModel(StringBuffer sb)//解析obj文件
	{
   
		lineSeparator=System.getProperty("line.separator");
		if(sb!=null)
		{
   
			sb.append(" ");//数据结尾要多一个字符
			//先把顶点拎出来
			int vLinePos[]=getStringLinePos(sb,"v ",0,-1);
			int vtLinePos[]=getStringLinePos(sb,"vt ",0,-1);
			int vnLinePos[]=getStringLinePos(sb,"vn ",0,-1);
			ArrayList<Float> v=new ArrayList<>(vLinePos.length*3);
			ArrayList<Float> vt=new ArrayList<>(vtLinePos.length*2);
			ArrayList<Float> vn=new ArrayList<>(vnLinePos.length*3);
			int length=sb.length();
			for(int x=0;x<vLinePos.length;x++)
			{
   
				int end=length;
				if(x<vLinePos.length-1)
				{
   
					end
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值