Removing my Wavefront Object loader now that it is working properly in Forge 650+

Modifying model classes to use the new Forge model loader
Set a dependency that EE3 requires Forge 650 and higher
Cleaning up source code/formatting
This commit is contained in:
pahimar 2013-04-10 21:04:31 -04:00
parent 3c93e6a62f
commit fea6200564
23 changed files with 71 additions and 876 deletions

View file

@ -59,25 +59,37 @@ import cpw.mods.fml.relauncher.Side;
* @license Lesser GNU Public License v3 (http://www.gnu.org/licenses/lgpl.html)
*
*/
@Mod(modid = Reference.MOD_ID, name = Reference.MOD_NAME, version = Reference.VERSION, certificateFingerprint = Reference.FINGERPRINT)
@NetworkMod(channels = { Reference.CHANNEL_NAME }, clientSideRequired = true, serverSideRequired = false, packetHandler = PacketHandler.class)
@Mod(
modid = Reference.MOD_ID,
name = Reference.MOD_NAME,
version = Reference.VERSION,
dependencies = Reference.DEPENDENCIES,
certificateFingerprint = Reference.FINGERPRINT)
@NetworkMod(
channels = { Reference.CHANNEL_NAME },
clientSideRequired = true,
serverSideRequired = false,
packetHandler = PacketHandler.class)
public class EquivalentExchange3 {
@Instance(Reference.MOD_ID)
public static EquivalentExchange3 instance;
@SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.SERVER_PROXY_CLASS)
@SidedProxy(
clientSide = Reference.CLIENT_PROXY_CLASS,
serverSide = Reference.SERVER_PROXY_CLASS)
public static CommonProxy proxy;
public static CreativeTabs tabsEE3 = new CreativeTabEE3(CreativeTabs.getNextID(), Reference.MOD_ID);
@FingerprintWarning
public void invalidFingerprint(FMLFingerprintViolationEvent event) {
// Report (log) to the user that the version of Equivalent Exchange 3 they are using has been changed/tampered with
LogHelper.log(Level.SEVERE, Strings.INVALID_FINGERPRINT_MESSAGE);
}
@ServerStarting
public void serverStarting(FMLServerStartingEvent event) {

View file

@ -1,7 +1,8 @@
package com.pahimar.ee3.client.model;
import net.minecraft.client.model.ModelBase;
import net.minecraftforge.client.model.obj.WavefrontObject;
import net.minecraftforge.client.model.AdvancedModelLoader;
import net.minecraftforge.client.model.IModelCustom;
import net.minecraftforge.common.ForgeDirection;
import org.lwjgl.opengl.GL11;
@ -26,33 +27,32 @@ import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ModelAludel extends ModelBase {
private WavefrontObject modelAludelObj;
private IModelCustom modelAludel;
public ModelAludel() {
modelAludelObj = new WavefrontObject(Models.ALUDEL);
modelAludelObj.load();
modelAludel = AdvancedModelLoader.loadModel(Models.ALUDEL);
}
public void render() {
modelAludelObj.renderAll();
modelAludel.renderAll();
}
public void render(TileAludel aludel, double x, double y, double z) {
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_LIGHTING);
// Scale, Translate, Rotate
scaleTranslateRotate(x, y, z, aludel.getOrientation());
// Bind texture
FMLClientHandler.instance().getClient().renderEngine.bindTexture(Textures.MODEL_ALUDEL);
// Render
this.render();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glPopMatrix();
}

View file

@ -1,7 +1,8 @@
package com.pahimar.ee3.client.model;
import net.minecraft.client.model.ModelBase;
import net.minecraftforge.client.model.obj.WavefrontObject;
import net.minecraftforge.client.model.AdvancedModelLoader;
import net.minecraftforge.client.model.IModelCustom;
import org.lwjgl.opengl.GL11;
@ -25,36 +26,35 @@ import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ModelCalcinator extends ModelBase {
private WavefrontObject modelCalcinatorObj;
private IModelCustom modelCalcinator;
public ModelCalcinator() {
modelCalcinatorObj = new WavefrontObject(Models.CALCINATOR);
modelCalcinatorObj.load();
modelCalcinator = AdvancedModelLoader.loadModel(Models.CALCINATOR);
}
public void render() {
modelCalcinatorObj.renderAll();
modelCalcinator.renderAll();
}
public void render(TileCalcinator calcinator, double x, double y, double z) {
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_LIGHTING);
// Scale, Translate, Rotate
GL11.glScalef(1.0F, 1.0F, 1.0F);
GL11.glTranslatef((float) x + 0.5F, (float) y + 0.0F, (float) z + 1.2F);
GL11.glRotatef(45F, 0F, 1F, 0F);
GL11.glRotatef(-90F, 1F, 0F, 0F);
// Bind texture
FMLClientHandler.instance().getClient().renderEngine.bindTexture(Textures.MODEL_CALCINATOR);
// Render
this.render();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glPopMatrix();
}

View file

@ -68,18 +68,18 @@ public class ItemAludelRenderer implements IItemRenderer {
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_LIGHTING);
// Scale, Translate, Rotate
GL11.glScalef(scale, scale, scale);
GL11.glTranslatef(x, y, z);
GL11.glRotatef(-90F, 1F, 0, 0);
// Bind texture
FMLClientHandler.instance().getClient().renderEngine.bindTexture(Textures.MODEL_ALUDEL);
// Render
aludelModel.render();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glPopMatrix();
}

View file

@ -68,18 +68,18 @@ public class ItemCalcinatorRenderer implements IItemRenderer {
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_LIGHTING);
// Scale, Translate, Rotate
GL11.glScalef(scale, scale, scale);
GL11.glTranslatef(x, y, z);
GL11.glRotatef(-90F, 1F, 0, 0);
// Bind texture
FMLClientHandler.instance().getClient().renderEngine.bindTexture(Textures.MODEL_CALCINATOR);
// Render
calcinatorModel.render();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glPopMatrix();
}

