package ast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
public class ResLoader {
static File mtlFile;
/**
* Loads .OBJ model from file
* @param file .OBJ model file
* @return Model
* @throws FileNotFoundException
* @throws IOException
*/
public static Model loadOBJ(File file)throws FileNotFoundException, IOException{
Texture texture = null;
Map<String, Texture> textures = new HashMap<String, Texture>();
BufferedReader reader = new BufferedReader(new FileReader(file));
Model model = new Model();
String line;
while((line = reader.readLine()) != null){
if(line.startsWith("mtllib")){
mtlFile = new File(line.split(" ")[1]);
}else if(line.startsWith("usemtl")){
String material = line.split(" ")[1];
//if already loaded texture
if(textures.containsKey(material)){
texture = textures.get(material);
//else load
}else{
textures.put(material, loadMaterial(material));
texture = textures.get(material);
}
//vertices
}else 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]);
Vector3f vert = new Vector3f(x,y,z);
model.vertices.add(vert);
checkBounds(model, vert);
//normals
}else if(line.startsWith("vn ")){
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
model.normals.add(new Vector3f(x, y, z));
//texture coords
}else if(line.startsWith("vt ")){
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
model.textureVertices.add(new Vector2f(x, y));
}
//faces
else if(line.startsWith("f ")){
Vector3f vertexIndeces = new Vector3f();
Vector3f normalIndeces = new Vector3f();
Vector3f textureIndeces = new Vector3f();
//splits line into 4 parts
String[] tokens = line.split(" ");
String[] parts;
parts = tokens[1].split("/");
vertexIndeces.x = Integer.parseInt(parts[0]);
textureIndeces.x = Integer.parseInt(parts[1]);
normalIndeces.x = Integer.parseInt(parts[2]);
parts = tokens[2].split("/");
vertexIndeces.y = Integer.parseInt(parts[0]);
textureIndeces.y = Integer.parseInt(parts[1]);
normalIndeces.y = Integer.parseInt(parts[2]);
parts = tokens[3].split("/");
vertexIndeces.z = Integer.parseInt(parts[0]);
textureIndeces.z = Integer.parseInt(parts[1]);
normalIndeces.z = Integer.parseInt(parts[2]);
model.faces.add(new Face(vertexIndeces,textureIndeces, normalIndeces, texture));
}
}
reader.close();
return model;
}
/**
* Loads Texture
* @param tex String name of texture in AssetStore
* @return Texture
*/
public static Texture loadTexture(String tex){
Texture texture = null;
String format = tex.substring(tex.lastIndexOf('.') + 1);
try {
texture = TextureLoader.getTexture(format, ResourceLoader.getResourceAsStream(tex));
} catch (IOException e) {
e.printStackTrace();
}
return texture;
}
/**
* Loads material from model file
* @param ref String
* @return Model
* @throws IOException
*/
private static Texture loadMaterial(String ref) throws IOException{
BufferedReader reader = new BufferedReader(new FileReader("res/model/" + mtlFile));
Texture texture = null;
String line = "";
String tex = null;
while((line != null)){
line = reader.readLine();
if(line != null){
if(line.startsWith("newmtl")){
if(line.split(" ")[1].equalsIgnoreCase(ref)){
break;
}
}
}
}
while(line != null){
line = reader.readLine();
if(line.split(" ")[0].equalsIgnoreCase("map_Kd")){
tex = line.split(" ")[1];
break;
}
}
if (tex != null){
texture = loadTexture("res/model/" + tex);
}
reader.close();
return texture;
}
/**
* Find max, min points for model
* @param m Model
* @param vec Vector
*/
private static void checkBounds(Model m, Vector3f vec){
if(vec.x < m.min.x){
m.min.x = vec.x;
}else if(vec.x > m.max.x){
m.max.x = vec.x;
}
if(vec.y < m.min.y){
m.min.y = vec.y;
}else if(vec.y > m.max.y){
m.max.y = vec.y;
}
if(vec.z < m.min.z){
m.min.z = vec.z;
}else if(vec.x > m.max.z){
m.max.z = vec.z;
}
}
}
class Face{
public Vector3f vertex = new Vector3f();
public Vector3f normal = new Vector3f();
public Vector3f textureVertex = new Vector3f();
public Texture texture;
public Face(Vector3f vertex,Vector3f textureVertex, Vector3f normal, Texture texture){
this.vertex = vertex;
this.normal = normal;
this.textureVertex = textureVertex;
this.texture = texture;
}
}