diff --git a/changelog b/changelog index 8feb884c5..e8354c233 100644 --- a/changelog +++ b/changelog @@ -21,6 +21,7 @@ * Bullet casings now make sounds when falling to the ground * Most ammo types now have QMAW pages, including information on whether or not they are a war crime * Both assembly and chemical factories now have four special ports that only allow items inserted to go into one recipe group +* All models using the HFR wavefront loader can now be hot-swapped via resource reload (F3 + T) # Fixed * Potentially fixed yet another issue regarding crates diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index b39761e3e..3a669b1c9 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -61,6 +61,7 @@ import com.hbm.render.item.ItemRenderMissileGeneric.RenderMissileType; import com.hbm.render.item.block.ItemRenderBlock; import com.hbm.render.item.block.ItemRenderDecoBlock; import com.hbm.render.item.weapon.*; +import com.hbm.render.loader.HFRModelReloader; import com.hbm.render.loader.HmfModelLoader; import com.hbm.render.model.ModelPigeon; import com.hbm.render.tileentity.*; @@ -162,7 +163,9 @@ public class ClientProxy extends ServerProxy { Jars.initJars(); - ((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(new QMAWLoader()); + IReloadableResourceManager resourceMan = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager(); + resourceMan.registerReloadListener(new QMAWLoader()); + resourceMan.registerReloadListener(new HFRModelReloader()); if(GeneralConfig.enableSoundExtension) { SoundSystemConfig.setNumberNormalChannels(GeneralConfig.normalSoundChannels); diff --git a/src/main/java/com/hbm/render/loader/HFRModelReloader.java b/src/main/java/com/hbm/render/loader/HFRModelReloader.java new file mode 100644 index 000000000..2dad6c70e --- /dev/null +++ b/src/main/java/com/hbm/render/loader/HFRModelReloader.java @@ -0,0 +1,34 @@ +package com.hbm.render.loader; + +import java.io.IOException; +import java.util.Map.Entry; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.IResourceManagerReloadListener; + +public class HFRModelReloader implements IResourceManagerReloadListener { + + @Override + public void onResourceManagerReload(IResourceManager resourceManager) { + + for(HFRWavefrontObject obj : HFRWavefrontObject.allModels) { + try { + obj.destroy(); + IResource resource = Minecraft.getMinecraft().getResourceManager().getResource(obj.resource); + obj.loadObjModel(resource.getInputStream()); + // MainRegistry.logger.info("Reloading OBJ " + obj.resource.getResourcePath()); + } catch(IOException e) { } + } + + for(Entry entry : HFRWavefrontObject.allVBOs.entrySet()) { + HFRWavefrontObjectVBO vbo = entry.getKey(); + HFRWavefrontObject obj = entry.getValue(); + + vbo.destroy(); + vbo.load(obj); + // MainRegistry.logger.info("Reloading VBO " + obj.resource.getResourcePath()); + } + } +} diff --git a/src/main/java/com/hbm/render/loader/HFRWavefrontObject.java b/src/main/java/com/hbm/render/loader/HFRWavefrontObject.java index d8863bb2f..2b65efee2 100644 --- a/src/main/java/com/hbm/render/loader/HFRWavefrontObject.java +++ b/src/main/java/com/hbm/render/loader/HFRWavefrontObject.java @@ -5,6 +5,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -22,6 +24,11 @@ import net.minecraftforge.client.model.obj.TextureCoordinate; import net.minecraftforge.client.model.obj.Vertex; public class HFRWavefrontObject implements IModelCustomNamed { + + /** For resource reloading */ + public static LinkedHashSet allModels = new LinkedHashSet(); + public static LinkedHashMap allVBOs = new LinkedHashMap(); + 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} *$)"); @@ -40,10 +47,12 @@ public class HFRWavefrontObject implements IModelCustomNamed { public ArrayList textureCoordinates = new ArrayList(); public ArrayList groupObjects = new ArrayList(); private S_GroupObject currentGroupObject; + public ResourceLocation resource; private String fileName; private boolean smoothing = true; public HFRWavefrontObject(ResourceLocation resource) throws ModelFormatException { + this.resource = resource; this.fileName = resource.toString(); try { @@ -52,6 +61,8 @@ public class HFRWavefrontObject implements IModelCustomNamed { } catch(IOException e) { throw new ModelFormatException("IO Exception reading model format", e); } + + this.allModels.add(this); } public HFRWavefrontObject(ResourceLocation resource, boolean smoothing) throws ModelFormatException { @@ -59,12 +70,15 @@ public class HFRWavefrontObject implements IModelCustomNamed { this.smoothing = smoothing; } - public HFRWavefrontObject(String filename, InputStream inputStream) throws ModelFormatException { - this.fileName = filename; - loadObjModel(inputStream); + public void destroy() { + vertices.clear(); + vertexNormals.clear(); + textureCoordinates.clear(); + groupObjects.clear(); + currentGroupObject = null; } - private void loadObjModel(InputStream inputStream) throws ModelFormatException { + public void loadObjModel(InputStream inputStream) throws ModelFormatException { BufferedReader reader = null; String currentLine = null; @@ -492,7 +506,9 @@ public class HFRWavefrontObject implements IModelCustomNamed { return names; } - public WavefrontObjVBO asVBO() { - return new WavefrontObjVBO(this); + public HFRWavefrontObjectVBO asVBO() { + HFRWavefrontObjectVBO vbo = new HFRWavefrontObjectVBO(this); + this.allVBOs.put(vbo, this); + return vbo; } } diff --git a/src/main/java/com/hbm/render/loader/WavefrontObjVBO.java b/src/main/java/com/hbm/render/loader/HFRWavefrontObjectVBO.java similarity index 84% rename from src/main/java/com/hbm/render/loader/WavefrontObjVBO.java rename to src/main/java/com/hbm/render/loader/HFRWavefrontObjectVBO.java index fe7eb985f..fa1ddd6a0 100644 --- a/src/main/java/com/hbm/render/loader/WavefrontObjVBO.java +++ b/src/main/java/com/hbm/render/loader/HFRWavefrontObjectVBO.java @@ -10,7 +10,7 @@ import org.lwjgl.opengl.*; import net.minecraftforge.client.model.obj.TextureCoordinate; import net.minecraftforge.client.model.obj.Vertex; -public class WavefrontObjVBO implements IModelCustomNamed { +public class HFRWavefrontObjectVBO implements IModelCustomNamed { class VBOBufferData { @@ -27,7 +27,11 @@ public class WavefrontObjVBO implements IModelCustomNamed { static int VERTEX_SIZE = 3; static int UV_SIZE = 3; - public WavefrontObjVBO(HFRWavefrontObject obj) { + public HFRWavefrontObjectVBO(HFRWavefrontObject obj) { + load(obj); + } + + public void load(HFRWavefrontObject obj) { for(S_GroupObject g : obj.groupObjects) { VBOBufferData data = new VBOBufferData(); data.name = g.name; @@ -74,6 +78,19 @@ public class WavefrontObjVBO implements IModelCustomNamed { groups.add(data); } } + + // truth be told, i have no fucking idea what i'm doing + // i know the VBO sends data to the GPU to be saved there directly which is where the optimization comes from in the first place + // so logically, if we want to get rid of this, we need to blow the data up + // documentation on GL15 functions seems nonexistant so fuck it we ball i guess + public void destroy() { + for(VBOBufferData data : groups) { + GL15.glDeleteBuffers(data.vertexHandle); + GL15.glDeleteBuffers(data.uvHandle); + GL15.glDeleteBuffers(data.normalHandle); + } + groups.clear(); + } @Override public String getType() {