/****************************************************************************** * Copyright (c) 2008 Marco Della Vedova, Matteo Foppiano * and Pimods contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.pixelinstrument.net/license/cpl-v10.html ******************************************************************************/ package net.sf.robocode.bv3d.model; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.StringTokenizer; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import net.sf.robocode.bv3d.math.Vertex3f; /** * @author Marco Della Vedova - pixelinstrument.net * @author Matteo Foppiano - pixelinstrument.net * */ public class LoadModel { public static final String modelsPath = "misc/models/"; public static final String texturesPath = (LoadModel.modelsPath + "textures/"); public static Model getModelFromFile(String filename) { ArrayList<Vertex3f> vertexList = new ArrayList<Vertex3f>(); ArrayList<Vertex3f> normalList = new ArrayList<Vertex3f>(); ArrayList<Vertex3f> uvList = new ArrayList<Vertex3f>(); ArrayList<ModelFace> faceList = new ArrayList<ModelFace>(); ArrayList<ModelObject> objectList = new ArrayList<ModelObject>(); ArrayList<ModelGroup> groupList = new ArrayList<ModelGroup>(); ArrayList<ModelMaterial> materialList = new ArrayList<ModelMaterial>(); ArrayList<ModelTexture> textureList = new ArrayList<ModelTexture>(); ArrayList<ModelTexture> materialCurrentTexture = new ArrayList<ModelTexture>(); Model model = new Model(); try { BufferedReader buffer = new BufferedReader(new FileReader(LoadModel.modelsPath + filename)); String line = buffer.readLine(); ModelGroup groupCurrent = new ModelGroup(); ModelObject objectCurrent = new ModelObject(); ModelMaterial materialCurrent = new ModelMaterial(); ModelTexture textureCurrent = new ModelTexture(); while (line != null) { StringTokenizer t = new StringTokenizer(line); if (t.hasMoreTokens()) { String type = t.nextToken(); if (type.equals("[GroupBegin]")) { objectList = new ArrayList<ModelObject>(); } else if (type.equals("[GroupEnd]")) { groupCurrent.setObjects(objectList); groupList.add(groupCurrent); } else if (type.equals("g")) { groupCurrent = new ModelGroup(t.nextToken()); // System.out.println( "New group: " + groupCurrent.getName() ); } else if (type.equals("[ObjectBegin]")) { faceList = new ArrayList<ModelFace>(); } else if (type.equals("[ObjectEnd]")) { objectCurrent.setFaces(faceList); objectList.add(objectCurrent); } else if (type.equals("o")) { // Object objectCurrent = new ModelObject(t.nextToken()); // System.out.println( "New object: " + objectCurrent.getName() ); } else if (type.equals("c")) { // Center Vertex3f center = new Vertex3f(); center.x = new Float(t.nextToken()).floatValue(); center.y = new Float(t.nextToken()).floatValue(); center.z = new Float(t.nextToken()).floatValue(); objectCurrent.setCenter(center); } else if (type.equals("om")) { // Object Material String mn = t.nextToken(); for (int i = 0; i < materialList.size(); i++) { ModelMaterial mat = (ModelMaterial) materialList.get(i); if (mat.getName().equals(mn)) { objectCurrent.setMaterialIndex(i); // System.out.println( "Material: " + mat.getName() + " index: " + i + " added to object: " + objectCurrent.getName() ); break; } } } else if (type.equals("v")) { // Vertex Vertex3f v = new Vertex3f(); v.x = new Float(t.nextToken()).floatValue(); v.y = new Float(t.nextToken()).floatValue(); v.z = new Float(t.nextToken()).floatValue(); vertexList.add(v); } else if (type.equals("vt")) { // Vertex Texture Vertex3f vt = new Vertex3f(); vt.x = new Float(t.nextToken()).floatValue(); vt.y = new Float(t.nextToken()).floatValue(); vt.z = new Float(t.nextToken()).floatValue(); uvList.add(vt); } else if (type.equals("vn")) { // Vertex Normal Vertex3f vn = new Vertex3f(); vn.x = new Float(t.nextToken()).floatValue(); vn.y = new Float(t.nextToken()).floatValue(); vn.z = new Float(t.nextToken()).floatValue(); normalList.add(vn); } else if (type.equals("f")) { // Face int size = t.countTokens(); int vertexIndex[] = new int[size]; int normalIndex[] = new int[size]; int uvIndex[] = new int[size]; for (int i = 0; i < size; i++) { StringTokenizer split = new StringTokenizer(t.nextToken(), "/"); if (split.hasMoreTokens()) { vertexIndex[i] = (new Integer(split.nextToken())).intValue(); } if (split.hasMoreTokens()) { uvIndex[i] = (new Integer(split.nextToken())).intValue(); } if (split.hasMoreTokens()) { normalIndex[i] = (new Integer(split.nextToken())).intValue(); } else { normalIndex[i] = uvIndex[i]; uvIndex[i] = 0; } } ModelFace face = new ModelFace(vertexIndex, normalIndex, uvIndex); faceList.add(face); } else if (type.equals("[MaterialBegin]")) { materialCurrentTexture = new ArrayList<ModelTexture>(); } else if (type.equals("[MaterialEnd]")) { materialCurrent.setTextures(materialCurrentTexture); materialList.add(materialCurrent); } else if (type.equals("[TextureBegin]")) {/* none */} else if (type.equals("[TextureEnd]")) { textureList.add(textureCurrent); } else if (type.equals("m")) { // Material materialCurrent = new ModelMaterial(t.nextToken()); } else if (type.equals("mt")) { // Material Texture String tn = t.nextToken(); for (int i = 0; i < textureList.size(); i++) { ModelTexture tex = (ModelTexture) textureList.get(i); if (tex.getName().equals(tn)) { materialCurrentTexture.add(tex); // System.out.println( "Texture: " + tex.getName() + " added to material: " + materialCurrent.getName() ); break; } } } else if (type.equals("t")) { // Texture textureCurrent = new ModelTexture(t.nextToken()); } else if (type.equals("ti")) { // Texture Image textureCurrent.setImage(t.nextToken()); } } line = buffer.readLine(); } model.setGroups(groupList); model.setVertex(vertexList); model.setNormals(normalList); model.setUV(uvList); model.setMaterials(materialList); buffer.close(); } catch (FileNotFoundException e) { System.err.println("Error: File not found"); } catch (IOException e) { System.err.println("Error: I/O exception"); } return(model); } public static BufferedImage getTextureFromFile(String filename) { BufferedImage bi = null; try { BufferedImage biOrig = ImageIO.read(new File(LoadModel.texturesPath + filename)); bi = new BufferedImage(biOrig.getWidth(), biOrig.getHeight(), /* biOrig.getType()*/ BufferedImage.TYPE_INT_ARGB); int height = bi.getHeight(); for (int r = 0; r < height; r++) { for (int c = 0; c < bi.getWidth(); c++) { // Conversion from ARGB to RGBA int color = biOrig.getRGB(c, r); int blue = color & 0x000000ff; int green = (color & 0x0000ff00) >> 8; int red = (color & 0x00ff0000) >> 16; int alpha = (color & 0xff000000) >> 24; // float grey = ( ( red+green+blue )*0.333f ); // if( grey<200 ) { // alpha = ( int )( 255*grey*0.005f ); // } else { // alpha = 255; // } color = red * 0x1000000 + green * 0x10000 + blue * 0x100 + alpha; // OpenGL wants the bottom of the image on the first row -> we must flip images vertically bi.setRGB(c, height - r - 1, color); } } } catch (IOException e) { System.err.println("Error: I/O exception: " + e); } return(bi); } }