私はいくつかの友達とゲームをしていて、もっと楽にするために、すべての3Dモデルが.objファイルを使用して作成され、 3DSMax、Maya、およびBlender3Dです。LWJGL .OBJファイルリーダーが時々変なファイルをレンダリングする、またはレンダリングしない
私は.objファイルリーダーを作成し、シンプルなシーンで試してみました。いくつかの.objファイルは(単純な立方体のように)レンダリングされていました。いくつかは本当に奇妙にレンダリングされ、レンダリングされませんでした。私は誰かが私が間違っていることを指摘できることを願っていました。次のコードには2つの組み込みクラスがあり、そのうちの1つに別の組み込みクラスが含まれています。混乱する可能性があるので、必要に応じて読みやすくするためにファイルにコピー&ペーストすることができます。
スクリプトはファイル内の行を1行ずつ読み込み、 "v"(頂点)で始まる場合は行をスペースで分割し、インデックス1,2および3(xyおよびz)をとり、 Vertexという名前のクラスを作成し、それをVertexオブジェクトの配列に追加します。 Vertexオブジェクトはベクトルのように動作し、位置ベクトルと法線ベクトルの2つのベクトルのみを含みます。
行が "vn"(Vertex Normal)で始まる場合、行を ""で分割し、インデックス1,2および3をとり、これまでのベクトルのように動作するVertexオブジェクトに追加します。 Vertexは、法線のために別の頂点配列に追加されます。
今ここで行は行は次のようになります "F"(顔)を開始すると、興味深い一部です:それぞれ#1 //#2
f 1//3 5//3 6//1 2//4
、#1は、のインデックスであります正しい頂点であり、#2は適切な法線のインデックスです。だから私は線の各部分を分割して "//"で分割し、頂点を頂点配列から取り出し、頂点を法線配列から取り出し、頂点の法線を法線のxyとzに設定し、 Faceオブジェクトを作成し、それを3つまたは4つの頂点オブジェクトだけを保持するフェイスのリストに追加しました。
うまくいけば、この説明によって、ファイルが乱雑に見えないことがあります。
まあは、ここでのコードは次のとおりです、私はそれはかなり簡単な修正だと信じ
package org.ic3d.utils;
import java.io.*;
import org.ic3d.utils.ObjReader.Face.FaceStateException;
import org.lwjgl.opengl.GL11;
public class ObjReader
{
public ObjReader(String file)
{
try
{
BufferedReader reader = new BufferedReader(new FileReader(new File(file)));
parse(reader);
}
catch(Exception e)
{
System.out.println(file+" Failed To Load! Can't continue.");
System.exit(0);
}
}
/**
* Parse all lines in the BufferedReader to convert the .obj file
*
* @param br - A BufferedReader object pointing to the desired .obj file
* @throws IOException If the obj file can not be read for any reason.
* @throws FaceStateException If the obj file is malformed and vertice are added to a face of different shape (tri - quad)
*/
public void parse(BufferedReader br) throws IOException, FaceStateException
{
String s="";
Vertex[] v1 = new Vertex[15000];
Vertex[] n1 = new Vertex[15000];
while((s = br.readLine())!=null)
{
if(s.startsWith("v"))
{
String[] pv = s.split(" ");
Vertex vert_0x = new Vertex(Float.parseFloat(pv[1]), Float.parseFloat(pv[2]), Float.parseFloat(pv[3]));
v1 = appendVert(v1, vert_0x);
}
if(s.startsWith("vn"))
{
String[] pv = s.split(" ");
Vertex vert_0x = new Vertex(Float.parseFloat(pv[1]), Float.parseFloat(pv[2]), Float.parseFloat(pv[3]));
n1 = appendVert(n1, vert_0x);
}
if(s.startsWith("f"))
{
String[] pv = s.split(" ");
Vertex[] temp = new Vertex[pv.length-1];
for(int i=1;i<pv.length;i++)
{
String[] vn = pv[i].split("//");
Vertex v = v1[Integer.parseInt(vn[0])];
Vertex n = n1[Integer.parseInt(vn[1])];
v.setNormals(n.getX(), n.getY(), n.getZ());
temp = appendVert(temp, v);
}
try
{
Face f = new Face(temp.length==3?Face.GL_FACE_TRI:Face.GL_FACE_QUAD, temp);
faces = appendFace(faces, f);
}
catch(FaceStateException e)
{
throw e;
}
}
}
}
private Vertex[] appendVert(Vertex[] l, Vertex v)
{
for(int i=0;i<l.length;i++)
{
if(l[i]==null)
{
l[i] = v;
return l;
}
}
System.out.println("Vertex[] can only hold "+l.length+" Vertices at one time");
return l;
}
private Face[] appendFace(Face[] l, Face f)
{
for(int i=0;i<l.length;i++)
{
if(l[i]==null)
{
l[i] = f;
return l;
}
}
System.out.println("Face[] can only hold "+faces.length+" Faces at one time");
return l;
}
public void renderTri(Face f, float x, float y, float z)
{
Vertex[] v = f.getVerts();
GL11.glBegin(GL11.GL_TRIANGLES);
Vertex cv = v[0];
GL11.glNormal3f(cv.getNormalX(), cv.getNormalY(), cv.getNormalZ());
GL11.glVertex3f(x+cv.getX(), y+cv.getY(), z+cv.getZ());
cv = v[1];
GL11.glNormal3f(cv.getNormalX(), cv.getNormalY(), cv.getNormalZ());
GL11.glVertex3f(x+cv.getX(), y+cv.getY(), z+cv.getZ());
cv = v[2];
GL11.glNormal3f(cv.getNormalX(), cv.getNormalY(), cv.getNormalZ());
GL11.glVertex3f(x+cv.getX(), y+cv.getY(), z+cv.getZ());
GL11.glEnd();
}
public void renderQuad(Face f, float x, float y, float z)
{
Vertex[] v = f.getVerts();
GL11.glBegin(GL11.GL_QUADS);
Vertex cv = v[0];
GL11.glNormal3f(cv.getNormalX(), cv.getNormalY(), cv.getNormalZ());
GL11.glVertex3f(x+cv.getX(), y+cv.getY(), z+cv.getZ());
cv = v[2];
GL11.glNormal3f(cv.getNormalX(), cv.getNormalY(), cv.getNormalZ());
GL11.glVertex3f(x+cv.getX(), y+cv.getY(), z+cv.getZ());
cv = v[2];
GL11.glNormal3f(cv.getNormalX(), cv.getNormalY(), cv.getNormalZ());
GL11.glVertex3f(x+cv.getX(), y+cv.getY(), z+cv.getZ());
cv = v[3];
GL11.glNormal3f(cv.getNormalX(), cv.getNormalY(), cv.getNormalZ());
GL11.glVertex3f(x+cv.getX(), y+cv.getY(), z+cv.getZ());
GL11.glEnd();
}
public void render(float x, float y, float z)
{
GL11.glPushMatrix();
for(Face f : faces)
{
if(f==null)
{
GL11.glPopMatrix();
return;
}
else
{
switch(f.getType())
{
case(3):
{
renderTri(f, x, y, z);
}
case(4):
{
renderQuad(f, x, y, z);
}
}
}
}
GL11.glPopMatrix();
}
public int listid=0;
public Face[] faces = new Face[15000];
public class Face
{
/**
* Create a new Face object, Faces Hold 3 or 4 Vertex Objects, Polygons not accepted.
* @param shape
* @param verts
* @throws FaceStateException - If the number of vertice in the Vertex[] is not equal to the face type set.
*/
public Face(int shape, Vertex[] vertlist) throws FaceStateException{
int vert_n = GL_FACE_NONE-shape;
if(vertlist.length>vert_n)
{
throw new FaceStateException(vert_n+" Vertice faces can not hold "+verts.length+" vertices");
}
if(vertlist.length<vert_n)
{
throw new FaceStateException(vert_n+" Vertice faces must hold "+vert_n+" vertice, not "+verts.length+" vertices");
}
if(vert_n!=3 && vert_n!=4)
{
throw new FaceStateException("Faces can only be 3 or 4 vertice. Shapes besides QUAD and TRI are not allowed.");
}
type=vert_n;
verts=vertlist;
}
public Vertex[] getVerts()
{
return verts;
}
public int getType()
{
return type;
}
public String getType(int i)
{
if(i==1)
{
return(type==3?"TRI":"QUAD");
}
else
{
return(type==3?"TRIANGLE":"QUAD");
}
}
private Vertex[] verts;
public static final int GL_FACE_QUAD = 3;
public static final int GL_FACE_TRI = 4;
public static final int GL_FACE_NONE = 7;
private int type=7;
public class FaceStateException extends Exception
{
public FaceStateException(String s)
{
super(s);
}
private static final long serialVersionUID = 1L;
}
}
public class Vertex
{
public Vertex(float x, float y, float z)
{
_x=x;
_y=y;
_z=z;
}
public void setNormals(float x, float y, float z)
{
_nx=x;
_ny=y;
_nz=z;
}
public float getX()
{
return _x;
}
public float getY()
{
return _y;
}
public float getZ()
{
return _z;
}
public float getNormalX()
{
return _nx;
}
public float getNormalY()
{
return _ny;
}
public float getNormalZ()
{
return _nz;
}
public float[] getNormalXYZ()
{
return new float[]{_nx, _ny, _nz};
}
public void setXYZ(float x, float y, float z)
{
_x=x;
_y=y;
_z=z;
}
public float[] getXYZ()
{
return new float[]{_x, _y, _z};
}
private float _x;
private float _y;
private float _z;
private float _nx;
private float _ny;
private float _nz;
}
}
あなたがこれを経験した場合、私は知らないが、あなたのコードを使用しているとき、私はインデックス検索をデクリメントしなければなりませんでしたこれを動作させるために顔を構築するとき –