Saturday, March 5, 2016

opengl - How do I get min/max on a mesh



I am trying to create an AABB but I need to know how to store min/max from a mesh.


Here is my code(I got it from thin matrix) :


package com.chimpro.london.objLoader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.util.vector.Vector2f;

import org.lwjgl.util.vector.Vector3f;

import com.chimpro.london.MainComp;
import com.chimpro.london.gfx.Loader;
import com.chimpro.london.models.TexturedModel;

public class OBJFileLoader {

public static TexturedModel loadOBJ(String objFileName,String textureLoc) throws IOException {
InputStreamReader fis = new InputStreamReader(MainComp.class.getResourceAsStream(objFileName));

BufferedReader reader = new BufferedReader(fis);
String line;
List vertices = new ArrayList();
List textures = new ArrayList();
List normals = new ArrayList();
List indices = new ArrayList();
try {
while (true) {
line = reader.readLine();
if (line.startsWith("v ")) {

String[] currentLine = line.split(" ");
Vector3f vertex = new Vector3f((float) Float.valueOf(currentLine[1]),
(float) Float.valueOf(currentLine[2]),
(float) Float.valueOf(currentLine[3]));
Vertex newVertex = new Vertex(vertices.size(), vertex);
vertices.add(newVertex);

} else if (line.startsWith("vt ")) {
String[] currentLine = line.split(" ");
Vector2f texture = new Vector2f((float) Float.valueOf(currentLine[1]),

(float) Float.valueOf(currentLine[2]));
textures.add(texture);
} else if (line.startsWith("vn ")) {
String[] currentLine = line.split(" ");
Vector3f normal = new Vector3f((float) Float.valueOf(currentLine[1]),
(float) Float.valueOf(currentLine[2]),
(float) Float.valueOf(currentLine[3]));
normals.add(normal);
} else if (line.startsWith("f ")) {
break;

}
}
while (line != null && line.startsWith("f ")) {
String[] currentLine = line.split(" ");
String[] vertex1 = currentLine[1].split("/");
String[] vertex2 = currentLine[2].split("/");
String[] vertex3 = currentLine[3].split("/");
processVertex(vertex1, vertices, indices);
processVertex(vertex2, vertices, indices);
processVertex(vertex3, vertices, indices);

line = reader.readLine();
}
reader.close();
} catch (IOException e) {
System.err.println("Error reading the file");
}
removeUnusedVertices(vertices);
float[] verticesArray = new float[vertices.size() * 3];
float[] texturesArray = new float[vertices.size() * 2];
float[] normalsArray = new float[vertices.size() * 3];

float furthest = convertDataToArrays(vertices, textures, normals, verticesArray,
texturesArray, normalsArray);
int[] indicesArray = convertIndicesListToArray(indices);
TexturedModel model = new TexturedModel(Loader.loadToVao(verticesArray, texturesArray, normalsArray, indicesArray),0,vertices,furthest, textureLoc);
return model;

}

private static void processVertex(String[] vertex, List vertices, List indices) {
int index = Integer.parseInt(vertex[0]) - 1;

Vertex currentVertex = vertices.get(index);
int textureIndex = Integer.parseInt(vertex[1]) - 1;
int normalIndex = Integer.parseInt(vertex[2]) - 1;
if (!currentVertex.isSet()) {
currentVertex.setTextureIndex(textureIndex);
currentVertex.setNormalIndex(normalIndex);
indices.add(index);
} else {
dealWithAlreadyProcessedVertex(currentVertex, textureIndex, normalIndex, indices,
vertices);

}
}

private static int[] convertIndicesListToArray(List indices) {
int[] indicesArray = new int[indices.size()];
for (int i = 0; i < indicesArray.length; i++) {
indicesArray[i] = indices.get(i);
}
return indicesArray;
}


private static float convertDataToArrays(List vertices, List textures,
List normals, float[] verticesArray, float[] texturesArray,
float[] normalsArray) {
float furthestPoint = 0;
for (int i = 0; i < vertices.size(); i++) {
Vertex currentVertex = vertices.get(i);
if (currentVertex.getLength() > furthestPoint) {
furthestPoint = currentVertex.getLength();
}

Vector3f position = currentVertex.getPosition();
Vector2f textureCoord = textures.get(currentVertex.getTextureIndex());
Vector3f normalVector = normals.get(currentVertex.getNormalIndex());
verticesArray[i * 3] = position.x;
verticesArray[i * 3 + 1] = position.y;
verticesArray[i * 3 + 2] = position.z;
texturesArray[i * 2] = textureCoord.x;
texturesArray[i * 2 + 1] = 1 - textureCoord.y;
normalsArray[i * 3] = normalVector.x;
normalsArray[i * 3 + 1] = normalVector.y;

normalsArray[i * 3 + 2] = normalVector.z;
}
return furthestPoint;
}

private static void dealWithAlreadyProcessedVertex(Vertex previousVertex, int newTextureIndex,
int newNormalIndex, List indices, List vertices) {
if (previousVertex.hasSameTextureAndNormal(newTextureIndex, newNormalIndex)) {
indices.add(previousVertex.getIndex());
} else {

Vertex anotherVertex = previousVertex.getDuplicateVertex();
if (anotherVertex != null) {
dealWithAlreadyProcessedVertex(anotherVertex, newTextureIndex, newNormalIndex,
indices, vertices);
} else {
Vertex duplicateVertex = new Vertex(vertices.size(), previousVertex.getPosition());
duplicateVertex.setTextureIndex(newTextureIndex);
duplicateVertex.setNormalIndex(newNormalIndex);
previousVertex.setDuplicateVertex(duplicateVertex);
vertices.add(duplicateVertex);

indices.add(duplicateVertex.getIndex());
}

}
}

private static void removeUnusedVertices(List vertices){
for(Vertex vertex:vertices){
if(!vertex.isSet()){
vertex.setTextureIndex(0);

vertex.setNormalIndex(0);
}
}
}

}

Answer



Same solution as Macky ben Jonah's but a little neater:


private static Vector3f getExtreme(final List vertices,
final BinaryOperator op) {

final float x = vertices.stream().map(v -> v.getPosition().x).reduce(op).orElse(0f);
final float y = vertices.stream().map(v -> v.getPosition().y).reduce(op).orElse(0f);
final float z = vertices.stream().map(v -> v.getPosition().z).reduce(op).orElse(0f);
return new Vector3f(x, y, z);
}

Then you can use it like this:


Vector3f min = getExtreme(vertices, Math::min);
Vector3f max = getExtreme(vertices, Math::max);


This requires Java 8 because it makes use of Streams and it is also a lot more performance friendly than the original solution since it does not have to create new lists and loop through them every time it is called.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...