From f058b37b13f3a8f47d188252ceda4f3a429afbfd Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Fri, 8 Jul 2022 12:37:54 -0700 Subject: [PATCH 01/11] Update changelog.txt --- changelog.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/changelog.txt b/changelog.txt index 89197f6e0..1682e9cdc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,8 @@ +0.6.3: +Technical/API + - Light updates are now processed in parallel. + - The light updater is now more selective of the levels it processes, fixing a memory leak. + 0.6.2: Update to 1.18.2 From 055802160fb44e9dc5808b23fd08f9dd85891824 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sat, 9 Jul 2022 13:23:40 -0400 Subject: [PATCH 02/11] Update light updates - ... to address the nullpointer with create pulleys - LightListeners track their own levels - Remove BasicProvider and LightProvider - Rename MovingListener to better match functionality - Remove ListenerStatus in favor of a boolean - Instances keep track of their removal status and properly report it via LightListener#isListenerInvalid - Bump version - 0.6.4 --- gradle.properties | 2 +- .../backend/instancing/AbstractInstance.java | 21 +++++-- .../backend/instancing/InstanceManager.java | 4 +- .../instancing/entity/EntityInstance.java | 7 +-- .../flywheel/light/BasicProvider.java | 23 ------- .../flywheel/light/GPULightVolume.java | 35 ++++------- .../flywheel/light/LightListener.java | 21 +++++-- .../flywheel/light/LightProvider.java | 12 ---- .../jozufozu/flywheel/light/LightUpdater.java | 34 +++++----- .../jozufozu/flywheel/light/LightVolume.java | 63 ++++++++++--------- .../flywheel/light/ListenerStatus.java | 16 ----- .../flywheel/light/MovingListener.java | 5 -- .../flywheel/light/TickingLightListener.java | 9 +++ .../jozufozu/flywheel/light/package-info.java | 7 +++ 14 files changed, 112 insertions(+), 147 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/light/BasicProvider.java delete mode 100644 src/main/java/com/jozufozu/flywheel/light/LightProvider.java delete mode 100644 src/main/java/com/jozufozu/flywheel/light/ListenerStatus.java delete mode 100644 src/main/java/com/jozufozu/flywheel/light/MovingListener.java create mode 100644 src/main/java/com/jozufozu/flywheel/light/TickingLightListener.java create mode 100644 src/main/java/com/jozufozu/flywheel/light/package-info.java diff --git a/gradle.properties b/gradle.properties index 45c6f4660..5ab61dd67 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G org.gradle.daemon = false # mod version info -mod_version = 0.6.3 +mod_version = 0.6.4 mc_update_version = 1.18 minecraft_version = 1.18.2 forge_version = 40.0.15 diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java index 6a3e67ba8..d039f402e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java @@ -10,8 +10,6 @@ import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; import com.jozufozu.flywheel.core.materials.FlatLit; import com.jozufozu.flywheel.light.LightListener; -import com.jozufozu.flywheel.light.LightProvider; -import com.jozufozu.flywheel.light.ListenerStatus; import com.jozufozu.flywheel.util.box.ImmutableBox; import net.minecraft.core.BlockPos; @@ -26,6 +24,7 @@ public abstract class AbstractInstance implements Instance, LightListener { protected final MaterialManager materialManager; public final Level world; + protected boolean removed = false; public AbstractInstance(MaterialManager materialManager, Level world) { this.materialManager = materialManager; @@ -39,10 +38,19 @@ public abstract class AbstractInstance implements Instance, LightListener { } + final void removeAndMark() { + if (removed) { + return; + } + + remove(); + removed = true; + } + /** * Free any acquired resources. */ - public abstract void remove(); + protected abstract void remove(); /** * Update instance data here. Good for when data doesn't change very often and when animations are GPU based. @@ -78,12 +86,12 @@ public abstract class AbstractInstance implements Instance, LightListener { } @Override - public ListenerStatus status() { - return ListenerStatus.OKAY; + public boolean isListenerInvalid() { + return removed; } @Override - public void onLightUpdate(LightProvider world, LightLayer type, ImmutableBox changed) { + public void onLightUpdate(LightLayer type, ImmutableBox changed) { updateLight(); } @@ -103,4 +111,5 @@ public abstract class AbstractInstance implements Instance, LightListener { models.forEach(model -> model.setBlockLight(block) .setSkyLight(sky)); } + } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java index 7f741cd8c..1f8310d1e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java @@ -260,7 +260,7 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift } public void invalidate() { - instances.values().forEach(AbstractInstance::remove); + instances.values().forEach(AbstractInstance::removeAndMark); instances.clear(); dynamicInstances.clear(); tickableInstances.clear(); @@ -314,7 +314,7 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift } protected void removeInternal(T obj, AbstractInstance instance) { - instance.remove(); + instance.removeAndMark(); instances.remove(obj); dynamicInstances.remove(obj); tickableInstances.remove(obj); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java index 02e03435c..d7025fe57 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java @@ -6,8 +6,7 @@ import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.instancing.AbstractInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; import com.jozufozu.flywheel.light.LightListener; -import com.jozufozu.flywheel.light.LightProvider; -import com.jozufozu.flywheel.light.MovingListener; +import com.jozufozu.flywheel.light.TickingLightListener; import com.jozufozu.flywheel.util.box.GridAlignedBB; import com.mojang.math.Vector3f; @@ -34,7 +33,7 @@ import net.minecraft.world.phys.Vec3; * * @param The type of {@link Entity} your class is an instance of. */ -public abstract class EntityInstance extends AbstractInstance implements LightListener, MovingListener { +public abstract class EntityInstance extends AbstractInstance implements LightListener, TickingLightListener { protected final E entity; protected final GridAlignedBB bounds; @@ -51,7 +50,7 @@ public abstract class EntityInstance extends AbstractInstance } @Override - public boolean update(LightProvider provider) { + public boolean tickLightListener() { AABB boundsNow = entity.getBoundingBox(); if (bounds.sameAs(boundsNow)) return false; diff --git a/src/main/java/com/jozufozu/flywheel/light/BasicProvider.java b/src/main/java/com/jozufozu/flywheel/light/BasicProvider.java deleted file mode 100644 index fb5d3b189..000000000 --- a/src/main/java/com/jozufozu/flywheel/light/BasicProvider.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.jozufozu.flywheel.light; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.LightLayer; - -/** - * Wraps a world and minimally lowers the interface. - */ -public class BasicProvider implements LightProvider { - - private final BlockAndTintGetter reader; - private final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); - - public BasicProvider(BlockAndTintGetter reader) { - this.reader = reader; - } - - @Override - public int getLight(LightLayer type, int x, int y, int z) { - return reader.getBrightness(type, pos.set(x, y, z)); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java b/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java index fee086071..6064f5e8d 100644 --- a/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java +++ b/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java @@ -26,6 +26,7 @@ import com.jozufozu.flywheel.backend.gl.GlTextureUnit; import com.jozufozu.flywheel.util.box.GridAlignedBB; import com.jozufozu.flywheel.util.box.ImmutableBox; +import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.LightLayer; public class GPULightVolume extends LightVolume { @@ -36,8 +37,8 @@ public class GPULightVolume extends LightVolume { private final GlTextureUnit textureUnit = GlTextureUnit.T4; protected boolean bufferDirty; - public GPULightVolume(ImmutableBox sampleVolume) { - super(sampleVolume); + public GPULightVolume(BlockAndTintGetter level, ImmutableBox sampleVolume) { + super(level, sampleVolume); this.sampleVolume.assign(sampleVolume); glTexture = new GlTexture(GL_TEXTURE_3D); @@ -110,38 +111,24 @@ public class GPULightVolume extends LightVolume { glTexture.delete(); } - public void move(LightProvider world, ImmutableBox newSampleVolume) { + public void move(BlockAndTintGetter level, ImmutableBox newSampleVolume) { if (lightData == null) return; if (box.contains(newSampleVolume)) { sampleVolume.assign(newSampleVolume); - initialize(world); + initialize(); } else { - super.move(world, newSampleVolume); + super.move(level, newSampleVolume); } } - public void onLightUpdate(LightProvider world, LightLayer type, ImmutableBox changedVolume) { - super.onLightUpdate(world, type, changedVolume); - bufferDirty = true; - } - - public void onLightPacket(LightProvider world, int chunkX, int chunkZ) { - super.onLightPacket(world, chunkX, chunkZ); - bufferDirty = true; - } - - /** - * Completely (re)populate this volume with block and sky lighting data. - * This is expensive and should be avoided. - */ - public void initialize(LightProvider world) { - super.initialize(world); - bufferDirty = true; - } - @Override public ImmutableBox getVolume() { return sampleVolume; } + + @Override + protected void markDirty() { + this.bufferDirty = true; + } } diff --git a/src/main/java/com/jozufozu/flywheel/light/LightListener.java b/src/main/java/com/jozufozu/flywheel/light/LightListener.java index 396ae6bbd..55a1e8020 100644 --- a/src/main/java/com/jozufozu/flywheel/light/LightListener.java +++ b/src/main/java/com/jozufozu/flywheel/light/LightListener.java @@ -5,26 +5,37 @@ import com.jozufozu.flywheel.util.box.ImmutableBox; import net.minecraft.world.level.LightLayer; +/** + * Implementors of this interface may choose to subscribe to light updates by calling + * {@link LightUpdater#addListener(LightListener)}.

