diff --git a/build.gradle b/build.gradle
index e6ca87806..48235fc58 100644
--- a/build.gradle
+++ b/build.gradle
@@ -11,7 +11,7 @@ project.buildnumber = System.getenv('BUILD_NUMBER') != null ? System.getenv('BUI
version = "${mc_update_version}-${mod_version}" + (dev ? ".${buildnumber}" : '')
group = 'com.jozufozu.flywheel'
-archivesBaseName = 'flywheel'
+archivesBaseName = 'flywheel-fabric'
sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16
diff --git a/gradle.properties b/gradle.properties
index f4921ab8a..28ca8d50f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,7 @@ mod_version = 0.3.0
mc_update_version = 1.17
minecraft_version = 1.17.1
loader_version = 0.12.5
-fabric_version = 0.42.1+1.17
+fabric_version = 0.43.0+1.17
# build dependency versions
loom_version = 0.10-SNAPSHOT
diff --git a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java
index a65bc5ec7..00707df63 100644
--- a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java
+++ b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java
@@ -5,7 +5,6 @@ import com.jozufozu.flywheel.backend.Loader;
import com.jozufozu.flywheel.backend.RenderWork;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.config.FlwConfig;
-import com.jozufozu.flywheel.core.AtlasStitcher;
import com.jozufozu.flywheel.core.Contexts;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.PartialModel;
@@ -21,10 +20,8 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
-import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.server.packs.PackType;
-import net.minecraft.world.inventory.InventoryMenu;
public class FlywheelClient implements ClientModInitializer {
@@ -33,8 +30,6 @@ public class FlywheelClient implements ClientModInitializer {
Backend.init();
- ClientSpriteRegistryCallback.event(InventoryMenu.BLOCK_ATLAS).register(AtlasStitcher.getInstance()::onTextureStitch);
-
FlywheelEvents.GATHER_CONTEXT.register(Contexts::flwInit);
FlywheelEvents.GATHER_CONTEXT.register(Materials::flwInit);
ModelLoadingRegistry.INSTANCE.registerModelProvider(PartialModel::onModelRegistry);
diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java
index 9228aebea..fe4dc0322 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java
@@ -40,7 +40,6 @@ public class Backend {
private boolean instancedArrays;
private boolean enabled;
- public boolean chunkCachingEnabled;
private final List> contexts = new ArrayList<>();
private final Map> materialRegistry = new HashMap<>();
@@ -138,8 +137,6 @@ public class Backend {
enabled = FlwConfig.get()
.enabled() && !OptifineHandler.usingShaders();
- chunkCachingEnabled = FlwConfig.get()
- .chunkCaching();
}
public boolean canUseInstancing(@Nullable Level world) {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java
index 474d03de8..b7c65f323 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java
@@ -22,7 +22,8 @@ public class InstancedRenderDispatcher {
* @param te The tile whose instance you want to update.
*/
public static void enqueueUpdate(BlockEntity te) {
- getTiles(te.getLevel()).queueUpdate(te);
+ if (te.hasLevel() && te.getLevel() instanceof ClientLevel)
+ getTiles(te.getLevel()).queueUpdate(te);
}
/**
diff --git a/src/main/java/com/jozufozu/flywheel/config/ConfigCommands.java b/src/main/java/com/jozufozu/flywheel/config/ConfigCommands.java
index e1921933c..f9b9671da 100644
--- a/src/main/java/com/jozufozu/flywheel/config/ConfigCommands.java
+++ b/src/main/java/com/jozufozu/flywheel/config/ConfigCommands.java
@@ -46,18 +46,6 @@ public final class ConfigCommands {
}
));
- commandBuilder.addOption(config.chunkCaching, (builder, option) -> booleanOptionCommand(builder, config, option,
- (source, value) -> {
- Component text = new TextComponent("Chunk caching is currently: ").append(boolToText(value));
- source.sendFeedback(text);
- },
- (source, value) -> {
- Component text = boolToText(value).append(new TextComponent(" chunk caching").withStyle(ChatFormatting.WHITE));
- source.sendFeedback(text);
- Backend.reloadWorldRenderers();
- }
- ));
-
commandBuilder.build();
}
diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java b/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java
index 6b6308517..1c16d87ea 100644
--- a/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java
+++ b/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java
@@ -38,8 +38,6 @@ public class FlwConfig {
public final BooleanOption enabled = addOption(new BooleanOption("enabled", true));
/** Enable or disable a debug overlay that colors pixels by their normal */
public final BooleanOption debugNormals = addOption(new BooleanOption("debugNormals", false));
- /** Cache chunk lookups to improve performance. */
- public final BooleanOption chunkCaching = addOption(new BooleanOption("chunkCaching", true));
public FlwConfig(File file) {
this.file = file;
@@ -62,10 +60,6 @@ public class FlwConfig {
return debugNormals.get();
}
- public boolean chunkCaching() {
- return chunkCaching.get();
- }
-
public void load() {
if (file.exists()) {
try (FileReader reader = new FileReader(file)) {
diff --git a/src/main/java/com/jozufozu/flywheel/core/AtlasStitcher.java b/src/main/java/com/jozufozu/flywheel/core/AtlasStitcher.java
deleted file mode 100644
index aff5a97e4..000000000
--- a/src/main/java/com/jozufozu/flywheel/core/AtlasStitcher.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.jozufozu.flywheel.core;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback.Registry;
-import net.minecraft.client.renderer.texture.TextureAtlas;
-import net.minecraft.resources.ResourceLocation;
-
-/**
- * This is primarily for hacking entity textures into the block atlas.
- */
-public class AtlasStitcher {
- protected static final AtlasStitcher INSTANCE = new AtlasStitcher();
-
- public static AtlasStitcher getInstance() {
- return INSTANCE;
- }
-
- private final List sprites = new ArrayList<>();
-
- public StitchedSprite get(ResourceLocation loc) {
- StitchedSprite sprite = new StitchedSprite(loc);
-
- sprites.add(sprite);
-
- return sprite;
- }
-
- public void onTextureStitch(TextureAtlas atlasTexture, Registry registry) {
- sprites.forEach(StitchedSprite::reset);
- sprites.stream()
- .map(StitchedSprite::getLoc)
- .forEach(registry::register);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/core/StitchedSprite.java b/src/main/java/com/jozufozu/flywheel/core/StitchedSprite.java
index c43f045a6..a06f22d8a 100644
--- a/src/main/java/com/jozufozu/flywheel/core/StitchedSprite.java
+++ b/src/main/java/com/jozufozu/flywheel/core/StitchedSprite.java
@@ -1,35 +1,81 @@
package com.jozufozu.flywheel.core;
-import net.minecraft.client.Minecraft;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
+import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.InventoryMenu;
public class StitchedSprite {
+ private static final Map ALL = new HashMap<>();
- private final ResourceLocation loc;
+ protected final ResourceLocation atlasLocation;
+ protected final ResourceLocation location;
+ protected TextureAtlasSprite sprite;
- TextureAtlasSprite sprite;
-
- StitchedSprite(ResourceLocation loc) {
- this.loc = loc;
+ public StitchedSprite(ResourceLocation atlas, ResourceLocation location) {
+ atlasLocation = atlas;
+ this.location = location;
+ ALL.computeIfAbsent(atlasLocation, SingleAtlasSpriteHolder::new).add(this);
}
- public ResourceLocation getLoc() {
- return loc;
+ public StitchedSprite(ResourceLocation location) {
+ this(InventoryMenu.BLOCK_ATLAS, location);
}
- public TextureAtlasSprite getSprite() {
- if (sprite == null) {
- sprite = Minecraft.getInstance()
- .getTextureAtlas(InventoryMenu.BLOCK_ATLAS)
- .apply(loc);
+ public static void onTextureStitchPost(TextureAtlas atlas) {
+ ResourceLocation atlasLocation = atlas.location();
+ SingleAtlasSpriteHolder holder = ALL.get(atlasLocation);
+ if (holder != null) {
+ holder.loadSprites(atlas);
}
+ }
+ protected void loadSprite(TextureAtlas atlas) {
+ sprite = atlas.getSprite(location);
+ }
+
+ public ResourceLocation getAtlasLocation() {
+ return atlasLocation;
+ }
+
+ public ResourceLocation getLocation() {
+ return location;
+ }
+
+ public TextureAtlasSprite get() {
return sprite;
}
- void reset() {
- sprite = null;
+ private static class SingleAtlasSpriteHolder implements ClientSpriteRegistryCallback {
+ private final ResourceLocation atlasLocation;
+ private final List sprites = new ArrayList<>();
+
+ private SingleAtlasSpriteHolder(ResourceLocation atlasLocation) {
+ this.atlasLocation = atlasLocation;
+ ClientSpriteRegistryCallback.event(this.atlasLocation).register(this);
+ }
+
+ public void add(StitchedSprite sprite) {
+ sprites.add(sprite);
+ }
+
+ @Override
+ public void registerSprites(TextureAtlas atlas, Registry registry) {
+ for (StitchedSprite sprite : sprites) {
+ registry.register(sprite.getLocation());
+ }
+ }
+
+ public void loadSprites(TextureAtlas atlas) {
+ for (StitchedSprite sprite : sprites) {
+ sprite.loadSprite(atlas);
+ }
+ }
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelData.java b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelData.java
index 2d437a1d2..7f53555ba 100644
--- a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelData.java
+++ b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelData.java
@@ -1,24 +1,27 @@
package com.jozufozu.flywheel.core.materials.model;
-import java.nio.FloatBuffer;
-
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.core.materials.BasicData;
-import com.jozufozu.flywheel.util.Attribute;
+import com.jozufozu.flywheel.util.WriteSafe;
+import com.jozufozu.flywheel.util.transform.Rotate;
+import com.jozufozu.flywheel.util.transform.Scale;
+import com.jozufozu.flywheel.util.transform.Translate;
import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.math.Matrix3f;
+import com.mojang.math.Matrix4f;
+import com.mojang.math.Quaternion;
-public class ModelData extends BasicData {
- private static final float[] empty = new float[25];
+import net.minecraft.util.Mth;
- public final float[] matrices = empty.clone();
- private final FloatBuffer wrap = FloatBuffer.wrap(matrices);
+public class ModelData extends BasicData implements Translate, Rotate, Scale {
+ public final Matrix4f model = new Matrix4f();
+ public final Matrix3f normal = new Matrix3f();
public ModelData setTransform(PoseStack stack) {
- this.wrap.position(0);
-
- ((Attribute)(Object) stack.last().pose()).append(this.wrap);
- ((Attribute)(Object) stack.last().normal()).append(this.wrap);
markDirty();
+
+ this.model.load(stack.last().pose());
+ this.normal.load(stack.last().normal());
return this;
}
@@ -30,15 +33,63 @@ public class ModelData extends BasicData {
*
*/
public ModelData setEmptyTransform() {
- this.wrap.position(0)
- .put(empty);
markDirty();
+
+ this.model.load(new Matrix4f());
+ this.normal.load(new Matrix3f());
+ return this;
+ }
+
+ public ModelData loadIdentity() {
+ markDirty();
+
+ this.model.setIdentity();
+ this.normal.setIdentity();
return this;
}
@Override
public void write(VecBuffer buf) {
super.write(buf);
- buf.putFloatArray(matrices);
+ ((WriteSafe) (Object) model).write(buf);
+ ((WriteSafe) (Object) normal).write(buf);
+ }
+
+ @Override
+ public ModelData multiply(Quaternion quaternion) {
+ markDirty();
+
+ model.multiply(quaternion);
+ normal.mul(quaternion);
+ return this;
+ }
+
+ @Override
+ public ModelData scale(float pX, float pY, float pZ) {
+ markDirty();
+
+ model.multiply(Matrix4f.createScaleMatrix(pX, pY, pZ));
+ if (pX == pY && pY == pZ) {
+ if (pX > 0.0F) {
+ return this;
+ }
+
+ normal.mul(-1.0F);
+ }
+
+ float f = 1.0F / pX;
+ float f1 = 1.0F / pY;
+ float f2 = 1.0F / pZ;
+ float f3 = Mth.fastInvCubeRoot(f * f1 * f2);
+ normal.mul(Matrix3f.createScaleMatrix(f3 * f, f3 * f1, f3 * f2));
+ return this;
+ }
+
+ @Override
+ public ModelData translate(double x, double y, double z) {
+ markDirty();
+
+ model.multiplyWithTranslation((float) x, (float) y, (float) z);
+ return this;
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/model/writer/UnsafeModelWriter.java b/src/main/java/com/jozufozu/flywheel/core/materials/model/writer/UnsafeModelWriter.java
index 2b07cebf0..090070cc2 100644
--- a/src/main/java/com/jozufozu/flywheel/core/materials/model/writer/UnsafeModelWriter.java
+++ b/src/main/java/com/jozufozu/flywheel/core/materials/model/writer/UnsafeModelWriter.java
@@ -6,6 +6,7 @@ import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.backend.struct.StructType;
import com.jozufozu.flywheel.backend.struct.UnsafeBufferWriter;
import com.jozufozu.flywheel.core.materials.model.ModelData;
+import com.jozufozu.flywheel.util.WriteUnsafe;
public class UnsafeModelWriter extends UnsafeBufferWriter {
@@ -25,10 +26,9 @@ public class UnsafeModelWriter extends UnsafeBufferWriter {
addr += 6;
- float[] matrices = d.matrices;
- for (int i = 0; i < matrices.length; i++) {
- MemoryUtil.memPutFloat(addr + i * 4L, matrices[i]);
- }
+ ((WriteUnsafe) (Object) d.model).writeUnsafe(addr);
+ addr += 4 * 16;
+ ((WriteUnsafe) (Object) d.normal).writeUnsafe(addr);
advance();
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedData.java b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedData.java
index b43711cf9..850b426a3 100644
--- a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedData.java
+++ b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedData.java
@@ -83,6 +83,15 @@ public class OrientedData extends BasicData {
return this;
}
+ public OrientedData resetRotation() {
+ this.qX = 0;
+ this.qY = 0;
+ this.qZ = 0;
+ this.qW = 1;
+ markDirty();
+ return this;
+ }
+
@Override
public void write(VecBuffer buf) {
super.write(buf);
diff --git a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
index 486499540..7a10218c4 100644
--- a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
+++ b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
@@ -6,6 +6,7 @@ import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.light.LightUpdater;
import com.jozufozu.flywheel.util.ChunkIter;
+import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
@@ -33,6 +34,7 @@ public class ForgeEvents {
public static void unloadWorld(ClientLevel world) {
ChunkIter._unload(world);
+ WorldAttached.invalidateWorld(world);
}
public static void tickLight(Minecraft mc) {
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/fabric/TextureAtlasMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/fabric/TextureAtlasMixin.java
new file mode 100644
index 000000000..ad11b74ea
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/fabric/TextureAtlasMixin.java
@@ -0,0 +1,19 @@
+package com.jozufozu.flywheel.mixin.fabric;
+
+import org.spongepowered.asm.mixin.Mixin;
+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.core.StitchedSprite;
+
+import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.client.renderer.texture.TextureAtlas.Preparations;
+
+@Mixin(TextureAtlas.class)
+public class TextureAtlasMixin {
+ @Inject(method = "reload(Lnet/minecraft/client/renderer/texture/TextureAtlas$Preparations;)V", at = @At("TAIL"))
+ private void onTailReload(Preparations preparations, CallbackInfo ci) {
+ StitchedSprite.onTextureStitchPost((TextureAtlas) (Object) this);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fMixin.java
index cf122e746..42a2e6023 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fMixin.java
@@ -1,15 +1,16 @@
package com.jozufozu.flywheel.mixin.matrix;
-import java.nio.FloatBuffer;
-
+import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
-import com.jozufozu.flywheel.util.Attribute;
+import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
+import com.jozufozu.flywheel.util.WriteSafe;
+import com.jozufozu.flywheel.util.WriteUnsafe;
import com.mojang.math.Matrix3f;
@Mixin(Matrix3f.class)
-public abstract class Matrix3fMixin implements Attribute {
+public abstract class Matrix3fMixin implements WriteUnsafe, WriteSafe {
@Shadow protected float m00;
@Shadow protected float m01;
@@ -22,15 +23,28 @@ public abstract class Matrix3fMixin implements Attribute {
@Shadow protected float m22;
@Override
- public void append(FloatBuffer buffer) {
- buffer.put(m00);
- buffer.put(m10);
- buffer.put(m20);
- buffer.put(m01);
- buffer.put(m11);
- buffer.put(m21);
- buffer.put(m02);
- buffer.put(m12);
- buffer.put(m22);
+ public void writeUnsafe(long addr) {
+ MemoryUtil.memPutFloat(addr, m00);
+ MemoryUtil.memPutFloat(addr += 4L, m10);
+ MemoryUtil.memPutFloat(addr += 4L, m20);
+ MemoryUtil.memPutFloat(addr += 4L, m01);
+ MemoryUtil.memPutFloat(addr += 4L, m11);
+ MemoryUtil.memPutFloat(addr += 4L, m21);
+ MemoryUtil.memPutFloat(addr += 4L, m02);
+ MemoryUtil.memPutFloat(addr += 4L, m12);
+ MemoryUtil.memPutFloat(addr += 4L, m22);
+ }
+
+ @Override
+ public void write(VecBuffer buffer) {
+ buffer.putFloat(m00);
+ buffer.putFloat(m10);
+ buffer.putFloat(m20);
+ buffer.putFloat(m01);
+ buffer.putFloat(m11);
+ buffer.putFloat(m21);
+ buffer.putFloat(m02);
+ buffer.putFloat(m12);
+ buffer.putFloat(m22);
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fMixin.java
index 224c6104f..3650880f9 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fMixin.java
@@ -1,15 +1,16 @@
package com.jozufozu.flywheel.mixin.matrix;
-import java.nio.FloatBuffer;
-
+import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
-import com.jozufozu.flywheel.util.Attribute;
+import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
+import com.jozufozu.flywheel.util.WriteSafe;
+import com.jozufozu.flywheel.util.WriteUnsafe;
import com.mojang.math.Matrix4f;
@Mixin(Matrix4f.class)
-public abstract class Matrix4fMixin implements Attribute {
+public abstract class Matrix4fMixin implements WriteUnsafe, WriteSafe {
@Shadow protected float m00;
@Shadow protected float m01;
@@ -29,22 +30,42 @@ public abstract class Matrix4fMixin implements Attribute {
@Shadow protected float m33;
@Override
- public void append(FloatBuffer buffer) {
- buffer.put(m00);
- buffer.put(m10);
- buffer.put(m20);
- buffer.put(m30);
- buffer.put(m01);
- buffer.put(m11);
- buffer.put(m21);
- buffer.put(m31);
- buffer.put(m02);
- buffer.put(m12);
- buffer.put(m22);
- buffer.put(m32);
- buffer.put(m03);
- buffer.put(m13);
- buffer.put(m23);
- buffer.put(m33);
+ public void writeUnsafe(long addr) {
+ MemoryUtil.memPutFloat(addr, m00);
+ MemoryUtil.memPutFloat(addr += 4L, m10);
+ MemoryUtil.memPutFloat(addr += 4L, m20);
+ MemoryUtil.memPutFloat(addr += 4L, m30);
+ MemoryUtil.memPutFloat(addr += 4L, m01);
+ MemoryUtil.memPutFloat(addr += 4L, m11);
+ MemoryUtil.memPutFloat(addr += 4L, m21);
+ MemoryUtil.memPutFloat(addr += 4L, m31);
+ MemoryUtil.memPutFloat(addr += 4L, m02);
+ MemoryUtil.memPutFloat(addr += 4L, m12);
+ MemoryUtil.memPutFloat(addr += 4L, m22);
+ MemoryUtil.memPutFloat(addr += 4L, m32);
+ MemoryUtil.memPutFloat(addr += 4L, m03);
+ MemoryUtil.memPutFloat(addr += 4L, m13);
+ MemoryUtil.memPutFloat(addr += 4L, m23);
+ MemoryUtil.memPutFloat(addr += 4L, m33);
+ }
+
+ @Override
+ public void write(VecBuffer buf) {
+ buf.putFloat(m00);
+ buf.putFloat(m10);
+ buf.putFloat(m20);
+ buf.putFloat(m30);
+ buf.putFloat(m01);
+ buf.putFloat(m11);
+ buf.putFloat(m21);
+ buf.putFloat(m31);
+ buf.putFloat(m02);
+ buf.putFloat(m12);
+ buf.putFloat(m22);
+ buf.putFloat(m32);
+ buf.putFloat(m03);
+ buf.putFloat(m13);
+ buf.putFloat(m23);
+ buf.putFloat(m33);
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/matrix/PoseStackMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/matrix/PoseStackMixin.java
new file mode 100644
index 000000000..8588b9546
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/matrix/PoseStackMixin.java
@@ -0,0 +1,56 @@
+package com.jozufozu.flywheel.mixin.matrix;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+import com.jozufozu.flywheel.util.transform.TransformStack;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.math.Quaternion;
+
+@Mixin(PoseStack.class)
+public abstract class PoseStackMixin implements TransformStack {
+ @Shadow
+ public abstract void mulPose(Quaternion pQuaternion);
+
+ @Shadow
+ public abstract void shadow$scale(float factorX, float factorY, float factorZ);
+
+ @Shadow
+ public abstract void shadow$pushPose();
+
+ @Shadow
+ public abstract void shadow$popPose();
+
+ @Shadow
+ public abstract void shadow$translate(double x, double y, double z);
+
+ @Override
+ public TransformStack multiply(Quaternion quaternion) {
+ mulPose(quaternion);
+ return this;
+ }
+
+ @Override
+ public TransformStack scale(float factorX, float factorY, float factorZ) {
+ shadow$scale(factorX, factorY, factorZ);
+ return this;
+ }
+
+ @Override
+ public TransformStack pushPose() {
+ shadow$pushPose();
+ return this;
+ }
+
+ @Override
+ public TransformStack popPose() {
+ shadow$popPose();
+ return this;
+ }
+
+ @Override
+ public TransformStack translate(double x, double y, double z) {
+ shadow$translate(x, y, z);
+ return this;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/AngleHelper.java b/src/main/java/com/jozufozu/flywheel/util/AngleHelper.java
index 7dbddb193..a89f8bf87 100644
--- a/src/main/java/com/jozufozu/flywheel/util/AngleHelper.java
+++ b/src/main/java/com/jozufozu/flywheel/util/AngleHelper.java
@@ -5,19 +5,7 @@ import net.minecraft.core.Direction.Axis;
public class AngleHelper {
- /**
- * Legacy method. See {@link #horizontalAngleNew(Direction)} for new method.
- */
public static float horizontalAngle(Direction facing) {
- float angle = facing.toYRot();
- if (facing.getAxis() == Axis.X) angle = -angle;
- return angle;
- }
-
- /**
- * Same as {@link #horizontalAngle(Direction)}, but returns 0 instead of -90 for vertical directions.
- */
- public static float horizontalAngleNew(Direction facing) {
if (facing.getAxis()
.isVertical()) {
return 0;
diff --git a/src/main/java/com/jozufozu/flywheel/util/Attribute.java b/src/main/java/com/jozufozu/flywheel/util/Attribute.java
deleted file mode 100644
index 75739b500..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/Attribute.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.jozufozu.flywheel.util;
-
-import java.nio.FloatBuffer;
-
-public interface Attribute {
-
- /**
- * Append the contents of this object to the given FloatBuffer.
- */
- void append(FloatBuffer buffer);
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/ChunkIter.java b/src/main/java/com/jozufozu/flywheel/util/ChunkIter.java
index 666658a2c..da296f4ca 100644
--- a/src/main/java/com/jozufozu/flywheel/util/ChunkIter.java
+++ b/src/main/java/com/jozufozu/flywheel/util/ChunkIter.java
@@ -31,7 +31,7 @@ public class ChunkIter {
}
}
- // INTERNAL MAINTENENCE METHODS BELOW
+ // INTERNAL MAINTENANCE METHODS BELOW
public static void _putStorageReference(BlockGetter level, AtomicReferenceArray storage) {
storages.put(level, storage);
diff --git a/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java b/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java
index 002ad3d86..408b54e51 100644
--- a/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java
+++ b/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java
@@ -1,6 +1,10 @@
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;
import java.util.function.Consumer;
@@ -12,12 +16,30 @@ import net.minecraft.world.level.LevelAccessor;
public class WorldAttached {
+ // weak references to prevent leaking hashmaps when a WorldAttached is GC'd during runtime
+ static List>> allMaps = new ArrayList<>();
private final Map attached;
private final Function factory;
public WorldAttached(Function factory) {
this.factory = factory;
attached = new HashMap<>();
+ allMaps.add(new WeakReference<>(attached));
+ }
+
+ public static void invalidateWorld(LevelAccessor world) {
+ Iterator>> i = allMaps.iterator();
+ while (i.hasNext()) {
+ Map map = i.next()
+ .get();
+ if (map == null) {
+ // If the map has been GC'd, remove the weak reference
+ i.remove();
+ } else {
+ // Prevent leaks
+ map.remove(world);
+ }
+ }
}
@Nonnull
diff --git a/src/main/java/com/jozufozu/flywheel/util/WriteSafe.java b/src/main/java/com/jozufozu/flywheel/util/WriteSafe.java
new file mode 100644
index 000000000..0fdc7f128
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/util/WriteSafe.java
@@ -0,0 +1,7 @@
+package com.jozufozu.flywheel.util;
+
+import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
+
+public interface WriteSafe {
+ void write(VecBuffer buf);
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/WriteUnsafe.java b/src/main/java/com/jozufozu/flywheel/util/WriteUnsafe.java
new file mode 100644
index 000000000..7d963ee5c
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/util/WriteUnsafe.java
@@ -0,0 +1,9 @@
+package com.jozufozu.flywheel.util;
+
+public interface WriteUnsafe {
+
+ /**
+ * Write the contents of this object into sequential memory starting at the given address.
+ */
+ void writeUnsafe(long addr);
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java b/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java
index 5f8604b9e..2fa562ffa 100644
--- a/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java
+++ b/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java
@@ -15,10 +15,6 @@ public class MatrixTransformStack implements TransformStack {
this.internal = internal;
}
- public static MatrixTransformStack of(PoseStack ms) {
- return new MatrixTransformStack(ms);
- }
-
public PoseStack unwrap() {
return internal;
}
@@ -58,13 +54,13 @@ public class MatrixTransformStack implements TransformStack {
}
@Override
- public TransformStack push() {
+ public TransformStack pushPose() {
internal.pushPose();
return this;
}
@Override
- public TransformStack pop() {
+ public TransformStack popPose() {
internal.popPose();
return this;
}
diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/Rotate.java b/src/main/java/com/jozufozu/flywheel/util/transform/Rotate.java
new file mode 100644
index 000000000..68814740c
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/util/transform/Rotate.java
@@ -0,0 +1,72 @@
+package com.jozufozu.flywheel.util.transform;
+
+import com.mojang.math.Quaternion;
+import com.mojang.math.Vector3f;
+
+import net.minecraft.core.Direction;
+
+public interface Rotate {
+
+ Self multiply(Quaternion quaternion);
+
+ default Self rotate(Direction axis, float radians) {
+ if (radians == 0)
+ return (Self) this;
+ return multiply(axis.step()
+ .rotation(radians));
+ }
+
+ default Self rotate(double angle, Direction.Axis axis) {
+ Vector3f vec =
+ axis == Direction.Axis.X ? Vector3f.XP : axis == Direction.Axis.Y ? Vector3f.YP : Vector3f.ZP;
+ return multiply(vec, angle);
+ }
+
+ default Self rotateX(double angle) {
+ return multiply(Vector3f.XP, angle);
+ }
+
+ default Self rotateY(double angle) {
+ return multiply(Vector3f.YP, angle);
+ }
+
+ default Self rotateZ(double angle) {
+ return multiply(Vector3f.ZP, angle);
+ }
+
+ default Self rotateXRadians(double angle) {
+ return multiplyRadians(Vector3f.XP, angle);
+ }
+
+ default Self rotateYRadians(double angle) {
+ return multiplyRadians(Vector3f.YP, angle);
+ }
+
+ default Self rotateZRadians(double angle) {
+ return multiplyRadians(Vector3f.ZP, angle);
+ }
+
+ default Self multiply(Vector3f axis, double angle) {
+ if (angle == 0)
+ return (Self) this;
+ return multiply(axis.rotationDegrees((float) angle));
+ }
+
+ default Self multiplyRadians(Vector3f axis, double angle) {
+ if (angle == 0)
+ return (Self) this;
+ return multiply(axis.rotation((float) angle));
+ }
+
+ default Self rotateToFace(Direction facing) {
+ switch (facing) {
+ case SOUTH -> multiply(Vector3f.YP.rotationDegrees(180));
+ case WEST -> multiply(Vector3f.YP.rotationDegrees(90));
+ case NORTH -> multiply(Vector3f.YP.rotationDegrees(0));
+ case EAST -> multiply(Vector3f.YP.rotationDegrees(270));
+ case UP -> multiply(Vector3f.XP.rotationDegrees(90));
+ case DOWN -> multiply(Vector3f.XN.rotationDegrees(90));
+ }
+ return (Self) this;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/Scale.java b/src/main/java/com/jozufozu/flywheel/util/transform/Scale.java
new file mode 100644
index 000000000..8fd7e7ab7
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/util/transform/Scale.java
@@ -0,0 +1,9 @@
+package com.jozufozu.flywheel.util.transform;
+
+public interface Scale {
+ Self scale(float factorX, float factorY, float factorZ);
+
+ default Self scale(float factor) {
+ return scale(factor, factor, factor);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/TStack.java b/src/main/java/com/jozufozu/flywheel/util/transform/TStack.java
new file mode 100644
index 000000000..1502fd750
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/util/transform/TStack.java
@@ -0,0 +1,7 @@
+package com.jozufozu.flywheel.util.transform;
+
+public interface TStack {
+ Self pushPose();
+
+ Self popPose();
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/TransformStack.java b/src/main/java/com/jozufozu/flywheel/util/transform/TransformStack.java
index f6cdf2ade..da521b69b 100644
--- a/src/main/java/com/jozufozu/flywheel/util/transform/TransformStack.java
+++ b/src/main/java/com/jozufozu/flywheel/util/transform/TransformStack.java
@@ -1,152 +1,9 @@
package com.jozufozu.flywheel.util.transform;
-import com.mojang.math.Quaternion;
-import com.mojang.math.Vector3f;
+import com.mojang.blaze3d.vertex.PoseStack;
-import net.minecraft.core.Direction;
-import net.minecraft.core.Vec3i;
-import net.minecraft.world.phys.Vec3;
-
-public interface TransformStack {
- Vec3 CENTER = new Vec3(0.5, 0.5, 0.5);
-
- TransformStack translate(double x, double y, double z);
-
- TransformStack multiply(Quaternion quaternion);
-
- TransformStack scale(float factorX, float factorY, float factorZ);
-
- TransformStack push();
-
- TransformStack pop();
-
- default TransformStack scale(float factor) {
- return scale(factor, factor, factor);
- }
-
- default TransformStack rotate(Direction axis, float radians) {
- if (radians == 0)
- return this;
- return multiply(axis.step()
- .rotation(radians));
- }
-
- default TransformStack rotate(double angle, Direction.Axis axis) {
- Vector3f vec =
- axis == Direction.Axis.X ? Vector3f.XP : axis == Direction.Axis.Y ? Vector3f.YP : Vector3f.ZP;
- return multiply(vec, angle);
- }
-
- default TransformStack rotateX(double angle) {
- return multiply(Vector3f.XP, angle);
- }
-
- default TransformStack rotateY(double angle) {
- return multiply(Vector3f.YP, angle);
- }
-
- default TransformStack rotateZ(double angle) {
- return multiply(Vector3f.ZP, angle);
- }
-
- default TransformStack rotateXRadians(double angle) {
- return multiplyRadians(Vector3f.XP, angle);
- }
-
- default TransformStack rotateYRadians(double angle) {
- return multiplyRadians(Vector3f.YP, angle);
- }
-
- default TransformStack rotateZRadians(double angle) {
- return multiplyRadians(Vector3f.ZP, angle);
- }
-
- default TransformStack centre() {
- return translateAll(0.5);
- }
-
- default TransformStack unCentre() {
- return translateAll(-0.5);
- }
-
- default TransformStack translateAll(double v) {
- return translate(v, v, v);
- }
-
- default TransformStack translateX(double x) {
- return translate(x, 0, 0);
- }
-
- default TransformStack translateY(double y) {
- return translate(0, y, 0);
- }
-
- default TransformStack translateZ(double z) {
- return translate(0, 0, z);
- }
-
- default TransformStack translate(Vec3i vec) {
- return translate(vec.getX(), vec.getY(), vec.getZ());
- }
-
- default TransformStack translate(Vec3 vec) {
- return translate(vec.x, vec.y, vec.z);
- }
-
- default TransformStack translate(Vector3f vec) {
- return translate(vec.x(), vec.y(), vec.z());
- }
-
- default TransformStack translateBack(Vec3 vec) {
- return translate(-vec.x, -vec.y, -vec.z);
- }
-
- default TransformStack translateBack(Vec3i vec) {
- return translate(-vec.getX(), -vec.getY(), -vec.getZ());
- }
-
- default TransformStack nudge(int id) {
- long randomBits = (long) id * 31L * 493286711L;
- randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L;
- float xNudge = (((float) (randomBits >> 16 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
- float yNudge = (((float) (randomBits >> 20 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
- float zNudge = (((float) (randomBits >> 24 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
- return translate(xNudge, yNudge, zNudge);
- }
-
- default TransformStack multiply(Vector3f axis, double angle) {
- if (angle == 0)
- return this;
- return multiply(axis.rotationDegrees((float) angle));
- }
-
- default TransformStack multiplyRadians(Vector3f axis, double angle) {
- if (angle == 0)
- return this;
- return multiply(axis.rotation((float) angle));
- }
-
- default TransformStack rotateToFace(Direction facing) {
- switch (facing) {
- case SOUTH:
- multiply(Vector3f.YP.rotationDegrees(180));
- break;
- case WEST:
- multiply(Vector3f.YP.rotationDegrees(90));
- break;
- case NORTH:
- multiply(Vector3f.YP.rotationDegrees(0));
- break;
- case EAST:
- multiply(Vector3f.YP.rotationDegrees(270));
- break;
- case UP:
- multiply(Vector3f.XP.rotationDegrees(90));
- break;
- case DOWN:
- multiply(Vector3f.XN.rotationDegrees(90));
- break;
- }
- return this;
+public interface TransformStack extends Scale, Translate, Rotate, TStack {
+ static TransformStack cast(PoseStack stack) {
+ return (TransformStack) stack;
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/Translate.java b/src/main/java/com/jozufozu/flywheel/util/transform/Translate.java
new file mode 100644
index 000000000..2e3da5a32
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/util/transform/Translate.java
@@ -0,0 +1,67 @@
+package com.jozufozu.flywheel.util.transform;
+
+import com.mojang.math.Vector3f;
+
+import net.minecraft.core.Vec3i;
+import net.minecraft.world.phys.Vec3;
+
+public interface Translate {
+ Self translate(double x, double y, double z);
+
+ default Self centre() {
+ return translateAll(0.5);
+ }
+
+ default Self unCentre() {
+ return translateAll(-0.5);
+ }
+
+ default Self translateAll(double v) {
+ return translate(v, v, v);
+ }
+
+ default Self translateX(double x) {
+ return translate(x, 0, 0);
+ }
+
+ default Self translateY(double y) {
+ return translate(0, y, 0);
+ }
+
+ default Self translateZ(double z) {
+ return translate(0, 0, z);
+ }
+
+ default Self translate(Vec3i vec) {
+ return translate(vec.getX(), vec.getY(), vec.getZ());
+ }
+
+ default Self translate(Vec3 vec) {
+ return translate(vec.x, vec.y, vec.z);
+ }
+
+ default Self translate(Vector3f vec) {
+ return translate(vec.x(), vec.y(), vec.z());
+ }
+
+ default Self translateBack(Vec3 vec) {
+ return translate(-vec.x, -vec.y, -vec.z);
+ }
+
+ default Self translateBack(double x, double y, double z) {
+ return translate(-x, -y, -z);
+ }
+
+ default Self translateBack(Vec3i vec) {
+ return translate(-vec.getX(), -vec.getY(), -vec.getZ());
+ }
+
+ default Self nudge(int id) {
+ long randomBits = (long) id * 31L * 493286711L;
+ randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L;
+ float xNudge = (((float) (randomBits >> 16 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
+ float yNudge = (((float) (randomBits >> 20 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
+ float zNudge = (((float) (randomBits >> 24 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
+ return translate(xNudge, yNudge, zNudge);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
index 3ed6547ec..a11867494 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
@@ -13,7 +13,6 @@ import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
import com.jozufozu.flywheel.core.model.ModelPart;
import com.jozufozu.flywheel.util.AnimationTickHolder;
-import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
@@ -31,7 +30,6 @@ import net.minecraft.world.level.block.state.properties.ChestType;
public class ChestInstance extends TileEntityInstance implements IDynamicInstance {
- private final MatrixTransformStack stack = new MatrixTransformStack();
private final OrientedData body;
private final ModelData lid;
@@ -57,9 +55,6 @@ public class ChestInstance extends TileE
if (block instanceof AbstractChestBlock) {
-// MatrixStack stack = new MatrixStack();
-//
-// stack.push();
float horizontalAngle = blockState.getValue(ChestBlock.FACING).toYRot();
baseRotation = Vector3f.YP.rotationDegrees(-horizontalAngle);
@@ -92,7 +87,7 @@ public class ChestInstance extends TileE
float angleX = -(progress * ((float) Math.PI / 2F));
- stack.setIdentity()
+ lid.loadIdentity()
.translate(getInstancePosition())
.translate(0, 9f/16f, 0)
.centre()
@@ -101,9 +96,6 @@ public class ChestInstance extends TileE
.translate(0, 0, 1f / 16f)
.multiply(Vector3f.XP.rotation(angleX))
.translate(0, 0, -1f / 16f);
-
- lid.setTransform(stack.unwrap());
-
}
@Override
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
index 021c5f069..a7e2ff9ae 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
@@ -111,12 +111,12 @@ public class MinecartInstance extends EntityInstance
int j = entity.getDisplayOffset();
if (contents != null) {
- stack.push();
+ stack.pushPose();
stack.scale(0.75F);
stack.translate(-0.5D, (float)(j - 8) / 16, 0.5D);
stack.multiply(Vector3f.YP.rotationDegrees(90));
contents.setTransform(stack.unwrap());
- stack.pop();
+ stack.popPose();
}
body.setTransform(stack.unwrap());
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
index a77affd6b..5da600a83 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
@@ -24,7 +24,7 @@ public class ShulkerBoxInstance extends TileEntityInstance