Java OBJ装载机索引自动边界
我在写一个3D引擎,我的OBJ Loader类似乎在更复杂的模型上有问题 我有一种无法识别的感觉,我不知道为什么。 索引3522上的ArrayList纹理的值似乎会导致此异常,但为什么 这是我的OBJ装入器类Java OBJ装载机索引自动边界,java,3d,lwjgl,3d-model,Java,3d,Lwjgl,3d Model,我在写一个3D引擎,我的OBJ Loader类似乎在更复杂的模型上有问题 我有一种无法识别的感觉,我不知道为什么。 索引3522上的ArrayList纹理的值似乎会导致此异常,但为什么 这是我的OBJ装入器类 package graphics.renderEngine; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException;
package graphics.renderEngine;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import org.joml.Vector2f;
import org.joml.Vector3f;
import graphics.models.RawModel;
public class OBJLoader
{
public static RawModel loadObjModel(String fileName, Loader loader)
{
FileReader fr = null;
try
{
fr = new FileReader(new File("Ressources/Models/"+fileName+".obj"));
}
catch (FileNotFoundException e)
{
System.err.println("Could not load File!");
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(fr);
String line;
List<Vector3f> vertices = new ArrayList<Vector3f>();
List<Vector2f> textures = new ArrayList<Vector2f>();
List<Vector3f> normals = new ArrayList<Vector3f>();
List<Integer> indices = new ArrayList<Integer>();
float[] verticesArray = null;
float[] normalsArray = null;
float[] texturesArray = null;
int[] indicesArray = null;
try
{
while(true)
{
line = reader.readLine();
String[] currentLine = line.split(" ");
if(line.startsWith("v "))
{
Vector3f vertex = new Vector3f(Float.parseFloat(currentLine[1]),Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3]));
vertices.add(vertex);
}
else if(line.startsWith("vt "))
{
Vector2f texture = new Vector2f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]));
textures.add(texture);
}
else if(line.startsWith("vn "))
{
Vector3f normal = new Vector3f(Float.parseFloat(currentLine[1]),Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3]));
normals.add(normal);
}
else if(line.startsWith("f "))
{
texturesArray = new float[vertices.size()*2];
normalsArray = new float[vertices.size()*3];
break;
}
}
while(line != null)
{
if(!line.startsWith("f "))
{
line = reader.readLine();
continue;
}
String[] currentLine = line.split(" ");
String[] vertex1 = currentLine[1].split("/");
String[] vertex2 = currentLine[2].split("/");
String[] vertex3 = currentLine[3].split("/");
processVertex(vertex1, indices, textures, normals, texturesArray, normalsArray);
processVertex(vertex2, indices, textures, normals, texturesArray, normalsArray);
processVertex(vertex3, indices, textures, normals, texturesArray, normalsArray);
line = reader.readLine();
}
reader.close();
}
catch(Exception e)
{
e.printStackTrace();
}
verticesArray = new float[vertices.size()*3];
indicesArray = new int[indices.size()];
int vertexPointer = 0;
for (Vector3f vertex:vertices)
{
verticesArray[vertexPointer++] = vertex.x;
verticesArray[vertexPointer++] = vertex.y;
verticesArray[vertexPointer++] = vertex.z;
}
for(int i=0;i<indices.size();i++)
{
indicesArray[i] = indices.get(i);
}
return
loader.loadToVAO
(verticesArray,
texturesArray,
normalsArray,
indicesArray);
}
private static void processVertex(String[] vertexData, List<Integer> indices, List<Vector2f> textures, List<Vector3f> normals, float[] textureArray, float[] normalsArray)
{
System.out.println(textures.get(3522));
int currentvertexPointer = Integer.parseInt(vertexData[0]) -1;
indices.add(currentvertexPointer);
Vector2f currentTex = textures.get(Integer.parseInt(vertexData[1])-1);
textureArray[currentvertexPointer*2] = currentTex.x;
textureArray[currentvertexPointer*2+1] = 1 - currentTex.y;
Vector3f currentNorm = normals.get(Integer.parseInt(vertexData[2])-1);
normalsArray[currentvertexPointer*3] = currentNorm.x;
normalsArray[currentvertexPointer*3+1] = currentNorm.y;
normalsArray[currentvertexPointer*3+2] = currentNorm.z;
}
}
在异常之前,我得到的最后一个向量是:
( 4.260E-1 1.275E-1)
( 4.650E-1 1.664E-1)
( 4.706E-1 1.621E-1)
( 4.650E-1 1.664E-1)
( 4.925E-1 2.140E-1)
( 1.340E-1 8.170E-2)
( 1.947E-1 4.650E-2)
( 1.902E-1 3.560E-2)
在查看了OBJ文件后,除了最后两个,我无法按顺序找到
这是我得到的例外
java.lang.IndexOutOfBoundsException: Index: 3522, Size: 3522
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at graphics.renderEngine.OBJLoader.processVertex(OBJLoader.java:122)
at graphics.renderEngine.OBJLoader.loadObjModel(OBJLoader.java:82)
at main.Main.init(Main.java:150)
at main.Main.<init>(Main.java:82)
at main.Main.main(Main.java:75)
java.lang.IndexOutOfBoundsException:索引:3522,大小:3522
位于java.util.ArrayList.rangeCheck(未知源)
位于java.util.ArrayList.get(未知源)
位于graphics.renderEngine.OBJLoader.processVertex(OBJLoader.java:122)
在graphics.renderEngine.OBJLoader.loadObjModel(OBJLoader.java:82)中
在main.main.init(main.java:150)
main.main.(main.java:82)
在main.main.main(main.java:75)
我只是感到困惑,我不知道为什么会出现这种异常,提前感谢您提供的任何线索。列表的大小是3522,索引值在0到3521之间。但是您试图使用不存在的索引3522来访问列表中的元素,因此出现了异常。在访问列表元素之前,您需要具备检查索引是否小于大小的条件。列表的大小为3522,索引值在0到3521之间。但是您试图使用不存在的索引3522来访问列表中的元素,因此出现了异常。在访问列表元素之前,需要具备检查索引是否小于大小的条件。实际问题是,一旦看到第一个“f”(面)声明,就停止读取“v”、“vt”和“vn”声明。您不能这样做,因为Wavefront OBJ规范没有规定“v*”声明必须在“f”声明之前。事实上,在您的示例文件中,它们是混合的。 这意味着,当您停止读取第一个循环中的“v*”声明时,最终将找到引用其他未读取的“v*”声明的“f”声明,因此您将得到IndexOutOfBounds异常。
您应该重新构造循环,以便可以随时读取“v*”和“f”声明。实际问题是,一旦看到第一个“f”(面)声明,您就停止读取“v”、“vt”和“vn”声明。您不能这样做,因为Wavefront OBJ规范没有规定“v*”声明必须在“f”声明之前。事实上,在您的示例文件中,它们是混合的。 这意味着,当您停止读取第一个循环中的“v*”声明时,最终将找到引用其他未读取的“v*”声明的“f”声明,因此您将得到IndexOutOfBounds异常。
您应该重新构造循环,以便随时可以读取“v*”和“f”声明。看起来您正在学习 教程很好;它工作得很好。(我以前用过)
问题 问题在于,他的OBJLoader特定于他选择的OBJ文件格式,而不是“通用”OBJ加载程序 他的格式如下: v/vt/vn/f/EOF 而您的更像: v/vt/vn/f/v/vt/vn/f/../EOF 您发布的代码假定在找到第一行“f”后,将不再有顶点数据,之后将只有面数据 因此,代码没有接收所有顶点数据,因此当您尝试索引到该数据时,它不在那里 修复 有两种可能的解决方案:
我猜,由于您正在学习有关该主题的教程,因此您在这方面没有太多经验,最简单的方法是解决方案2。看起来您正在学习 教程很好;它工作得很好。(我以前用过)
问题 问题在于,他的OBJLoader特定于他选择的OBJ文件格式,而不是“通用”OBJ加载程序 他的格式如下: v/vt/vn/f/EOF 而您的更像: v/vt/vn/f/v/vt/vn/f/../EOF 您发布的代码假定在找到第一行“f”后,将不再有顶点数据,之后将只有面数据 因此,代码没有接收所有顶点数据,因此当您尝试索引到该数据时,它不在那里 修复 有两种可能的解决方案:
返回loader.loadToVAO(垂直阵列、纹理阵列、指示阵列) 这里有一些小的拼写错误,请参见textureArray的拼写 您取消了纹理阵列的定义。有一个s。检查
返回loader.loadToVAO(垂直阵列、纹理阵列、指示阵列) 这里有一些小的拼写错误,请参见textureArray的拼写 您定义了纹理数组,其中有一个s.如下所示:if(textures.size()>Integer.parseInt(vertexData[1])-1)
java.lang.IndexOutOfBoundsException: Index: 3522, Size: 3522
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at graphics.renderEngine.OBJLoader.processVertex(OBJLoader.java:122)
at graphics.renderEngine.OBJLoader.loadObjModel(OBJLoader.java:82)
at main.Main.init(Main.java:150)
at main.Main.<init>(Main.java:82)
at main.Main.main(Main.java:75)