+ * + * It is the responsibility of the implementor to keep a reference to the level an object is contained in. + */ public interface LightListener { ImmutableBox getVolume(); - ListenerStatus status(); + /** + * Check the status of the light listener. + * @return {@code true} if the listener is invalid/removed/deleted, + * and should no longer receive updates. + */ + boolean isListenerInvalid(); /** * Called when a light updates in a chunk the implementor cares about. */ - void onLightUpdate(LightProvider world, LightLayer type, ImmutableBox changed); + void onLightUpdate(LightLayer type, ImmutableBox changed); /** * Called when the server sends light data to the client. * */ - default void onLightPacket(LightProvider world, int chunkX, int chunkZ) { + default void onLightPacket(int chunkX, int chunkZ) { GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ); - onLightUpdate(world, LightLayer.BLOCK, changedVolume); + onLightUpdate(LightLayer.BLOCK, changedVolume); - onLightUpdate(world, LightLayer.SKY, changedVolume); + onLightUpdate(LightLayer.SKY, changedVolume); } } diff --git a/src/main/java/com/jozufozu/flywheel/light/LightProvider.java b/src/main/java/com/jozufozu/flywheel/light/LightProvider.java deleted file mode 100644 index c95a04df7..000000000 --- a/src/main/java/com/jozufozu/flywheel/light/LightProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.jozufozu.flywheel.light; - -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.world.level.LightLayer; - -public interface LightProvider { - int getLight(LightLayer type, int x, int y, int z); - - default int getPackedLight(int x, int y, int z) { - return LightTexture.pack(getLight(LightLayer.BLOCK, x, y, z), getLight(LightLayer.SKY, x, y, z)); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java b/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java index 4958fd682..9cce9fd44 100644 --- a/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java +++ b/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java @@ -39,19 +39,15 @@ public class LightUpdater { } } - private final LightProvider provider; + private final LevelAccessor level; - private final WeakHashSet movingListeners = new WeakHashSet<>(); + private final WeakHashSet tickingLightListeners = new WeakHashSet<>(); private final WeakContainmentMultiMap sections = new WeakContainmentMultiMap<>(); private final WeakContainmentMultiMap chunks = new WeakContainmentMultiMap<>(); - public LightUpdater(LevelAccessor world) { + public LightUpdater(LevelAccessor level) { taskEngine = Backend.getTaskEngine(); - provider = new BasicProvider(world); - } - - public LightProvider getProvider() { - return provider; + this.level = level; } public void tick() { @@ -60,9 +56,9 @@ public class LightUpdater { } private void tickSerial() { - for (MovingListener movingListener : movingListeners) { - if (movingListener.update(provider)) { - addListener(movingListener); + for (TickingLightListener tickingLightListener : tickingLightListeners) { + if (tickingLightListener.tickLightListener()) { + addListener(tickingLightListener); } } } @@ -71,8 +67,8 @@ public class LightUpdater { Queue listeners = new ConcurrentLinkedQueue<>(); taskEngine.group("LightUpdater") - .addTasks(movingListeners.stream(), listener -> { - if (listener.update(provider)) { + .addTasks(tickingLightListeners.stream(), listener -> { + if (listener.tickLightListener()) { listeners.add(listener); } }) @@ -86,8 +82,8 @@ public class LightUpdater { * @param listener The object that wants to receive light update notifications. */ public void addListener(LightListener listener) { - if (listener instanceof MovingListener) - movingListeners.add(((MovingListener) listener)); + if (listener instanceof TickingLightListener) + tickingLightListeners.add(((TickingLightListener) listener)); ImmutableBox box = listener.getVolume(); @@ -130,12 +126,12 @@ public class LightUpdater { if (set == null || set.isEmpty()) return; - set.removeIf(l -> l.status().shouldRemove()); + set.removeIf(LightListener::isListenerInvalid); ImmutableBox chunkBox = GridAlignedBB.from(SectionPos.of(sectionPos)); for (LightListener listener : set) { - listener.onLightUpdate(provider, type, chunkBox); + listener.onLightUpdate(type, chunkBox); } } @@ -151,10 +147,10 @@ public class LightUpdater { if (set == null || set.isEmpty()) return; - set.removeIf(l -> l.status().shouldRemove()); + set.removeIf(LightListener::isListenerInvalid); for (LightListener listener : set) { - listener.onLightPacket(provider, chunkX, chunkZ); + listener.onLightPacket(chunkX, chunkZ); } } diff --git a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java index b5a830f86..e2fc15d13 100644 --- a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java +++ b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java @@ -8,14 +8,17 @@ import com.jozufozu.flywheel.util.box.GridAlignedBB; import com.jozufozu.flywheel.util.box.ImmutableBox; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.LightLayer; public class LightVolume implements ImmutableBox, LightListener { + protected final BlockAndTintGetter level; protected final GridAlignedBB box = new GridAlignedBB(); protected ByteBuffer lightData; - public LightVolume(ImmutableBox sampleVolume) { + public LightVolume(BlockAndTintGetter level, ImmutableBox sampleVolume) { + this.level = level; this.setBox(sampleVolume); this.lightData = MemoryUtil.memAlloc(this.box.volume() * 2); @@ -57,7 +60,7 @@ public class LightVolume implements ImmutableBox, LightListener { return box.getMaxZ(); } - public void move(LightProvider world, ImmutableBox newSampleVolume) { + public void move(BlockAndTintGetter level, ImmutableBox newSampleVolume) { if (lightData == null) return; setBox(newSampleVolume); @@ -65,51 +68,43 @@ public class LightVolume implements ImmutableBox, LightListener { if (neededCapacity > lightData.capacity()) { lightData = MemoryUtil.memRealloc(lightData, neededCapacity); } - initialize(world); + initialize(); } @Override - public void onLightUpdate(LightProvider world, LightLayer type, ImmutableBox changedVolume) { + public void onLightUpdate(LightLayer type, ImmutableBox changedVolume) { if (lightData == null) return; GridAlignedBB vol = changedVolume.copy(); if (!vol.intersects(getVolume())) return; vol.intersectAssign(getVolume()); // compute the region contained by us that has dirty lighting data. - if (type == LightLayer.BLOCK) copyBlock(world, vol); - else if (type == LightLayer.SKY) copySky(world, vol); + if (type == LightLayer.BLOCK) copyBlock(vol); + else if (type == LightLayer.SKY) copySky(vol); + markDirty(); } @Override - public void onLightPacket(LightProvider world, int chunkX, int chunkZ) { + public void onLightPacket(int chunkX, int chunkZ) { if (lightData == null) return; GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ); if (!changedVolume.intersects(getVolume())) return; changedVolume.intersectAssign(getVolume()); // compute the region contained by us that has dirty lighting data. - copyLight(world, changedVolume); + copyLight(changedVolume); + markDirty(); } /** * Completely (re)populate this volume with block and sky lighting data. * This is expensive and should be avoided. */ - public void initialize(LightProvider world) { + public void initialize() { if (lightData == null) return; - // the volume is indexed based on the greater bounding box - int shiftX = box.getMinX(); - int shiftY = box.getMinY(); - int shiftZ = box.getMinZ(); - - // ... but we only iterate over the (potentially) smaller sample volume - getVolume().forEachContained((x, y, z) -> { - int blockLight = world.getLight(LightLayer.BLOCK, x, y, z); - int skyLight = world.getLight(LightLayer.SKY, x, y, z); - - writeLight(x - shiftX, y - shiftY, z - shiftZ, blockLight, skyLight); - }); + copyLight(getVolume()); + markDirty(); } /** @@ -117,13 +112,15 @@ public class LightVolume implements ImmutableBox, LightListener { * * @param worldVolume the region in the world to copy data from. */ - public void copyBlock(LightProvider world, ImmutableBox worldVolume) { + public void copyBlock(ImmutableBox worldVolume) { + var pos = new BlockPos.MutableBlockPos(); + int xShift = box.getMinX(); int yShift = box.getMinY(); int zShift = box.getMinZ(); worldVolume.forEachContained((x, y, z) -> { - int light = world.getLight(LightLayer.BLOCK, x, y, z); + int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z)); writeBlock(x - xShift, y - yShift, z - zShift, light); }); @@ -134,13 +131,15 @@ public class LightVolume implements ImmutableBox, LightListener { * * @param worldVolume the region in the world to copy data from. */ - public void copySky(LightProvider world, ImmutableBox worldVolume) { + public void copySky(ImmutableBox worldVolume) { + var pos = new BlockPos.MutableBlockPos(); + int xShift = box.getMinX(); int yShift = box.getMinY(); int zShift = box.getMinZ(); worldVolume.forEachContained((x, y, z) -> { - int light = world.getLight(LightLayer.SKY, x, y, z); + int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z)); writeSky(x - xShift, y - yShift, z - zShift, light); }); @@ -151,7 +150,7 @@ public class LightVolume implements ImmutableBox, LightListener { * * @param worldVolume the region in the world to copy data from. */ - public void copyLight(LightProvider world, ImmutableBox worldVolume) { + public void copyLight(ImmutableBox worldVolume) { BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); int xShift = box.getMinX(); @@ -161,8 +160,8 @@ public class LightVolume implements ImmutableBox, LightListener { worldVolume.forEachContained((x, y, z) -> { pos.set(x, y, z); - int block = world.getLight(LightLayer.BLOCK, x, y, z); - int sky = world.getLight(LightLayer.SKY, x, y, z); + int block = this.level.getBrightness(LightLayer.BLOCK, pos); + int sky = this.level.getBrightness(LightLayer.SKY, pos); writeLight(x - xShift, y - yShift, z - zShift, block, sky); }); @@ -173,6 +172,10 @@ public class LightVolume implements ImmutableBox, LightListener { lightData = null; } + protected void markDirty() { + // noop + } + protected void writeLight(int x, int y, int z, int block, int sky) { byte b = (byte) ((block & 0xF) << 4); byte s = (byte) ((sky & 0xF) << 4); @@ -211,8 +214,8 @@ public class LightVolume implements ImmutableBox, LightListener { } @Override - public ListenerStatus status() { - return ListenerStatus.OKAY; + public boolean isListenerInvalid() { + return lightData == null; } } diff --git a/src/main/java/com/jozufozu/flywheel/light/ListenerStatus.java b/src/main/java/com/jozufozu/flywheel/light/ListenerStatus.java deleted file mode 100644 index e8ca36d30..000000000 --- a/src/main/java/com/jozufozu/flywheel/light/ListenerStatus.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.jozufozu.flywheel.light; - -public enum ListenerStatus { - OKAY, - REMOVE, - UPDATE, - ; - - public boolean isOk() { - return this == OKAY; - } - - public boolean shouldRemove() { - return this == REMOVE; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/light/MovingListener.java b/src/main/java/com/jozufozu/flywheel/light/MovingListener.java deleted file mode 100644 index 388d6fdd7..000000000 --- a/src/main/java/com/jozufozu/flywheel/light/MovingListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.jozufozu.flywheel.light; - -public interface MovingListener extends LightListener { - boolean update(LightProvider provider); -} diff --git a/src/main/java/com/jozufozu/flywheel/light/TickingLightListener.java b/src/main/java/com/jozufozu/flywheel/light/TickingLightListener.java new file mode 100644 index 000000000..cd3d00b7a --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/light/TickingLightListener.java @@ -0,0 +1,9 @@ +package com.jozufozu.flywheel.light; + +public interface TickingLightListener extends LightListener { + /** + * Called every tick for active listeners. + * @return {@code true} if the listener changed. + */ + boolean tickLightListener(); +} diff --git a/src/main/java/com/jozufozu/flywheel/light/package-info.java b/src/main/java/com/jozufozu/flywheel/light/package-info.java new file mode 100644 index 000000000..da21c0a32 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/light/package-info.java @@ -0,0 +1,7 @@ + +@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault +package com.jozufozu.flywheel.light; + +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.MethodsReturnNonnullByDefault; From c3b1a43bebd5d5fdd573cd2596ec9356c8ab9790 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sun, 10 Jul 2022 15:22:02 -0400 Subject: [PATCH 03/11] One more thing... - Missed a level param in LightVolume - Public removeAndMark - Remove batching warning - Bump forge and parchment builds --- gradle.properties | 4 ++-- .../backend/instancing/AbstractInstance.java | 2 +- .../com/jozufozu/flywheel/config/FlwCommands.java | 12 +----------- .../com/jozufozu/flywheel/light/GPULightVolume.java | 5 ++--- .../com/jozufozu/flywheel/light/LightVolume.java | 2 +- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5ab61dd67..42e95d776 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ org.gradle.daemon = false mod_version = 0.6.4 mc_update_version = 1.18 minecraft_version = 1.18.2 -forge_version = 40.0.15 +forge_version = 40.1.60 # build dependency versions forgegradle_version = 5.1.+ @@ -13,7 +13,7 @@ mixingradle_version = 0.7-SNAPSHOT mixin_version = 0.8.5 librarian_version = 1.+ cursegradle_version = 1.4.0 -parchment_version = 2022.03.13 +parchment_version = 2022.07.10 # curseforge info projectId = 486392 diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java index d039f402e..deb007634 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java @@ -38,7 +38,7 @@ public abstract class AbstractInstance implements Instance, LightListener { } - final void removeAndMark() { + public final void removeAndMark() { if (removed) { return; } diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java index 7575111e0..ce0ea95d7 100644 --- a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java +++ b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java @@ -118,17 +118,7 @@ public class FlwCommands { return switch (type) { case OFF -> new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED); case INSTANCING -> new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN); - case BATCHING -> { - MutableComponent msg = new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN); - - if (ModList.get() - .isLoaded("create")) { - // FIXME: batching engine contraption lighting issues - msg.append(new TextComponent("\nWARNING: May cause issues with Create Contraptions").withStyle(ChatFormatting.RED)); - } - - yield msg; - } + case BATCHING -> new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN); }; } diff --git a/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java b/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java index 6064f5e8d..673670973 100644 --- a/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java +++ b/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java @@ -27,7 +27,6 @@ import com.jozufozu.flywheel.util.box.GridAlignedBB; import com.jozufozu.flywheel.util.box.ImmutableBox; import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.LightLayer; public class GPULightVolume extends LightVolume { @@ -111,14 +110,14 @@ public class GPULightVolume extends LightVolume { glTexture.delete(); } - public void move(BlockAndTintGetter level, ImmutableBox newSampleVolume) { + public void move(ImmutableBox newSampleVolume) { if (lightData == null) return; if (box.contains(newSampleVolume)) { sampleVolume.assign(newSampleVolume); initialize(); } else { - super.move(level, newSampleVolume); + super.move(newSampleVolume); } } diff --git a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java index e2fc15d13..31245dea9 100644 --- a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java +++ b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java @@ -60,7 +60,7 @@ public class LightVolume implements ImmutableBox, LightListener { return box.getMaxZ(); } - public void move(BlockAndTintGetter level, ImmutableBox newSampleVolume) { + public void move(ImmutableBox newSampleVolume) { if (lightData == null) return; setBox(newSampleVolume); From 273c99619f292a00584ea5e33c4000d32ef381e8 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sun, 10 Jul 2022 18:08:59 -0400 Subject: [PATCH 04/11] Oculus compatibility - Rename OptifineHandler to ShadersModHandler - Rename functions to match fabric version --- build.gradle | 15 +- .../java/com/jozufozu/flywheel/Flywheel.java | 4 +- .../jozufozu/flywheel/backend/Backend.java | 2 +- .../flywheel/backend/OptifineHandler.java | 117 ------------ .../flywheel/backend/ShadersModHandler.java | 179 ++++++++++++++++++ .../batching/BatchedMaterialGroup.java | 4 +- .../jozufozu/flywheel/mixin/FrustumMixin.java | 4 +- 7 files changed, 200 insertions(+), 125 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java create mode 100644 src/main/java/com/jozufozu/flywheel/backend/ShadersModHandler.java diff --git a/build.gradle b/build.gradle index 928cd432d..341b6b0e2 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,8 @@ minecraft { property 'forge.logging.markers', '' property 'forge.logging.console.level', 'debug' property 'mixin.debug.export', 'true' + property 'mixin.env.remapRefMap', 'true' + property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" arg '-mixin.config=flywheel.mixins.json' @@ -102,12 +104,23 @@ repositories { name 'tterrag maven' url 'https://maven.tterrag.com/' } + maven { + name = "Modrinth" + url = "https://api.modrinth.com/maven" + content { + includeGroup "maven.modrinth" + } + } } dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" - compileOnly fg.deobf("curse.maven:starlight-526854:3599856") + // switch to implementation for debugging + compileOnly fg.deobf("maven.modrinth:starlight-forge:1.0.2+1.18.2") + + compileOnly fg.deobf("maven.modrinth:rubidium:0.5.2a") + compileOnly fg.deobf("curse.maven:oculus-581495:3821406") // https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497 // Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index 3ae7e9691..be8be85d0 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -4,7 +4,7 @@ import org.apache.maven.artifact.versioning.ArtifactVersion; import org.slf4j.Logger; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.OptifineHandler; +import com.jozufozu.flywheel.backend.ShadersModHandler; import com.jozufozu.flywheel.config.BackendTypeArgument; import com.jozufozu.flywheel.config.FlwCommands; import com.jozufozu.flywheel.config.FlwConfig; @@ -65,7 +65,7 @@ public class Flywheel { private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) { CrashReportCallables.registerCrashCallable("Flywheel Backend", Backend::getBackendDescriptor); - OptifineHandler.init(); + ShadersModHandler.init(); Backend.init(); forgeEventBus.addListener(FlwCommands::registerClientCommands); diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index d3be6f353..77528cb30 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -96,7 +96,7 @@ public class Backend { BackendType preferredChoice = FlwConfig.get() .getBackendType(); - boolean usingShaders = OptifineHandler.isUsingShaders(); + boolean usingShaders = ShadersModHandler.isShaderPackInUse(); boolean canUseEngine = switch (preferredChoice) { case OFF -> true; case BATCHING -> !usingShaders; diff --git a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java deleted file mode 100644 index 1e49c7270..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.jozufozu.flywheel.backend; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.function.BooleanSupplier; - -import javax.annotation.Nullable; - -import net.minecraft.client.Camera; -import net.minecraft.client.renderer.culling.Frustum; - -public final class OptifineHandler { - public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine"; - public static final String SHADER_PACKAGE = "net.optifine.shaders"; - - private static boolean isOptifineInstalled; - private static BooleanSupplier shadersEnabledSupplier; - private static BooleanSupplier shadowPassSupplier; - private static FrustumConstructor shadowFrustumConstructor; - - private OptifineHandler() { - } - - private static FrustumConstructor createShadowFrustumConstructor() { - try { - Class ofShaders = Class.forName("net.optifine.shaders.ShadersRender"); - Method method = ofShaders.getDeclaredMethod("makeShadowFrustum", Camera.class, Float.TYPE); - method.setAccessible(true); - return (cam, pt) -> { - try { - return (Frustum) method.invoke(null, cam, pt); - } catch (Exception ignored) { - return null; - } - }; - } catch (Exception ignored) { - return ($, $$) -> null; - } - } - - private static BooleanSupplier createShadowPassSupplier() { - try { - Class ofShaders = Class.forName("net.optifine.shaders.Shaders"); - Field field = ofShaders.getDeclaredField("isShadowPass"); - field.setAccessible(true); - return () -> { - try { - return field.getBoolean(null); - } catch (IllegalAccessException ignored) { - return false; - } - }; - } catch (Exception ignored) { - return () -> false; - } - } - - private static BooleanSupplier createShadersEnabledSupplier() { - try { - Class ofShaders = Class.forName("net.optifine.shaders.Shaders"); - Field field = ofShaders.getDeclaredField("shaderPackLoaded"); - field.setAccessible(true); - return () -> { - try { - return field.getBoolean(null); - } catch (IllegalAccessException ignored) { - return false; - } - }; - } catch (Exception ignored) { - return () -> false; - } - } - - public static void init() { - Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE); - isOptifineInstalled = optifinePackage != null; - - if (isOptifineInstalled) { - Backend.LOGGER.info("Optifine detected."); - } else { - Backend.LOGGER.info("Optifine not detected."); - } - - shadersEnabledSupplier = createShadersEnabledSupplier(); - shadowPassSupplier = createShadowPassSupplier(); - shadowFrustumConstructor = createShadowFrustumConstructor(); - } - - public static boolean isOptifineInstalled() { - return isOptifineInstalled; - } - - public static boolean isUsingShaders() { - return shadersEnabledSupplier.getAsBoolean(); - } - - public static boolean isShadowPass() { - return shadowPassSupplier.getAsBoolean(); - } - - @Nullable - public static Frustum createShadowFrustum(Camera camera, float partialTicks) { - var frustum = shadowFrustumConstructor.create(camera, partialTicks); - if (frustum != null) { - var position = camera.getPosition(); - frustum.prepare(position.x, position.y, position.z); - } - return frustum; - } - - @FunctionalInterface - public interface FrustumConstructor { - @Nullable - Frustum create(Camera camera, float partialTicks); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/ShadersModHandler.java b/src/main/java/com/jozufozu/flywheel/backend/ShadersModHandler.java new file mode 100644 index 000000000..d96eef8a0 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/ShadersModHandler.java @@ -0,0 +1,179 @@ +package com.jozufozu.flywheel.backend; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.function.BooleanSupplier; + +import javax.annotation.Nullable; + +import net.irisshaders.iris.api.v0.IrisApi; +import net.minecraft.client.Camera; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraftforge.fml.ModList; + +public final class ShadersModHandler { + public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine"; + public static final String SHADER_PACKAGE = "net.optifine.shaders"; + + private static final boolean isOculusLoaded; + private static final boolean isOptifineInstalled; + private static final InternalHandler internalHandler; + + static { + Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE); + isOptifineInstalled = optifinePackage != null; + isOculusLoaded = ModList.get() + .isLoaded("oculus"); + + // optfine and oculus are assumed to be mutually exclusive + + if (isOptifineInstalled) { + Backend.LOGGER.info("Optifine detected."); + internalHandler = new Optifine(); + } else if (isOculusLoaded) { + Backend.LOGGER.info("Oculus detected."); + internalHandler = new Oculus(); + } else { + Backend.LOGGER.info("No shaders mod detected."); + internalHandler = new InternalHandler() {}; + } + } + + private ShadersModHandler() { + } + + public static void init() { + // noop, load statics + } + + public static boolean isOptifineInstalled() { + return isOptifineInstalled; + } + + public static boolean isOculusLoaded() { + return isOculusLoaded; + } + + public static boolean isShaderPackInUse() { + return internalHandler.isShaderPackInUse(); + } + + public static boolean isRenderingShadowPass() { + return internalHandler.isRenderingShadowPass(); + } + + private interface InternalHandler { + default boolean isShaderPackInUse() { + return false; + }; + + default boolean isRenderingShadowPass() { + return false; + }; + } + + // simple, lovely api calls + private static class Oculus implements InternalHandler { + @Override + public boolean isShaderPackInUse() { + return IrisApi.getInstance() + .isShaderPackInUse(); + } + + @Override + public boolean isRenderingShadowPass() { + return IrisApi.getInstance() + .isRenderingShadowPass(); + } + } + + // evil reflection + private static class Optifine implements InternalHandler { + private final BooleanSupplier shadersEnabledSupplier; + private final BooleanSupplier shadowPassSupplier; + private final FrustumConstructor shadowFrustumConstructor; + + Optifine() { + shadersEnabledSupplier = createShadersEnabledSupplier(); + shadowPassSupplier = createShadowPassSupplier(); + shadowFrustumConstructor = createShadowFrustumConstructor(); + } + + @Override + public boolean isShaderPackInUse() { + return shadersEnabledSupplier.getAsBoolean(); + } + + @Override + public boolean isRenderingShadowPass() { + return shadowPassSupplier.getAsBoolean(); + } + + @Nullable + public Frustum createShadowFrustum(Camera camera, float partialTicks) { + var frustum = shadowFrustumConstructor.create(camera, partialTicks); + if (frustum != null) { + var position = camera.getPosition(); + frustum.prepare(position.x, position.y, position.z); + } + return frustum; + } + + private static FrustumConstructor createShadowFrustumConstructor() { + try { + Class ofShaders = Class.forName("net.optifine.shaders.ShadersRender"); + Method method = ofShaders.getDeclaredMethod("makeShadowFrustum", Camera.class, Float.TYPE); + method.setAccessible(true); + return (cam, pt) -> { + try { + return (Frustum) method.invoke(null, cam, pt); + } catch (Exception ignored) { + return null; + } + }; + } catch (Exception ignored) { + return ($, $$) -> null; + } + } + + private static BooleanSupplier createShadowPassSupplier() { + try { + Class ofShaders = Class.forName("net.optifine.shaders.Shaders"); + Field field = ofShaders.getDeclaredField("isShadowPass"); + field.setAccessible(true); + return () -> { + try { + return field.getBoolean(null); + } catch (IllegalAccessException ignored) { + return false; + } + }; + } catch (Exception ignored) { + return () -> false; + } + } + + private static BooleanSupplier createShadersEnabledSupplier() { + try { + Class ofShaders = Class.forName("net.optifine.shaders.Shaders"); + Field field = ofShaders.getDeclaredField("shaderPackLoaded"); + field.setAccessible(true); + return () -> { + try { + return field.getBoolean(null); + } catch (IllegalAccessException ignored) { + return false; + } + }; + } catch (Exception ignored) { + return () -> false; + } + } + + @FunctionalInterface + public interface FrustumConstructor { + @Nullable + Frustum create(Camera camera, float partialTicks); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index 14b2cd212..37787e7c6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -7,7 +7,7 @@ import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.MaterialGroup; import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.api.struct.StructType; -import com.jozufozu.flywheel.backend.OptifineHandler; +import com.jozufozu.flywheel.backend.ShadersModHandler; import com.jozufozu.flywheel.backend.instancing.BatchDrawingTracker; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; @@ -56,7 +56,7 @@ public class BatchedMaterialGroup implements MaterialGroup { for (BatchedMaterial material : materials.values()) { for (CPUInstancer instancer : material.models.values()) { - instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && !OptifineHandler.isUsingShaders(); + instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && !ShadersModHandler.isShaderPackInUse(); instancer.submitTasks(stack, pool, consumer); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java index c0edf6bf0..789e2773b 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java @@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.jozufozu.flywheel.backend.OptifineHandler; +import com.jozufozu.flywheel.backend.ShadersModHandler; import com.jozufozu.flywheel.core.LastActiveCamera; import com.jozufozu.flywheel.event.BeginFrameEvent; @@ -18,7 +18,7 @@ public class FrustumMixin { @Inject(method = "prepare", at = @At("TAIL")) private void onPrepare(double x, double y, double z, CallbackInfo ci) { - if (OptifineHandler.isShadowPass()) { + if (ShadersModHandler.isRenderingShadowPass()) { MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(Minecraft.getInstance().level, LastActiveCamera.getActiveCamera(), (Frustum) (Object) this)); } } From faa5652c4cba174d2797f1fdf39812b72dbc623e Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sun, 10 Jul 2022 19:04:30 -0400 Subject: [PATCH 05/11] World building exercise - Yoink the WorldModelBuilder and associated changes from 1.18/next --- .../core/model/BakedModelBuilder.java | 48 ++++++++ .../flywheel/core/model/Bufferable.java | 19 ++++ .../flywheel/core/model/ModelUtil.java | 106 +++++++----------- .../flywheel/core/model/WorldModel.java | 14 +-- .../core/model/WorldModelBuilder.java | 86 ++++++++++++++ .../core/vertex/BlockVertexListUnsafe.java | 14 ++- .../vertex/PosTexNormalVertexListUnsafe.java | 14 ++- 7 files changed, 216 insertions(+), 85 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/core/model/BakedModelBuilder.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/model/Bufferable.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java diff --git a/src/main/java/com/jozufozu/flywheel/core/model/BakedModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/BakedModelBuilder.java new file mode 100644 index 000000000..70631ebea --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/model/BakedModelBuilder.java @@ -0,0 +1,48 @@ + +package com.jozufozu.flywheel.core.model; + +import java.util.Random; + +import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import com.jozufozu.flywheel.core.virtual.VirtualEmptyModelData; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; + +import net.minecraft.client.renderer.block.ModelBlockRenderer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public final class BakedModelBuilder implements Bufferable { + private final BakedModel model; + private BlockAndTintGetter renderWorld = VirtualEmptyBlockGetter.INSTANCE; + private BlockState referenceState = Blocks.AIR.defaultBlockState(); + private PoseStack poseStack = new PoseStack(); + + public BakedModelBuilder(BakedModel model) { + this.model = model; + } + + public BakedModelBuilder withRenderWorld(BlockAndTintGetter renderWorld) { + this.renderWorld = renderWorld; + return this; + } + + public BakedModelBuilder withReferenceState(BlockState referenceState) { + this.referenceState = referenceState; + return this; + } + + public BakedModelBuilder withPoseStack(PoseStack poseStack) { + this.poseStack = poseStack; + return this; + } + + @Override + public void bufferInto(ModelBlockRenderer blockRenderer, VertexConsumer consumer, Random random) { + blockRenderer.tesselateBlock(renderWorld, model, referenceState, BlockPos.ZERO, poseStack, consumer, false, random, 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Bufferable.java b/src/main/java/com/jozufozu/flywheel/core/model/Bufferable.java new file mode 100644 index 000000000..ee78333ad --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/model/Bufferable.java @@ -0,0 +1,19 @@ + +package com.jozufozu.flywheel.core.model; + +import java.util.Random; + +import com.mojang.blaze3d.vertex.VertexConsumer; + +import net.minecraft.client.renderer.block.ModelBlockRenderer; + +/** + * An interface for objects that can "rendered" into a BufferBuilder. + */ +public interface Bufferable { + void bufferInto(ModelBlockRenderer renderer, VertexConsumer consumer, Random random); + + default ShadeSeparatedBufferBuilder build() { + return ModelUtil.getBufferBuilder(this); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java index 0815adf28..1cd4f903c 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java @@ -6,8 +6,6 @@ import java.util.Random; import java.util.function.Supplier; import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; -import com.jozufozu.flywheel.core.virtual.VirtualEmptyModelData; import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; @@ -15,20 +13,14 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.BlockRenderDispatcher; import net.minecraft.client.renderer.block.ModelBlockRenderer; -import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import net.minecraftforge.client.ForgeHooksClient; -import net.minecraftforge.client.model.data.EmptyModelData; import net.minecraftforge.fml.util.ObfuscationReflectionHelper; public class ModelUtil { @@ -56,75 +48,43 @@ public class ModelUtil { return dispatcher; } - public static ShadeSeparatedBufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack poseStack) { - return getBufferBuilder(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, poseStack); - } - - public static ShadeSeparatedBufferBuilder getBufferBuilder(BlockAndTintGetter renderWorld, BakedModel model, BlockState referenceState, PoseStack poseStack) { + public static ShadeSeparatedBufferBuilder getBufferBuilder(Bufferable bufferable) { ModelBlockRenderer blockRenderer = VANILLA_RENDERER.getModelRenderer(); ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); - ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper; - ShadeSeparatedBufferBuilder builder = new ShadeSeparatedBufferBuilder(512); - BufferBuilder unshadedBuilder = objects.unshadedBuilder; + objects.begin(); - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - shadeSeparatingWrapper.prepare(builder, unshadedBuilder); - blockRenderer.tesselateBlock(renderWorld, model, referenceState, BlockPos.ZERO, poseStack, shadeSeparatingWrapper, - false, objects.random, 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE); - shadeSeparatingWrapper.clear(); - unshadedBuilder.end(); - builder.appendUnshadedVertices(unshadedBuilder); - builder.end(); + bufferable.bufferInto(blockRenderer, objects.shadeSeparatingWrapper, objects.random); - return builder; + objects.end(); + + return objects.separatedBufferBuilder; + } + + public static ShadeSeparatedBufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack poseStack) { + return new BakedModelBuilder(model).withReferenceState(referenceState) + .withPoseStack(poseStack) + .build(); + } + + public static ShadeSeparatedBufferBuilder getBufferBuilder(BlockAndTintGetter renderWorld, BakedModel model, BlockState referenceState, PoseStack poseStack) { + return new BakedModelBuilder(model).withReferenceState(referenceState) + .withPoseStack(poseStack) + .withRenderWorld(renderWorld) + .build(); } public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks) { - return getBufferBuilderFromTemplate(renderWorld, layer, blocks, new PoseStack()); + return new WorldModelBuilder(layer).withRenderWorld(renderWorld) + .withBlocks(blocks) + .build(); } public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks, PoseStack poseStack) { - ModelBlockRenderer modelRenderer = VANILLA_RENDERER.getModelRenderer(); - ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); - - Random random = objects.random; - ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper; - ShadeSeparatedBufferBuilder builder = new ShadeSeparatedBufferBuilder(512); - BufferBuilder unshadedBuilder = objects.unshadedBuilder; - - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - shadeSeparatingWrapper.prepare(builder, unshadedBuilder); - - ForgeHooksClient.setRenderType(layer); - ModelBlockRenderer.enableCaching(); - for (StructureTemplate.StructureBlockInfo info : blocks) { - BlockState state = info.state; - - if (state.getRenderShape() != RenderShape.MODEL) - continue; - if (!ItemBlockRenderTypes.canRenderInLayer(state, layer)) - continue; - - BlockPos pos = info.pos; - - poseStack.pushPose(); - poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); - modelRenderer.tesselateBlock(renderWorld, VANILLA_RENDERER.getBlockModel(state), state, pos, poseStack, shadeSeparatingWrapper, - true, random, 42, OverlayTexture.NO_OVERLAY, EmptyModelData.INSTANCE); - poseStack.popPose(); - } - ModelBlockRenderer.clearCache(); - ForgeHooksClient.setRenderType(null); - - shadeSeparatingWrapper.clear(); - unshadedBuilder.end(); - builder.appendUnshadedVertices(unshadedBuilder); - builder.end(); - - return builder; + return new WorldModelBuilder(layer).withRenderWorld(renderWorld) + .withBlocks(blocks) + .withPoseStack(poseStack) + .build(); } public static Supplier rotateToFace(Direction facing) { @@ -141,6 +101,20 @@ public class ModelUtil { private static class ThreadLocalObjects { public final Random random = new Random(); public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer(); + public final ShadeSeparatedBufferBuilder separatedBufferBuilder = new ShadeSeparatedBufferBuilder(512); public final BufferBuilder unshadedBuilder = new BufferBuilder(512); + + private void begin() { + this.separatedBufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); + this.unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); + this.shadeSeparatingWrapper.prepare(this.separatedBufferBuilder, this.unshadedBuilder); + } + + private void end() { + this.shadeSeparatingWrapper.clear(); + this.unshadedBuilder.end(); + this.separatedBufferBuilder.appendUnshadedVertices(this.unshadedBuilder); + this.separatedBufferBuilder.end(); + } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java index c350361c9..c144f43c6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java @@ -1,25 +1,17 @@ package com.jozufozu.flywheel.core.model; -import java.util.Collection; - import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.Formats; - -import net.minecraft.client.renderer.RenderType; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import com.mojang.blaze3d.vertex.BufferBuilder; public class WorldModel implements Model { private final VertexList reader; private final String name; - /** - * It is expected that {@code renderWorld.getShade(...)} returns a constant. - */ - public WorldModel(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks, String name) { - reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks)); + public WorldModel(BufferBuilder bufferBuilder, String name) { + this.reader = Formats.BLOCK.createReader(bufferBuilder); this.name = name; } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java new file mode 100644 index 000000000..38bda7d1c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java @@ -0,0 +1,86 @@ +package com.jozufozu.flywheel.core.model; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Random; + +import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; + +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.ModelBlockRenderer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.data.EmptyModelData; +import net.minecraftforge.client.model.data.IModelData; + +public final class WorldModelBuilder implements Bufferable { + private final RenderType layer; + + private PoseStack poseStack = new PoseStack(); + private Map modelData = Collections.emptyMap(); + private BlockAndTintGetter renderWorld = VirtualEmptyBlockGetter.INSTANCE; + private Collection blocks = Collections.emptyList(); + + public WorldModelBuilder(RenderType layer) { + this.layer = layer; + } + + @Override + public void bufferInto(ModelBlockRenderer modelRenderer, VertexConsumer consumer, Random random) { + ForgeHooksClient.setRenderType(this.layer); + ModelBlockRenderer.enableCaching(); + for (StructureTemplate.StructureBlockInfo info : this.blocks) { + BlockState state = info.state; + + if (state.getRenderShape() != RenderShape.MODEL) continue; + if (!ItemBlockRenderTypes.canRenderInLayer(state, this.layer)) continue; + + BlockPos pos = info.pos; + + IModelData data = this.modelData.getOrDefault(pos, EmptyModelData.INSTANCE); + + poseStack.pushPose(); + poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); + modelRenderer.tesselateBlock(this.renderWorld, ModelUtil.VANILLA_RENDERER.getBlockModel(state), state, pos, poseStack, consumer, true, random, 42, OverlayTexture.NO_OVERLAY, data); + poseStack.popPose(); + } + ModelBlockRenderer.clearCache(); + ForgeHooksClient.setRenderType(null); + } + + /** + * It is expected that {@code renderWorld.getShade(...)} returns a constant. + */ + public WorldModelBuilder withRenderWorld(BlockAndTintGetter renderWorld) { + this.renderWorld = renderWorld; + return this; + } + + public WorldModelBuilder withBlocks(Collection blocks) { + this.blocks = blocks; + return this; + } + + public WorldModelBuilder withModelData(Map modelData) { + this.modelData = modelData; + return this; + } + + public WorldModelBuilder withPoseStack(PoseStack poseStack) { + this.poseStack = poseStack; + return this; + } + + public WorldModel intoMesh(String name) { + return new WorldModel(ModelUtil.getBufferBuilder(this), name); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java index 0993f29e5..839687a7e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.core.vertex; +import java.nio.Buffer; import java.nio.ByteBuffer; import org.lwjgl.system.MemoryUtil; @@ -7,16 +8,21 @@ import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.vertex.ShadedVertexList; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.util.RenderMath; +import com.mojang.blaze3d.platform.MemoryTracker; public class BlockVertexListUnsafe implements VertexList { - private final ByteBuffer buffer; + private final ByteBuffer contents; private final int vertexCount; private final long base; - public BlockVertexListUnsafe(ByteBuffer buffer, int vertexCount) { - this.buffer = buffer; - this.base = MemoryUtil.memAddress(buffer); + public BlockVertexListUnsafe(ByteBuffer copyFrom, int vertexCount) { + this.contents = MemoryTracker.create(copyFrom.capacity()); + this.contents.order(copyFrom.order()); + this.contents.put(copyFrom); + ((Buffer) this.contents).flip(); + + this.base = MemoryUtil.memAddress(this.contents); this.vertexCount = vertexCount; } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java index 70d4a72ee..e94861b47 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java @@ -1,22 +1,28 @@ package com.jozufozu.flywheel.core.vertex; +import java.nio.Buffer; import java.nio.ByteBuffer; import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.util.RenderMath; +import com.mojang.blaze3d.platform.MemoryTracker; public class PosTexNormalVertexListUnsafe implements VertexList { - private final ByteBuffer buffer; + private final ByteBuffer contents; private final int vertexCount; private final long base; - public PosTexNormalVertexListUnsafe(ByteBuffer buffer, int vertexCount) { - this.buffer = buffer; + public PosTexNormalVertexListUnsafe(ByteBuffer copyFrom, int vertexCount) { + this.contents = MemoryTracker.create(copyFrom.capacity()); + this.contents.order(copyFrom.order()); + this.contents.put(copyFrom); + ((Buffer) this.contents).flip(); + + this.base = MemoryUtil.memAddress(this.contents); this.vertexCount = vertexCount; - this.base = MemoryUtil.memAddress(buffer); } private long ptr(long idx) { From f01e1699541c9d8675c035b812010b0505cfc539 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Mon, 11 Jul 2022 14:08:07 -0400 Subject: [PATCH 06/11] Reading copy - All vertex lists extend from AbstractVertexList, which handles copying the input --- .../core/vertex/AbstractVertexList.java | 49 +++++++++++++++++++ .../flywheel/core/vertex/BlockVertexList.java | 49 ++++++------------- .../core/vertex/BlockVertexListUnsafe.java | 19 +------ .../vertex/PosTexNormalVertexListUnsafe.java | 19 +------ 4 files changed, 69 insertions(+), 67 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java new file mode 100644 index 000000000..a68e0c943 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java @@ -0,0 +1,49 @@ +package com.jozufozu.flywheel.core.vertex; + +import java.nio.Buffer; +import java.nio.ByteBuffer; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.api.vertex.VertexList; +import com.mojang.blaze3d.platform.MemoryTracker; +import com.mojang.blaze3d.vertex.BufferBuilder; + +public abstract class AbstractVertexList implements VertexList, AutoCloseable { + + protected final ByteBuffer contents; + protected final long base; + protected final int vertexCount; + + protected AbstractVertexList(ByteBuffer copyFrom, int vertexCount) { + this.contents = MemoryTracker.create(copyFrom.capacity()); + this.vertexCount = vertexCount; + this.base = MemoryUtil.memAddress(this.contents); + init(copyFrom); + } + + public AbstractVertexList(BufferBuilder builder) { + var pair = builder.popNextBuffer(); + ByteBuffer copyFrom = pair.getSecond(); + this.contents = MemoryTracker.create(copyFrom.capacity()); + this.vertexCount = pair.getFirst().vertexCount(); + this.base = MemoryUtil.memAddress(this.contents); + init(copyFrom); + } + + private void init(ByteBuffer copyFrom) { + this.contents.order(copyFrom.order()); + this.contents.put(copyFrom); + ((Buffer) this.contents).flip(); + } + + @Override + public void close() { + MemoryUtil.memFree(contents); + } + + @Override + public int getVertexCount() { + return vertexCount; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java index eaac02cee..f84385f78 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java @@ -1,30 +1,18 @@ package com.jozufozu.flywheel.core.vertex; -import java.nio.ByteBuffer; - import com.jozufozu.flywheel.api.vertex.ShadedVertexList; -import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder; import com.jozufozu.flywheel.util.RenderMath; import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.datafixers.util.Pair; -public class BlockVertexList implements VertexList { +public class BlockVertexList extends AbstractVertexList { - private final ByteBuffer buffer; - private final int vertexCount; private final int stride; public BlockVertexList(BufferBuilder builder) { - Pair data = builder.popNextBuffer(); - buffer = data.getSecond(); - - stride = builder.getVertexFormat() + super(builder); + this.stride = builder.getVertexFormat() .getVertexSize(); - - vertexCount = data.getFirst() - .vertexCount(); - } @Override @@ -38,72 +26,67 @@ public class BlockVertexList implements VertexList { @Override public float getX(int index) { - return buffer.getFloat(vertIdx(index)); + return contents.getFloat(vertIdx(index)); } @Override public float getY(int index) { - return buffer.getFloat(vertIdx(index) + 4); + return contents.getFloat(vertIdx(index) + 4); } @Override public float getZ(int index) { - return buffer.getFloat(vertIdx(index) + 8); + return contents.getFloat(vertIdx(index) + 8); } @Override public byte getR(int index) { - return buffer.get(vertIdx(index) + 12); + return contents.get(vertIdx(index) + 12); } @Override public byte getG(int index) { - return buffer.get(vertIdx(index) + 13); + return contents.get(vertIdx(index) + 13); } @Override public byte getB(int index) { - return buffer.get(vertIdx(index) + 14); + return contents.get(vertIdx(index) + 14); } @Override public byte getA(int index) { - return buffer.get(vertIdx(index) + 15); + return contents.get(vertIdx(index) + 15); } @Override public float getU(int index) { - return buffer.getFloat(vertIdx(index) + 16); + return contents.getFloat(vertIdx(index) + 16); } @Override public float getV(int index) { - return buffer.getFloat(vertIdx(index) + 20); + return contents.getFloat(vertIdx(index) + 20); } @Override public int getLight(int index) { - return buffer.getInt(vertIdx(index) + 24); + return contents.getInt(vertIdx(index) + 24); } @Override public float getNX(int index) { - return RenderMath.f(buffer.get(vertIdx(index) + 28)); + return RenderMath.f(contents.get(vertIdx(index) + 28)); } @Override public float getNY(int index) { - return RenderMath.f(buffer.get(vertIdx(index) + 29)); + return RenderMath.f(contents.get(vertIdx(index) + 29)); } @Override public float getNZ(int index) { - return RenderMath.f(buffer.get(vertIdx(index) + 30)); - } - - @Override - public int getVertexCount() { - return vertexCount; + return RenderMath.f(contents.get(vertIdx(index) + 30)); } public static class Shaded extends BlockVertexList implements ShadedVertexList { diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java index 839687a7e..959b90ef3 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java @@ -10,20 +10,10 @@ import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.util.RenderMath; import com.mojang.blaze3d.platform.MemoryTracker; -public class BlockVertexListUnsafe implements VertexList { - - private final ByteBuffer contents; - private final int vertexCount; - private final long base; +public class BlockVertexListUnsafe extends AbstractVertexList { public BlockVertexListUnsafe(ByteBuffer copyFrom, int vertexCount) { - this.contents = MemoryTracker.create(copyFrom.capacity()); - this.contents.order(copyFrom.order()); - this.contents.put(copyFrom); - ((Buffer) this.contents).flip(); - - this.base = MemoryUtil.memAddress(this.contents); - this.vertexCount = vertexCount; + super(copyFrom, vertexCount); } private long ptr(long index) { @@ -100,11 +90,6 @@ public class BlockVertexListUnsafe implements VertexList { return RenderMath.f(MemoryUtil.memGetByte(ptr(index) + 30)); } - @Override - public int getVertexCount() { - return vertexCount; - } - public static class Shaded extends BlockVertexListUnsafe implements ShadedVertexList { private final int unshadedStartVertex; diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java index e94861b47..79baf8e00 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java @@ -9,20 +9,10 @@ import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.util.RenderMath; import com.mojang.blaze3d.platform.MemoryTracker; -public class PosTexNormalVertexListUnsafe implements VertexList { - - private final ByteBuffer contents; - private final int vertexCount; - private final long base; +public class PosTexNormalVertexListUnsafe extends AbstractVertexList { public PosTexNormalVertexListUnsafe(ByteBuffer copyFrom, int vertexCount) { - this.contents = MemoryTracker.create(copyFrom.capacity()); - this.contents.order(copyFrom.order()); - this.contents.put(copyFrom); - ((Buffer) this.contents).flip(); - - this.base = MemoryUtil.memAddress(this.contents); - this.vertexCount = vertexCount; + super(copyFrom, vertexCount); } private long ptr(long idx) { @@ -93,9 +83,4 @@ public class PosTexNormalVertexListUnsafe implements VertexList { public float getNZ(int index) { return RenderMath.f(MemoryUtil.memGetByte(ptr(index) + 22)); } - - @Override - public int getVertexCount() { - return vertexCount; - } } From d9cdd361cd66a37b9cd24db864d30e35e283646b Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Mon, 11 Jul 2022 14:36:54 -0400 Subject: [PATCH 07/11] One line update - Add modrinth updateJSONURL --- src/main/resources/META-INF/mods.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index a9f736a89..2f6649f40 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -9,6 +9,7 @@ version = "${file.jarVersion}" displayName = "Flywheel" logoFile = "logo.png" displayURL = "https://www.curseforge.com/minecraft/mc-mods/flywheel" +updateJSONURL = "https://api.modrinth.com/updates/5lpsZoRi/forge_updates.json" authors = "Jozufozu" description = ''' A modern engine for modded minecraft.''' From 0a671b8f439c4d37721478c1a700e32b6faf2429 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Mon, 11 Jul 2022 20:55:01 -0400 Subject: [PATCH 08/11] Update changelog and bug report template --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 ++ changelog.txt | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 03c717f62..0f414bd42 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -59,6 +59,8 @@ body: label: Mod Version description: The version of the mod you were using when the bug occured options: + - "0.6.4" + - "0.6.3" - "0.6.2" - "0.6.1" - "0.6.0" diff --git a/changelog.txt b/changelog.txt index 1682e9cdc..c7781fb32 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,11 @@ +0.6.4: +Fixes + - Fix shader detection with oculus +Technical/API + - LightUpdater is simplified to increase reliability and reflect how it is actually used + - ModelUtil is superseded by model builders, to be improved more in 0.7.0 + - VertexLists now copy input buffers to reduce memory usage + 0.6.3: Technical/API - Light updates are now processed in parallel. From a42c027b6f3ae4125d4bf5d70ed80ecda9c9f8c4 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Fri, 15 Jul 2022 00:00:54 -0700 Subject: [PATCH 09/11] Scheme-a-version - Fix Resources not being closed properly - Change versioning scheme to match Create - Add LICENSE to built jar - Fix mods.toml version sync - Move JOML code to non-src directory - Update Gradle - Organize imports --- build.gradle | 67 ++++++++++-------- gradle.properties | 3 +- gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 10 +-- .../repack/joml => joml}/AxisAngle4d.java | 0 .../repack/joml => joml}/AxisAngle4f.java | 0 .../joml => joml}/ConfigurationException.java | 0 .../joml => joml}/FrustumIntersection.java | 0 .../joml => joml}/FrustumRayBuilder.java | 0 .../repack/joml => joml}/GeometryUtils.java | 0 .../repack/joml => joml}/Interpolationd.java | 0 .../repack/joml => joml}/Interpolationf.java | 0 .../repack/joml => joml}/Intersectiond.java | 0 .../repack/joml => joml}/Intersectionf.java | 0 .../flywheel/repack/joml => joml}/Math.java | 0 .../repack/joml => joml}/Matrix2d.java | 0 .../repack/joml => joml}/Matrix2dc.java | 0 .../repack/joml => joml}/Matrix2f.java | 0 .../repack/joml => joml}/Matrix2fc.java | 0 .../repack/joml => joml}/Matrix3d.java | 0 .../repack/joml => joml}/Matrix3dStack.java | 0 .../repack/joml => joml}/Matrix3dc.java | 0 .../repack/joml => joml}/Matrix3f.java | 0 .../repack/joml => joml}/Matrix3fStack.java | 0 .../repack/joml => joml}/Matrix3fc.java | 0 .../repack/joml => joml}/Matrix3x2d.java | 0 .../repack/joml => joml}/Matrix3x2dStack.java | 0 .../repack/joml => joml}/Matrix3x2dc.java | 0 .../repack/joml => joml}/Matrix3x2f.java | 0 .../repack/joml => joml}/Matrix3x2fStack.java | 0 .../repack/joml => joml}/Matrix3x2fc.java | 0 .../repack/joml => joml}/Matrix4d.java | 0 .../repack/joml => joml}/Matrix4dStack.java | 0 .../repack/joml => joml}/Matrix4dc.java | 0 .../repack/joml => joml}/Matrix4f.java | 0 .../repack/joml => joml}/Matrix4fStack.java | 0 .../repack/joml => joml}/Matrix4fc.java | 0 .../repack/joml => joml}/Matrix4x3d.java | 0 .../repack/joml => joml}/Matrix4x3dStack.java | 0 .../repack/joml => joml}/Matrix4x3dc.java | 0 .../repack/joml => joml}/Matrix4x3f.java | 0 .../repack/joml => joml}/Matrix4x3fStack.java | 0 .../repack/joml => joml}/Matrix4x3fc.java | 0 .../repack/joml => joml}/MemUtil.java | 0 .../repack/joml => joml}/Options.java | 0 .../joml => joml}/PolygonsIntersection.java | 0 .../repack/joml => joml}/Quaterniond.java | 0 .../QuaterniondInterpolator.java | 0 .../repack/joml => joml}/Quaterniondc.java | 0 .../repack/joml => joml}/Quaternionf.java | 0 .../QuaternionfInterpolator.java | 0 .../repack/joml => joml}/Quaternionfc.java | 0 .../flywheel/repack/joml => joml}/Random.java | 0 .../joml => joml}/RayAabIntersection.java | 0 .../repack/joml => joml}/RoundingMode.java | 0 .../repack/joml => joml}/Runtime.java | 0 .../repack/joml => joml}/SimplexNoise.java | 0 .../repack/joml => joml}/Vector2d.java | 0 .../repack/joml => joml}/Vector2dc.java | 0 .../repack/joml => joml}/Vector2f.java | 0 .../repack/joml => joml}/Vector2fc.java | 0 .../repack/joml => joml}/Vector2i.java | 0 .../repack/joml => joml}/Vector2ic.java | 0 .../repack/joml => joml}/Vector3d.java | 0 .../repack/joml => joml}/Vector3dc.java | 0 .../repack/joml => joml}/Vector3f.java | 0 .../repack/joml => joml}/Vector3fc.java | 0 .../repack/joml => joml}/Vector3i.java | 0 .../repack/joml => joml}/Vector3ic.java | 0 .../repack/joml => joml}/Vector4d.java | 0 .../repack/joml => joml}/Vector4dc.java | 0 .../repack/joml => joml}/Vector4f.java | 0 .../repack/joml => joml}/Vector4fc.java | 0 .../repack/joml => joml}/Vector4i.java | 0 .../repack/joml => joml}/Vector4ic.java | 0 .../repack/joml => joml}/package.html | 0 .../sampling/BestCandidateSampling.java | 0 .../joml => joml}/sampling/Callback2d.java | 0 .../joml => joml}/sampling/Callback3d.java | 0 .../joml => joml}/sampling/Convolution.java | 0 .../repack/joml => joml}/sampling/Math.java | 0 .../sampling/PoissonSampling.java | 0 .../sampling/SpiralSampling.java | 0 .../sampling/StratifiedSampling.java | 0 .../sampling/UniformSampling.java | 0 .../joml => joml}/sampling/package.html | 0 .../jozufozu/flywheel/backend/Backend.java | 2 +- .../com/jozufozu/flywheel/backend/Loader.java | 6 +- .../jozufozu/flywheel/config/FlwCommands.java | 1 - .../flywheel/core/source/ShaderSources.java | 6 +- .../core/vertex/BlockVertexListUnsafe.java | 3 - .../vertex/PosTexNormalVertexListUnsafe.java | 3 - .../jozufozu/flywheel/util/WorldAttached.java | 1 - src/main/resources/META-INF/mods.toml | 2 +- 95 files changed, 50 insertions(+), 56 deletions(-) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/AxisAngle4d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/AxisAngle4f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/ConfigurationException.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/FrustumIntersection.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/FrustumRayBuilder.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/GeometryUtils.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Interpolationd.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Interpolationf.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Intersectiond.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Intersectionf.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Math.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix2d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix2dc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix2f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix2fc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3dStack.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3dc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3fStack.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3fc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3x2d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3x2dStack.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3x2dc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3x2f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3x2fStack.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix3x2fc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4dStack.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4dc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4fStack.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4fc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4x3d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4x3dStack.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4x3dc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4x3f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4x3fStack.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Matrix4x3fc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/MemUtil.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Options.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/PolygonsIntersection.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Quaterniond.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/QuaterniondInterpolator.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Quaterniondc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Quaternionf.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/QuaternionfInterpolator.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Quaternionfc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Random.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/RayAabIntersection.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/RoundingMode.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Runtime.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/SimplexNoise.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector2d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector2dc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector2f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector2fc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector2i.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector2ic.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector3d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector3dc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector3f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector3fc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector3i.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector3ic.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector4d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector4dc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector4f.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector4fc.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector4i.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/Vector4ic.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/package.html (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/BestCandidateSampling.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/Callback2d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/Callback3d.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/Convolution.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/Math.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/PoissonSampling.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/SpiralSampling.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/StratifiedSampling.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/UniformSampling.java (100%) rename {src/main/java/com/jozufozu/flywheel/repack/joml => joml}/sampling/package.html (100%) diff --git a/build.gradle b/build.gradle index 341b6b0e2..438422d9a 100644 --- a/build.gradle +++ b/build.gradle @@ -11,10 +11,10 @@ buildscript { classpath "org.parchmentmc:librarian:${librarian_version}" } } + plugins { id 'com.matthewprenger.cursegradle' version "${cursegradle_version}" } - apply plugin: 'net.minecraftforge.gradle' apply plugin: 'org.parchmentmc.librarian.forgegradle' apply plugin: 'eclipse' @@ -24,11 +24,10 @@ apply plugin: 'org.spongepowered.mixin' boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equalsIgnoreCase('false'); ext.buildNumber = System.getenv('BUILD_NUMBER') -if (buildNumber == null) buildNumber = 'custom' -version = "${mc_update_version}-${mod_version}" + (dev ? ".${buildNumber}" : '') group = 'com.jozufozu.flywheel' -archivesBaseName = 'flywheel-forge' +archivesBaseName = "flywheel-forge-${artifact_minecraft_version}" +version = mod_version + (dev && buildNumber != null ? "-${buildNumber}" : '') java.toolchain.languageVersion = JavaLanguageVersion.of(17) @@ -36,7 +35,6 @@ println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getPro minecraft { mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}" - runs { client { workingDirectory project.file('run') @@ -89,10 +87,6 @@ minecraft { } } -mixin { - add sourceSets.main, 'flywheel.refmap.json' -} - repositories { maven { url 'https://www.cursemaven.com' @@ -130,53 +124,64 @@ dependencies { } } -// Example for how to get properties into the manifest for reading by the runtime.. +processResources { + inputs.property 'version', mod_version + + filesMatching('META-INF/mods.toml') { + expand 'version': mod_version + } +} + +mixin { + add sourceSets.main, 'flywheel.refmap.json' +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation +} + jar { manifest { attributes([ 'Specification-Title' : 'flywheel', //'Specification-Vendor': 'flywheel authors', 'Specification-Version' : '1', // We are version 1 of ourselves - 'Implementation-Title' : project.name, - 'Implementation-Version' : project.version, + 'Implementation-Title' : project.jar.baseName, + 'Implementation-Version' : project.jar.archiveVersion, //'Implementation-Vendor': 'flywheel authors', - 'MixinConfigs' : 'flywheel.mixins.json', - 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), + 'MixinConfigs' : 'flywheel.mixins.json' ]) } } -jar.finalizedBy('reobfJar') - javadoc { source = [sourceSets.main.allJava] // prevent java 8's strict doclint for javadocs from failing builds options.addStringOption('Xdoclint:none', '-quiet') } -task sourcesJar(type: Jar) { - from sourceSets.main.allSource - archiveBaseName.set(project.archivesBaseName) - archiveVersion.set("${project.version}") - archiveClassifier.set('sources') +java { + withSourcesJar() + withJavadocJar() } -task javadocJar(type: Jar, dependsOn: javadoc) { - from javadoc.destinationDir - archiveClassifier.set('javadoc') +void addLicense(jarTask) { + jarTask.from('LICENSE') { + rename { "${it}_${project.archivesBaseName}" } + } } -artifacts { - archives jar, sourcesJar, javadocJar -} +jar.finalizedBy('reobfJar') +addLicense(jar) publishing { - tasks.publish.dependsOn 'build' publications { mavenJava(MavenPublication) { - artifact jar - artifact sourcesJar - artifact javadocJar + artifactId = archivesBaseName + + from components.java + fg.component(it) } } diff --git a/gradle.properties b/gradle.properties index 42e95d776..67b6f3ee8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,8 @@ org.gradle.daemon = false # mod version info mod_version = 0.6.4 -mc_update_version = 1.18 +artifact_minecraft_version = 1.18.2 + minecraft_version = 1.18.2 forge_version = 40.1.60 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 8958 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 84d1f85fd..aa991fcea 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index c53aefaa5..1b6c78733 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,10 +32,10 @@ # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/AxisAngle4d.java b/joml/AxisAngle4d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/AxisAngle4d.java rename to joml/AxisAngle4d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/AxisAngle4f.java b/joml/AxisAngle4f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/AxisAngle4f.java rename to joml/AxisAngle4f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/ConfigurationException.java b/joml/ConfigurationException.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/ConfigurationException.java rename to joml/ConfigurationException.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/FrustumIntersection.java b/joml/FrustumIntersection.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/FrustumIntersection.java rename to joml/FrustumIntersection.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/FrustumRayBuilder.java b/joml/FrustumRayBuilder.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/FrustumRayBuilder.java rename to joml/FrustumRayBuilder.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/GeometryUtils.java b/joml/GeometryUtils.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/GeometryUtils.java rename to joml/GeometryUtils.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Interpolationd.java b/joml/Interpolationd.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Interpolationd.java rename to joml/Interpolationd.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Interpolationf.java b/joml/Interpolationf.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Interpolationf.java rename to joml/Interpolationf.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Intersectiond.java b/joml/Intersectiond.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Intersectiond.java rename to joml/Intersectiond.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Intersectionf.java b/joml/Intersectionf.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Intersectionf.java rename to joml/Intersectionf.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Math.java b/joml/Math.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Math.java rename to joml/Math.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2d.java b/joml/Matrix2d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2d.java rename to joml/Matrix2d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2dc.java b/joml/Matrix2dc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2dc.java rename to joml/Matrix2dc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2f.java b/joml/Matrix2f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2f.java rename to joml/Matrix2f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2fc.java b/joml/Matrix2fc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix2fc.java rename to joml/Matrix2fc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3d.java b/joml/Matrix3d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3d.java rename to joml/Matrix3d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3dStack.java b/joml/Matrix3dStack.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3dStack.java rename to joml/Matrix3dStack.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3dc.java b/joml/Matrix3dc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3dc.java rename to joml/Matrix3dc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3f.java b/joml/Matrix3f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3f.java rename to joml/Matrix3f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3fStack.java b/joml/Matrix3fStack.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3fStack.java rename to joml/Matrix3fStack.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3fc.java b/joml/Matrix3fc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3fc.java rename to joml/Matrix3fc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2d.java b/joml/Matrix3x2d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2d.java rename to joml/Matrix3x2d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2dStack.java b/joml/Matrix3x2dStack.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2dStack.java rename to joml/Matrix3x2dStack.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2dc.java b/joml/Matrix3x2dc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2dc.java rename to joml/Matrix3x2dc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2f.java b/joml/Matrix3x2f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2f.java rename to joml/Matrix3x2f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2fStack.java b/joml/Matrix3x2fStack.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2fStack.java rename to joml/Matrix3x2fStack.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2fc.java b/joml/Matrix3x2fc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix3x2fc.java rename to joml/Matrix3x2fc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4d.java b/joml/Matrix4d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4d.java rename to joml/Matrix4d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4dStack.java b/joml/Matrix4dStack.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4dStack.java rename to joml/Matrix4dStack.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4dc.java b/joml/Matrix4dc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4dc.java rename to joml/Matrix4dc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4f.java b/joml/Matrix4f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4f.java rename to joml/Matrix4f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4fStack.java b/joml/Matrix4fStack.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4fStack.java rename to joml/Matrix4fStack.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4fc.java b/joml/Matrix4fc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4fc.java rename to joml/Matrix4fc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3d.java b/joml/Matrix4x3d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3d.java rename to joml/Matrix4x3d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3dStack.java b/joml/Matrix4x3dStack.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3dStack.java rename to joml/Matrix4x3dStack.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3dc.java b/joml/Matrix4x3dc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3dc.java rename to joml/Matrix4x3dc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3f.java b/joml/Matrix4x3f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3f.java rename to joml/Matrix4x3f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3fStack.java b/joml/Matrix4x3fStack.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3fStack.java rename to joml/Matrix4x3fStack.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3fc.java b/joml/Matrix4x3fc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Matrix4x3fc.java rename to joml/Matrix4x3fc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/MemUtil.java b/joml/MemUtil.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/MemUtil.java rename to joml/MemUtil.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Options.java b/joml/Options.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Options.java rename to joml/Options.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/PolygonsIntersection.java b/joml/PolygonsIntersection.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/PolygonsIntersection.java rename to joml/PolygonsIntersection.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Quaterniond.java b/joml/Quaterniond.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Quaterniond.java rename to joml/Quaterniond.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/QuaterniondInterpolator.java b/joml/QuaterniondInterpolator.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/QuaterniondInterpolator.java rename to joml/QuaterniondInterpolator.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Quaterniondc.java b/joml/Quaterniondc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Quaterniondc.java rename to joml/Quaterniondc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Quaternionf.java b/joml/Quaternionf.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Quaternionf.java rename to joml/Quaternionf.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/QuaternionfInterpolator.java b/joml/QuaternionfInterpolator.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/QuaternionfInterpolator.java rename to joml/QuaternionfInterpolator.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Quaternionfc.java b/joml/Quaternionfc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Quaternionfc.java rename to joml/Quaternionfc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Random.java b/joml/Random.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Random.java rename to joml/Random.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/RayAabIntersection.java b/joml/RayAabIntersection.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/RayAabIntersection.java rename to joml/RayAabIntersection.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/RoundingMode.java b/joml/RoundingMode.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/RoundingMode.java rename to joml/RoundingMode.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Runtime.java b/joml/Runtime.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Runtime.java rename to joml/Runtime.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/SimplexNoise.java b/joml/SimplexNoise.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/SimplexNoise.java rename to joml/SimplexNoise.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector2d.java b/joml/Vector2d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector2d.java rename to joml/Vector2d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector2dc.java b/joml/Vector2dc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector2dc.java rename to joml/Vector2dc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector2f.java b/joml/Vector2f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector2f.java rename to joml/Vector2f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector2fc.java b/joml/Vector2fc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector2fc.java rename to joml/Vector2fc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector2i.java b/joml/Vector2i.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector2i.java rename to joml/Vector2i.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector2ic.java b/joml/Vector2ic.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector2ic.java rename to joml/Vector2ic.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector3d.java b/joml/Vector3d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector3d.java rename to joml/Vector3d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector3dc.java b/joml/Vector3dc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector3dc.java rename to joml/Vector3dc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector3f.java b/joml/Vector3f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector3f.java rename to joml/Vector3f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector3fc.java b/joml/Vector3fc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector3fc.java rename to joml/Vector3fc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector3i.java b/joml/Vector3i.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector3i.java rename to joml/Vector3i.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector3ic.java b/joml/Vector3ic.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector3ic.java rename to joml/Vector3ic.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector4d.java b/joml/Vector4d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector4d.java rename to joml/Vector4d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector4dc.java b/joml/Vector4dc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector4dc.java rename to joml/Vector4dc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector4f.java b/joml/Vector4f.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector4f.java rename to joml/Vector4f.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector4fc.java b/joml/Vector4fc.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector4fc.java rename to joml/Vector4fc.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector4i.java b/joml/Vector4i.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector4i.java rename to joml/Vector4i.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/Vector4ic.java b/joml/Vector4ic.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/Vector4ic.java rename to joml/Vector4ic.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/package.html b/joml/package.html similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/package.html rename to joml/package.html diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/BestCandidateSampling.java b/joml/sampling/BestCandidateSampling.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/BestCandidateSampling.java rename to joml/sampling/BestCandidateSampling.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/Callback2d.java b/joml/sampling/Callback2d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/Callback2d.java rename to joml/sampling/Callback2d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/Callback3d.java b/joml/sampling/Callback3d.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/Callback3d.java rename to joml/sampling/Callback3d.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/Convolution.java b/joml/sampling/Convolution.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/Convolution.java rename to joml/sampling/Convolution.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/Math.java b/joml/sampling/Math.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/Math.java rename to joml/sampling/Math.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/PoissonSampling.java b/joml/sampling/PoissonSampling.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/PoissonSampling.java rename to joml/sampling/PoissonSampling.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/SpiralSampling.java b/joml/sampling/SpiralSampling.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/SpiralSampling.java rename to joml/sampling/SpiralSampling.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/StratifiedSampling.java b/joml/sampling/StratifiedSampling.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/StratifiedSampling.java rename to joml/sampling/StratifiedSampling.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/UniformSampling.java b/joml/sampling/UniformSampling.java similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/UniformSampling.java rename to joml/sampling/UniformSampling.java diff --git a/src/main/java/com/jozufozu/flywheel/repack/joml/sampling/package.html b/joml/sampling/package.html similarity index 100% rename from src/main/java/com/jozufozu/flywheel/repack/joml/sampling/package.html rename to joml/sampling/package.html diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index 77528cb30..977ac0162 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -7,8 +7,8 @@ import org.slf4j.Logger; import com.jozufozu.flywheel.api.FlywheelWorld; import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.instancing.ParallelTaskEngine; -import com.jozufozu.flywheel.config.FlwConfig; import com.jozufozu.flywheel.config.BackendType; +import com.jozufozu.flywheel.config.FlwConfig; import com.jozufozu.flywheel.core.shader.ProgramSpec; import com.mojang.logging.LogUtils; diff --git a/src/main/java/com/jozufozu/flywheel/backend/Loader.java b/src/main/java/com/jozufozu/flywheel/backend/Loader.java index 94c3628cf..203c2660c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Loader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Loader.java @@ -96,10 +96,8 @@ public class Loader implements ResourceManagerReloadListener { Collection programSpecs = manager.listResources(PROGRAM_DIR, s -> s.endsWith(".json")); for (ResourceLocation location : programSpecs) { - try { - Resource file = manager.getResource(location); - - String s = StringUtil.readToString(file.getInputStream()); + try (Resource resource = manager.getResource(location)) { + String s = StringUtil.readToString(resource.getInputStream()); ResourceLocation specName = ResourceUtil.trim(location, PROGRAM_DIR, ".json"); diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java index ce0ea95d7..12b775205 100644 --- a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java +++ b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java @@ -19,7 +19,6 @@ import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.TextComponent; import net.minecraftforge.client.event.RegisterClientCommandsEvent; import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; -import net.minecraftforge.fml.ModList; public class FlwCommands { public static void registerClientCommands(RegisterClientCommandsEvent event) { diff --git a/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java b/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java index b7e29c2a4..c4b42ec10 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java @@ -36,16 +36,14 @@ public class ShaderSources implements SourceFinder { }); for (ResourceLocation location : allShaders) { - try { - Resource resource = manager.getResource(location); - + try (Resource resource = manager.getResource(location)) { String source = StringUtil.readToString(resource.getInputStream()); ResourceLocation name = ResourceUtil.removePrefixUnchecked(location, SHADER_DIR); shaderSources.put(name, new SourceFile(this, name, source)); } catch (IOException e) { - + // } } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java index 959b90ef3..07dbdeb4d 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java @@ -1,14 +1,11 @@ package com.jozufozu.flywheel.core.vertex; -import java.nio.Buffer; import java.nio.ByteBuffer; import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.vertex.ShadedVertexList; -import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.util.RenderMath; -import com.mojang.blaze3d.platform.MemoryTracker; public class BlockVertexListUnsafe extends AbstractVertexList { diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java index 79baf8e00..6b5a99305 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java @@ -1,13 +1,10 @@ package com.jozufozu.flywheel.core.vertex; -import java.nio.Buffer; import java.nio.ByteBuffer; import org.lwjgl.system.MemoryUtil; -import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.util.RenderMath; -import com.mojang.blaze3d.platform.MemoryTracker; public class PosTexNormalVertexListUnsafe extends AbstractVertexList { diff --git a/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java b/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java index 45b989f2f..2573a9a52 100644 --- a/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java +++ b/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java @@ -3,7 +3,6 @@ package com.jozufozu.flywheel.util; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 2f6649f40..347fb6482 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -5,7 +5,7 @@ license = "MIT" [[mods]] modId = "flywheel" -version = "${file.jarVersion}" +version = "${version}" displayName = "Flywheel" logoFile = "logo.png" displayURL = "https://www.curseforge.com/minecraft/mc-mods/flywheel" From 17d8688fd72b2183269935a453aecfab67b943c7 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Fri, 15 Jul 2022 09:42:14 -0700 Subject: [PATCH 10/11] Fix mixins sometimes not remapping - Compress logo image --- build.gradle | 17 +++++++++++------ src/main/resources/logo.png | Bin 73785 -> 57936 bytes 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 438422d9a..952fa137c 100644 --- a/build.gradle +++ b/build.gradle @@ -136,10 +136,21 @@ mixin { add sourceSets.main, 'flywheel.refmap.json' } +// Fix for SpongePowered/MixinGradle#38 +afterEvaluate { + tasks.configureReobfTaskForReobfJar.mustRunAfter(tasks.compileJava) +} + tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation } +javadoc { + source = [sourceSets.main.allJava] + // prevent java 8's strict doclint for javadocs from failing builds + options.addStringOption('Xdoclint:none', '-quiet') +} + jar { manifest { attributes([ @@ -155,12 +166,6 @@ jar { } } -javadoc { - source = [sourceSets.main.allJava] - // prevent java 8's strict doclint for javadocs from failing builds - options.addStringOption('Xdoclint:none', '-quiet') -} - java { withSourcesJar() withJavadocJar() diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png index e660fbc83ab2ea5dcdca0ef4b3aa1e9f853761af..1a02d5f3f2e8eb585105c8ba52fb11d9f07fdb9d 100644 GIT binary patch literal 57936 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%0A)49H71^~po9#7e$7 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 GV*U@sAGIw2 From 418672c065200172687cc1b712658f07ced89612 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Fri, 15 Jul 2022 19:29:42 -0700 Subject: [PATCH 11/11] Final fix-ups - Revert mods.toml version to ${file.jarVersion} - Fix license not being added to built jars - Rename LICENCE.md to LICENSE.md --- LICENCE.md => LICENSE.md | 0 build.gradle | 14 +++----------- src/main/resources/META-INF/mods.toml | 3 ++- 3 files changed, 5 insertions(+), 12 deletions(-) rename LICENCE.md => LICENSE.md (100%) diff --git a/LICENCE.md b/LICENSE.md similarity index 100% rename from LICENCE.md rename to LICENSE.md diff --git a/build.gradle b/build.gradle index 952fa137c..c2f7e6bc0 100644 --- a/build.gradle +++ b/build.gradle @@ -124,19 +124,11 @@ dependencies { } } -processResources { - inputs.property 'version', mod_version - - filesMatching('META-INF/mods.toml') { - expand 'version': mod_version - } -} - mixin { add sourceSets.main, 'flywheel.refmap.json' } -// Fix for SpongePowered/MixinGradle#38 +// Workaround for SpongePowered/MixinGradle#38 afterEvaluate { tasks.configureReobfTaskForReobfJar.mustRunAfter(tasks.compileJava) } @@ -172,8 +164,8 @@ java { } void addLicense(jarTask) { - jarTask.from('LICENSE') { - rename { "${it}_${project.archivesBaseName}" } + jarTask.from('LICENSE.md') { + rename '(.*)\\.(.*)', '$1_' + archivesBaseName + '.$2' } } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 347fb6482..1ca2ff67b 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -5,7 +5,8 @@ license = "MIT" [[mods]] modId = "flywheel" -version = "${version}" +# The Implementation-Version property in the jar's MANIFEST.MF file will be used as the mod version at runtime +version = "${file.jarVersion}" displayName = "Flywheel" logoFile = "logo.png" displayURL = "https://www.curseforge.com/minecraft/mc-mods/flywheel"