View file

@ -25,7 +25,8 @@ import cpw.mods.fml.relauncher.SideOnly;
*
*/
@SideOnly(Side.CLIENT)
public class TileEntityAlchemicalChestRenderer extends TileEntitySpecialRenderer {
public class TileEntityAlchemicalChestRenderer extends
TileEntitySpecialRenderer {
private ModelChest modelChest = new ModelChest();

View file

@ -33,7 +33,7 @@ public class EntityLivingHandler {
if (event.source.getSourceOfDamage() instanceof EntityArrow) {
if (((EntityArrow) event.source.getSourceOfDamage()).shootingEntity != null) {
if (((EntityArrow) event.source.getSourceOfDamage()).shootingEntity instanceof EntityPlayer) {
ItemDropHelper.dropMiniumShard((EntityPlayer) ((EntityArrow)event.source.getSourceOfDamage()).shootingEntity, event.entityLiving);
ItemDropHelper.dropMiniumShard((EntityPlayer) ((EntityArrow) event.source.getSourceOfDamage()).shootingEntity, event.entityLiving);
}
}
}

View file

@ -42,7 +42,7 @@ public class ItemAlchemicalBag extends ItemEE {
@Override
@SideOnly(Side.CLIENT)
public void updateIcons(IconRegister iconRegister) {
public void registerIcons(IconRegister iconRegister) {
icons = new Icon[ALCHEMICAL_BAG_SUBTYPES.length];

View file

@ -61,7 +61,7 @@ public class ItemAlchemicalDust extends ItemEE {
@Override
@SideOnly(Side.CLIENT)
public void updateIcons(IconRegister iconRegister) {
public void registerIcons(IconRegister iconRegister) {
icons = new Icon[ALCHEMICAL_DUST_NAMES.length];
@ -81,12 +81,12 @@ public class ItemAlchemicalDust extends ItemEE {
else
return false;
}
@Override
public String getItemDisplayName(ItemStack itemStack) {
int meta = MathHelper.clamp_int(itemStack.getItemDamage(), 0, 5);
switch (meta) {
case 0:
return EnumChatFormatting.WHITE + super.getItemDisplayName(itemStack);

View file

@ -28,8 +28,8 @@ public class ItemEE extends Item {
@Override
@SideOnly(Side.CLIENT)
public void updateIcons(IconRegister iconRegister) {
public void registerIcons(IconRegister iconRegister) {
iconIndex = iconRegister.registerIcon(Reference.MOD_ID.toLowerCase() + ":" + this.getUnlocalizedName().substring(this.getUnlocalizedName().indexOf(".") + 1));
itemIcon = iconRegister.registerIcon(Reference.MOD_ID.toLowerCase() + ":" + this.getUnlocalizedName().substring(this.getUnlocalizedName().indexOf(".") + 1));
}
}

View file

@ -24,7 +24,8 @@ import cpw.mods.fml.relauncher.SideOnly;
* @license Lesser GNU Public License v3 (http://www.gnu.org/licenses/lgpl.html)
*
*/
public class ItemMiniumStone extends ItemEE implements ITransmutationStone, IKeyBound {
public class ItemMiniumStone extends ItemEE
implements ITransmutationStone, IKeyBound {
public ItemMiniumStone(int id) {
@ -40,10 +41,10 @@ public class ItemMiniumStone extends ItemEE implements ITransmutationStone, IKey
return NBTHelper.hasTag(itemStack, Strings.NBT_ITEM_CRAFTING_GUI_OPEN) || NBTHelper.hasTag(itemStack, Strings.NBT_ITEM_TRANSMUTATION_GUI_OPEN);
}
@Override
public String getItemDisplayName(ItemStack itemStack) {
return EnumChatFormatting.BLUE + super.getItemDisplayName(itemStack);
}

View file

@ -48,7 +48,7 @@ public class ItemPhilosophersStone extends ItemEE
return NBTHelper.hasTag(itemStack, Strings.NBT_ITEM_CRAFTING_GUI_OPEN) || NBTHelper.hasTag(itemStack, Strings.NBT_ITEM_TRANSMUTATION_GUI_OPEN);
}
@Override
public String getItemDisplayName(ItemStack itemStack) {

View file

@ -13,29 +13,6 @@ public class Localizations {
private static final String LANG_RESOURCE_LOCATION = "/mods/ee3/lang/";
public static String[] localeFiles = {
LANG_RESOURCE_LOCATION + "cs_CZ.xml",
LANG_RESOURCE_LOCATION + "cy_GB.xml",
LANG_RESOURCE_LOCATION + "da_DK.xml",
LANG_RESOURCE_LOCATION + "de_DE.xml",
LANG_RESOURCE_LOCATION + "en_US.xml",
LANG_RESOURCE_LOCATION + "es_ES.xml",
LANG_RESOURCE_LOCATION + "fi_FI.xml",
LANG_RESOURCE_LOCATION + "fr_FR.xml",
LANG_RESOURCE_LOCATION + "it_IT.xml",
LANG_RESOURCE_LOCATION + "ja_JP.xml",
LANG_RESOURCE_LOCATION + "la_IT.xml",
LANG_RESOURCE_LOCATION + "nl_NL.xml",
LANG_RESOURCE_LOCATION + "nb_NO.xml",
LANG_RESOURCE_LOCATION + "pl_PL.xml",
LANG_RESOURCE_LOCATION + "pt_BR.xml",
LANG_RESOURCE_LOCATION + "pt_PT.xml",
LANG_RESOURCE_LOCATION + "ru_RU.xml",
LANG_RESOURCE_LOCATION + "sk_SK.xml",
LANG_RESOURCE_LOCATION + "sr_RS.xml",
LANG_RESOURCE_LOCATION + "sv_SE.xml",
LANG_RESOURCE_LOCATION + "tr_TR.xml",
LANG_RESOURCE_LOCATION + "zh_CN.xml",
LANG_RESOURCE_LOCATION + "zh_TW.xml" };
public static String[] localeFiles = { LANG_RESOURCE_LOCATION + "cs_CZ.xml", LANG_RESOURCE_LOCATION + "cy_GB.xml", LANG_RESOURCE_LOCATION + "da_DK.xml", LANG_RESOURCE_LOCATION + "de_DE.xml", LANG_RESOURCE_LOCATION + "en_US.xml", LANG_RESOURCE_LOCATION + "es_ES.xml", LANG_RESOURCE_LOCATION + "fi_FI.xml", LANG_RESOURCE_LOCATION + "fr_FR.xml", LANG_RESOURCE_LOCATION + "it_IT.xml", LANG_RESOURCE_LOCATION + "ja_JP.xml", LANG_RESOURCE_LOCATION + "la_IT.xml", LANG_RESOURCE_LOCATION + "nl_NL.xml", LANG_RESOURCE_LOCATION + "nb_NO.xml", LANG_RESOURCE_LOCATION + "pl_PL.xml", LANG_RESOURCE_LOCATION + "pt_BR.xml", LANG_RESOURCE_LOCATION + "pt_PT.xml", LANG_RESOURCE_LOCATION + "ru_RU.xml", LANG_RESOURCE_LOCATION + "sk_SK.xml", LANG_RESOURCE_LOCATION + "sr_RS.xml", LANG_RESOURCE_LOCATION + "sv_SE.xml", LANG_RESOURCE_LOCATION + "tr_TR.xml", LANG_RESOURCE_LOCATION + "zh_CN.xml", LANG_RESOURCE_LOCATION + "zh_TW.xml" };
}

View file

@ -19,6 +19,7 @@ public class Reference {
public static final String MOD_NAME = "Equivalent Exchange 3";
public static final String VERSION = "@VERSION@";
public static final String CHANNEL_NAME = MOD_ID;
public static final String DEPENDENCIES = "required-after:Forge@[7.7.1.650,)";
public static final String FINGERPRINT = "@FINGERPRINT@";
public static final int SECOND_IN_TICKS = 20;
public static final int SHIFTED_ID_RANGE_CORRECTION = 256;

View file

@ -17,7 +17,7 @@ public class Strings {
/* Fingerprint check related constants */
public static final String INVALID_FINGERPRINT_MESSAGE = "The copy of Equivalent Exchange 3 that you are running has been modified from the original, and unpredictable things may happen. Please consider re-downloading the original version of the mod.";
/* Version check related constants */
public static final String VERSION_CHECK_INIT_LOG_MESSAGE = "version.init_log_message";
public static final String UNINITIALIZED_MESSAGE = "version.uninitialized";

View file

@ -25,9 +25,12 @@ import com.pahimar.ee3.network.packet.PacketTileUpdate;
*
*/
public enum PacketTypeHandler {
KEY(PacketKeyPressed.class), TILE(PacketTileUpdate.class), REQUEST_EVENT(
PacketRequestEvent.class), SPAWN_PARTICLE(PacketSpawnParticle.class), SOUND_EVENT(
PacketSoundEvent.class), ITEM_UPDATE(PacketItemUpdate.class);
KEY(PacketKeyPressed.class),
TILE(PacketTileUpdate.class),
REQUEST_EVENT(PacketRequestEvent.class),
SPAWN_PARTICLE(PacketSpawnParticle.class),
SOUND_EVENT(PacketSoundEvent.class),
ITEM_UPDATE(PacketItemUpdate.class);
private Class<? extends PacketEE> clazz;

View file

@ -109,8 +109,8 @@ public class RecipesTransmutationStone {
RecipeHelper.addRecipe(new ItemStack(Item.ingotGold, 4), transmutationStone, Item.diamond);
/* 8 Iron Block <-> 1 Gold Block */
RecipeHelper.addRecipe(Block.blockGold, transmutationStone, Block.blockSteel, Block.blockSteel, Block.blockSteel, Block.blockSteel, Block.blockSteel, Block.blockSteel, Block.blockSteel, Block.blockSteel);
RecipeHelper.addRecipe(new ItemStack(Block.blockSteel, 8), transmutationStone, Block.blockGold);
RecipeHelper.addRecipe(Block.blockGold, transmutationStone, Block.blockIron, Block.blockIron, Block.blockIron, Block.blockIron, Block.blockIron, Block.blockIron, Block.blockIron, Block.blockIron);
RecipeHelper.addRecipe(new ItemStack(Block.blockIron, 8), transmutationStone, Block.blockGold);
/* 4 Gold Block <-> 1 Diamond Block */
RecipeHelper.addRecipe(Block.blockDiamond, transmutationStone, Block.blockGold, Block.blockGold, Block.blockGold, Block.blockGold);

View file

@ -1,13 +0,0 @@
package net.minecraftforge.client.model;
public interface IModelCustom {
public abstract IModelCustom load(String fileName);
public abstract void renderAll();
public abstract void renderPart(String partName);
}

View file

@ -1,84 +0,0 @@
package net.minecraftforge.client.model.obj;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.Vec3;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class Face
{
public Vertex[] vertices;
public Vertex[] vertexNormals;
public Vertex faceNormal;
public TextureCoordinate[] textureCoordinates;
public void addFaceForRender(Tessellator tessellator)
{
addFaceForRender(tessellator, 0.0005F);
}
public void addFaceForRender(Tessellator tessellator, float textureOffset)
{
if (faceNormal == null)
{
faceNormal = this.calculateFaceNormal();
}
tessellator.setNormal(faceNormal.x, faceNormal.y, faceNormal.z);
float averageU = 0F;
float averageV = 0F;
if (textureCoordinates.length != 0)
{
for (int i = 0; i < textureCoordinates.length; ++i)
{
averageU += textureCoordinates[i].u;
averageV += textureCoordinates[i].v;
}
averageU = averageU / textureCoordinates.length;
averageV = averageV / textureCoordinates.length;
}
float offsetU, offsetV;
for (int i = 0; i < vertices.length; ++i)
{
if (textureCoordinates.length != 0)
{
offsetU = textureOffset;
offsetV = textureOffset;
if (textureCoordinates[i].u > averageU)
{
offsetU = -offsetU;
}
if (textureCoordinates[i].v > averageV)
{
offsetV = -offsetV;
}
tessellator.addVertexWithUV(vertices[i].x, vertices[i].y, vertices[i].z, textureCoordinates[i].u + offsetU, textureCoordinates[i].v + offsetV);
}
else
{
tessellator.addVertex(vertices[i].x, vertices[i].y, vertices[i].z);
}
}
}
public Vertex calculateFaceNormal()
{
Vec3 v1 = Vec3.createVectorHelper(vertices[1].x - vertices[0].x, vertices[1].y - vertices[0].y, vertices[1].z - vertices[0].z);
Vec3 v2 = Vec3.createVectorHelper(vertices[2].x - vertices[0].x, vertices[2].y - vertices[0].y, vertices[2].z - vertices[0].z);
Vec3 normalVector = null;
normalVector = v1.crossProduct(v2).normalize();
return new Vertex((float) normalVector.xCoord, (float) normalVector.yCoord, (float) normalVector.zCoord);
}
}

View file

@ -1,54 +0,0 @@
package net.minecraftforge.client.model.obj;
import java.util.ArrayList;
import net.minecraft.client.renderer.Tessellator;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class GroupObject
{
public String name;
public ArrayList<Face> faces = new ArrayList<Face>();
public int glDrawingMode;
public GroupObject()
{
this("");
}
public GroupObject(String name)
{
this(name, -1);
}
public GroupObject(String name, int glDrawingMode)
{
this.name = name;
this.glDrawingMode = glDrawingMode;
}
public void render()
{
if (faces.size() > 0)
{
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawing(glDrawingMode);
render(tessellator);
tessellator.draw();
}
}
public void render(Tessellator tessellator)
{
if (faces.size() > 0)
{
for (Face face : faces)
{
face.addFaceForRender(tessellator);
}
}
}
}

View file

@ -1,23 +0,0 @@
package net.minecraftforge.client.model.obj;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class TextureCoordinate
{
public float u, v, w;
public TextureCoordinate(float u, float v)
{
this(u, v, 0F);
}
public TextureCoordinate(float u, float v, float w)
{
this.u = u;
this.v = v;
this.w = w;
}
}

View file

@ -1,32 +0,0 @@
package net.minecraftforge.client.model.obj;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class Vertex
{
public float x, y, z, w;
public Vertex(float x, float y)
{
this(x, y, 0F, 0F);
}
public Vertex(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
this.w = 1F;
}
public Vertex(float x, float y, float z, float w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
}

View file

@ -1,594 +0,0 @@
package net.minecraftforge.client.model.obj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.DataFormatException;
import net.minecraft.client.renderer.Tessellator;
import net.minecraftforge.client.model.IModelCustom;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* Wavefront Object importer
* Based heavily off of the specifications found at http://en.wikipedia.org/wiki/Wavefront_.obj_file
*/
@SideOnly(Side.CLIENT)
public class WavefrontObject implements IModelCustom
{
private static Pattern vertexPattern = Pattern.compile("(v( (\\-){0,1}\\d+\\.\\d+){3,4} *\\n)|(v( (\\-){0,1}\\d+\\.\\d+){3,4} *$)");
private static Pattern vertexNormalPattern = Pattern.compile("(vn( (\\-){0,1}\\d+\\.\\d+){3,4} *\\n)|(vn( (\\-){0,1}\\d+\\.\\d+){3,4} *$)");
private static Pattern textureCoordinatePattern = Pattern.compile("(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *\\n)|(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *$)");
private static Pattern face_V_VT_VN_Pattern = Pattern.compile("(f( \\d+/\\d+/\\d+){3,4} *\\n)|(f( \\d+/\\d+/\\d+){3,4} *$)");
private static Pattern face_V_VT_Pattern = Pattern.compile("(f( \\d+/\\d+){3,4} *\\n)|(f( \\d+/\\d+){3,4} *$)");
private static Pattern face_V_VN_Pattern = Pattern.compile("(f( \\d+//\\d+){3,4} *\\n)|(f( \\d+//\\d+){3,4} *$)");
private static Pattern face_V_Pattern = Pattern.compile("(f( \\d+){3,4} *\\n)|(f( \\d+){3,4} *$)");
private static Pattern groupObjectPattern = Pattern.compile("([go]( [\\w\\d]+) *\\n)|([go]( [\\w\\d]+) *$)");
private static Matcher vertexMatcher, vertexNormalMatcher, textureCoordinateMatcher;
private static Matcher face_V_VT_VN_Matcher, face_V_VT_Matcher, face_V_VN_Matcher, face_V_Matcher;
private static Matcher groupObjectMatcher;
public ArrayList<Vertex> vertices = new ArrayList<Vertex>();
public ArrayList<Vertex> vertexNormals = new ArrayList<Vertex>();
public ArrayList<TextureCoordinate> textureCoordinates = new ArrayList<TextureCoordinate>();
public ArrayList<GroupObject> groupObjects = new ArrayList<GroupObject>();
private GroupObject currentGroupObject;
private String fileName;
public WavefrontObject(String fileName)
{
this.fileName = fileName;
try
{
loadObjModel(this.getClass().getResource(fileName));
}
catch (DataFormatException e)
{
e.printStackTrace();
}
}
public IModelCustom load(String fileName)
{
return new WavefrontObject(fileName);
}
public void load()
{
try
{
loadObjModel(this.getClass().getResource(fileName));
}
catch (DataFormatException e)
{
e.printStackTrace();
}
}
private void loadObjModel(URL fileURL) throws DataFormatException
{
BufferedReader reader = null;
InputStream inputStream = null;
String currentLine = null;
int lineCount = 0;
try
{
inputStream = fileURL.openStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
while ((currentLine = reader.readLine()) != null)
{
lineCount++;
currentLine = currentLine.replaceAll("\\s+", " ").trim();
if (currentLine.startsWith("#") || currentLine.length() == 0)
{
continue;
}
else if (currentLine.startsWith("v "))
{
Vertex vertex = parseVertex(currentLine, lineCount);
if (vertex != null)
{
vertices.add(vertex);
}
}
else if (currentLine.startsWith("vn "))
{
Vertex vertex = parseVertexNormal(currentLine, lineCount);
if (vertex != null)
{
vertexNormals.add(vertex);
}
}
else if (currentLine.startsWith("vt "))
{
TextureCoordinate textureCoordinate = parseTextureCoordinate(currentLine, lineCount);
if (textureCoordinate != null)
{
textureCoordinates.add(textureCoordinate);
}
}
else if (currentLine.startsWith("f "))
{
if (currentGroupObject == null)
{
currentGroupObject = new GroupObject("Default");
}
Face face = parseFace(currentLine, lineCount);
if (face != null)
{
currentGroupObject.faces.add(face);
}
}
else if (currentLine.startsWith("g ") | currentLine.startsWith("o "))
{
GroupObject group = parseGroupObject(currentLine, lineCount);
if (group != null)
{
if (currentGroupObject != null)
{
groupObjects.add(currentGroupObject);
}
}
currentGroupObject = group;
}
}
groupObjects.add(currentGroupObject);
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
inputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public void renderAll()
{
Tessellator tessellator = Tessellator.instance;
if (currentGroupObject != null)
{
tessellator.startDrawing(currentGroupObject.glDrawingMode);
}
else
{
tessellator.startDrawing(GL11.GL_TRIANGLES);
}
for (GroupObject groupObject : groupObjects)
{
groupObject.render(tessellator);
}
tessellator.draw();
}
public void renderOnly(String... groupNames)
{
for (GroupObject groupObject : groupObjects)
{
for (String groupName : groupNames)
{
if (groupName.equalsIgnoreCase(groupObject.name))
{
groupObject.render();
}
}
}
}
public void renderPart(String partName)
{
for (GroupObject groupObject : groupObjects)
{
if (partName.equalsIgnoreCase(groupObject.name))
{
groupObject.render();
}
}
}
public void renderAllExcept(String... excludedGroupNames)
{
for (GroupObject groupObject : groupObjects)
{
for (String excludedGroupName : excludedGroupNames)
{
if (!excludedGroupName.equalsIgnoreCase(groupObject.name))
{
groupObject.render();
}
}
}
}
private Vertex parseVertex(String line, int lineCount) throws DataFormatException
{
Vertex vertex = null;
if (isValidVertexLine(line))
{
line = line.substring(line.indexOf(" ") + 1);
String[] tokens = line.split(" ");
try
{
if (tokens.length == 3)
{
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
}
else if (tokens.length == 4)
{
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]), Float.parseFloat(tokens[3]));
}
}
catch (NumberFormatException e)
{
e.printStackTrace();
}
}
else
{
throw new DataFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return vertex;
}
private Vertex parseVertexNormal(String line, int lineCount) throws DataFormatException
{
Vertex vertexNormal = null;
if (isValidVertexNormalLine(line))
{
line = line.substring(line.indexOf(" ") + 1);
String[] tokens = line.split(" ");
try
{
if (tokens.length == 3)
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
}
catch (NumberFormatException e)
{
e.printStackTrace();
}
}
else
{
throw new DataFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return vertexNormal;
}
private TextureCoordinate parseTextureCoordinate(String line, int lineCount) throws DataFormatException
{
TextureCoordinate textureCoordinate = null;
if (isValidTextureCoordinateLine(line))
{
line = line.substring(line.indexOf(" ") + 1);
String[] tokens = line.split(" ");
try
{
if (tokens.length == 2)
return new TextureCoordinate(Float.parseFloat(tokens[0]), 1 - Float.parseFloat(tokens[1]));
else if (tokens.length == 3)
return new TextureCoordinate(Float.parseFloat(tokens[0]), 1 - Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
}
catch (NumberFormatException e)
{
e.printStackTrace();
}
}
else
{
throw new DataFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return textureCoordinate;
}
private Face parseFace(String line, int lineCount) throws DataFormatException
{
Face face = null;
if (isValidFaceLine(line))
{
face = new Face();
String trimmedLine = line.substring(line.indexOf(" ") + 1);
String[] tokens = trimmedLine.split(" ");
String[] subTokens = null;
if (tokens.length == 3)
{
if (currentGroupObject.glDrawingMode == -1)
{
currentGroupObject.glDrawingMode = GL11.GL_TRIANGLES;
}
else if (currentGroupObject.glDrawingMode != GL11.GL_TRIANGLES)
{
throw new DataFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Invalid number of points for face (expected 4, found " + tokens.length + ")");
}
}
else if (tokens.length == 4)
{
if (currentGroupObject.glDrawingMode == -1)
{
currentGroupObject.glDrawingMode = GL11.GL_QUADS;
}
else if (currentGroupObject.glDrawingMode != GL11.GL_QUADS)
{
throw new DataFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Invalid number of points for face (expected 3, found " + tokens.length + ")");
}
}
face.vertices = new Vertex[tokens.length];
face.textureCoordinates = new TextureCoordinate[tokens.length];
face.vertexNormals = new Vertex[tokens.length];
// f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...
if (isValidFace_V_VT_VN_Line(line))
{
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("/");
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
face.textureCoordinates[i] = textureCoordinates.get(Integer.parseInt(subTokens[1]) - 1);
face.vertexNormals[i] = vertexNormals.get(Integer.parseInt(subTokens[2]) - 1);
}
face.faceNormal = face.calculateFaceNormal();
}
// f v1/vt1 v2/vt2 v3/vt3 ...
else if (isValidFace_V_VT_Line(line))
{
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("/");
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
face.textureCoordinates[i] = textureCoordinates.get(Integer.parseInt(subTokens[1]) - 1);
}
face.faceNormal = face.calculateFaceNormal();
}
// f v1//vn1 v2//vn2 v3//vn3 ...
else if (isValidFace_V_VN_Line(line))
{
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("//");
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
face.vertexNormals[i] = vertexNormals.get(Integer.parseInt(subTokens[1]) - 1);
}
face.faceNormal = face.calculateFaceNormal();
}
// f v1 v2 v3 ...
else if (isValidFace_V_Line(line))
{
for (int i = 0; i < tokens.length; ++i)
{
face.vertices[i] = vertices.get(Integer.parseInt(tokens[i]) - 1);
}
face.faceNormal = face.calculateFaceNormal();
}
else
{
throw new DataFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
}
else
{
throw new DataFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return face;
}
private GroupObject parseGroupObject(String line, int lineCount) throws DataFormatException
{
GroupObject group = null;
if (isValidGroupObjectLine(line))
{
String trimmedLine = line.substring(line.indexOf(" ") + 1);
if (trimmedLine.length() > 0)
{
group = new GroupObject(trimmedLine);
}
}
else
{
throw new DataFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return group;
}
/***
* Verifies that the given line from the model file is a valid vertex
* @param line the line being validated
* @return true if the line is a valid vertex, false otherwise
*/
private static boolean isValidVertexLine(String line)
{
if (vertexMatcher != null)
{
vertexMatcher.reset();
}
vertexMatcher = vertexPattern.matcher(line);
return vertexMatcher.matches();
}
/***
* Verifies that the given line from the model file is a valid vertex normal
* @param line the line being validated
* @return true if the line is a valid vertex normal, false otherwise
*/
private static boolean isValidVertexNormalLine(String line)
{
if (vertexNormalMatcher != null)
{
vertexNormalMatcher.reset();
}
vertexNormalMatcher = vertexNormalPattern.matcher(line);
return vertexNormalMatcher.matches();
}
/***
* Verifies that the given line from the model file is a valid texture coordinate
* @param line the line being validated
* @return true if the line is a valid texture coordinate, false otherwise
*/
private static boolean isValidTextureCoordinateLine(String line)
{
if (textureCoordinateMatcher != null)
{
textureCoordinateMatcher.reset();
}
textureCoordinateMatcher = textureCoordinatePattern.matcher(line);
return textureCoordinateMatcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face that is described by vertices, texture coordinates, and vertex normals
* @param line the line being validated
* @return true if the line is a valid face that matches the format "f v1/vt1/vn1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
*/
private static boolean isValidFace_V_VT_VN_Line(String line)
{
if (face_V_VT_VN_Matcher != null)
{
face_V_VT_VN_Matcher.reset();
}
face_V_VT_VN_Matcher = face_V_VT_VN_Pattern.matcher(line);
return face_V_VT_VN_Matcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face that is described by vertices and texture coordinates
* @param line the line being validated
* @return true if the line is a valid face that matches the format "f v1/vt1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
*/
private static boolean isValidFace_V_VT_Line(String line)
{
if (face_V_VT_Matcher != null)
{
face_V_VT_Matcher.reset();
}
face_V_VT_Matcher = face_V_VT_Pattern.matcher(line);
return face_V_VT_Matcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face that is described by vertices and vertex normals
* @param line the line being validated
* @return true if the line is a valid face that matches the format "f v1//vn1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
*/
private static boolean isValidFace_V_VN_Line(String line)
{
if (face_V_VN_Matcher != null)
{
face_V_VN_Matcher.reset();
}
face_V_VN_Matcher = face_V_VN_Pattern.matcher(line);
return face_V_VN_Matcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face that is described by only vertices
* @param line the line being validated
* @return true if the line is a valid face that matches the format "f v1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
*/
private static boolean isValidFace_V_Line(String line)
{
if (face_V_Matcher != null)
{
face_V_Matcher.reset();
}
face_V_Matcher = face_V_Pattern.matcher(line);
return face_V_Matcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face of any of the possible face formats
* @param line the line being validated
* @return true if the line is a valid face that matches any of the valid face formats, false otherwise
*/
private static boolean isValidFaceLine(String line)
{
return isValidFace_V_VT_VN_Line(line) || isValidFace_V_VT_Line(line) || isValidFace_V_VN_Line(line) || isValidFace_V_Line(line);
}
/***
* Verifies that the given line from the model file is a valid group (or object)
* @param line the line being validated
* @return true if the line is a valid group (or object), false otherwise
*/
private static boolean isValidGroupObjectLine(String line)
{
if (groupObjectMatcher != null)
{
groupObjectMatcher.reset();
}
groupObjectMatcher = groupObjectPattern.matcher(line);
return groupObjectMatcher.matches();
}
}