Merge remote-tracking branch 'origin/1.17/dev' into 1.17/fabric/dev

Conflicts:
	gradle.properties
	src/main/java/com/jozufozu/flywheel/FlywheelClient.java
	src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java
	src/main/java/com/jozufozu/flywheel/config/BooleanDirective.java
	src/main/java/com/jozufozu/flywheel/config/FlwCommands.java
	src/main/java/com/jozufozu/flywheel/config/FlwConfig.java
	src/main/java/com/jozufozu/flywheel/config/SConfigureBooleanPacket.java
	src/main/java/com/jozufozu/flywheel/core/AtlasStitcher.java
	src/main/resources/flywheel.mixins.json
This commit is contained in:
PepperBell 2021-11-24 20:53:22 -08:00
commit 7a4d875061
33 changed files with 505 additions and 333 deletions

View file

@ -11,7 +11,7 @@ project.buildnumber = System.getenv('BUILD_NUMBER') != null ? System.getenv('BUI
version = "${mc_update_version}-${mod_version}" + (dev ? ".${buildnumber}" : '') version = "${mc_update_version}-${mod_version}" + (dev ? ".${buildnumber}" : '')
group = 'com.jozufozu.flywheel' group = 'com.jozufozu.flywheel'
archivesBaseName = 'flywheel' archivesBaseName = 'flywheel-fabric'
sourceCompatibility = JavaVersion.VERSION_16 sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16 targetCompatibility = JavaVersion.VERSION_16

View file

@ -6,7 +6,7 @@ mod_version = 0.3.0
mc_update_version = 1.17 mc_update_version = 1.17
minecraft_version = 1.17.1 minecraft_version = 1.17.1
loader_version = 0.12.5 loader_version = 0.12.5
fabric_version = 0.42.1+1.17 fabric_version = 0.43.0+1.17
# build dependency versions # build dependency versions
loom_version = 0.10-SNAPSHOT loom_version = 0.10-SNAPSHOT

View file

@ -5,7 +5,6 @@ import com.jozufozu.flywheel.backend.Loader;
import com.jozufozu.flywheel.backend.RenderWork; import com.jozufozu.flywheel.backend.RenderWork;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.config.FlwConfig; import com.jozufozu.flywheel.config.FlwConfig;
import com.jozufozu.flywheel.core.AtlasStitcher;
import com.jozufozu.flywheel.core.Contexts; import com.jozufozu.flywheel.core.Contexts;
import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.PartialModel; 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.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry; import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; 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.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.PackType;
import net.minecraft.world.inventory.InventoryMenu;
public class FlywheelClient implements ClientModInitializer { public class FlywheelClient implements ClientModInitializer {
@ -33,8 +30,6 @@ public class FlywheelClient implements ClientModInitializer {
Backend.init(); Backend.init();
ClientSpriteRegistryCallback.event(InventoryMenu.BLOCK_ATLAS).register(AtlasStitcher.getInstance()::onTextureStitch);
FlywheelEvents.GATHER_CONTEXT.register(Contexts::flwInit); FlywheelEvents.GATHER_CONTEXT.register(Contexts::flwInit);
FlywheelEvents.GATHER_CONTEXT.register(Materials::flwInit); FlywheelEvents.GATHER_CONTEXT.register(Materials::flwInit);
ModelLoadingRegistry.INSTANCE.registerModelProvider(PartialModel::onModelRegistry); ModelLoadingRegistry.INSTANCE.registerModelProvider(PartialModel::onModelRegistry);

View file

@ -40,7 +40,6 @@ public class Backend {
private boolean instancedArrays; private boolean instancedArrays;
private boolean enabled; private boolean enabled;
public boolean chunkCachingEnabled;
private final List<IShaderContext<?>> contexts = new ArrayList<>(); private final List<IShaderContext<?>> contexts = new ArrayList<>();
private final Map<ResourceLocation, MaterialSpec<?>> materialRegistry = new HashMap<>(); private final Map<ResourceLocation, MaterialSpec<?>> materialRegistry = new HashMap<>();
@ -138,8 +137,6 @@ public class Backend {
enabled = FlwConfig.get() enabled = FlwConfig.get()
.enabled() && !OptifineHandler.usingShaders(); .enabled() && !OptifineHandler.usingShaders();
chunkCachingEnabled = FlwConfig.get()
.chunkCaching();
} }
public boolean canUseInstancing(@Nullable Level world) { public boolean canUseInstancing(@Nullable Level world) {

View file

@ -22,6 +22,7 @@ public class InstancedRenderDispatcher {
* @param te The tile whose instance you want to update. * @param te The tile whose instance you want to update.
*/ */
public static void enqueueUpdate(BlockEntity te) { public static void enqueueUpdate(BlockEntity te) {
if (te.hasLevel() && te.getLevel() instanceof ClientLevel)
getTiles(te.getLevel()).queueUpdate(te); getTiles(te.getLevel()).queueUpdate(te);
} }

View file

@ -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(); commandBuilder.build();
} }

View file

@ -38,8 +38,6 @@ public class FlwConfig {
public final BooleanOption enabled = addOption(new BooleanOption("enabled", true)); public final BooleanOption enabled = addOption(new BooleanOption("enabled", true));
/** Enable or disable a debug overlay that colors pixels by their normal */ /** Enable or disable a debug overlay that colors pixels by their normal */
public final BooleanOption debugNormals = addOption(new BooleanOption("debugNormals", false)); 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) { public FlwConfig(File file) {
this.file = file; this.file = file;
@ -62,10 +60,6 @@ public class FlwConfig {
return debugNormals.get(); return debugNormals.get();
} }
public boolean chunkCaching() {
return chunkCaching.get();
}
public void load() { public void load() {
if (file.exists()) { if (file.exists()) {
try (FileReader reader = new FileReader(file)) { try (FileReader reader = new FileReader(file)) {

View file

@ -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<StitchedSprite> 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);
}
}

View file

@ -1,35 +1,81 @@
package com.jozufozu.flywheel.core; 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.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.InventoryMenu;
public class StitchedSprite { public class StitchedSprite {
private static final Map<ResourceLocation, SingleAtlasSpriteHolder> ALL = new HashMap<>();
private final ResourceLocation loc; protected final ResourceLocation atlasLocation;
protected final ResourceLocation location;
protected TextureAtlasSprite sprite;
TextureAtlasSprite sprite; public StitchedSprite(ResourceLocation atlas, ResourceLocation location) {
atlasLocation = atlas;
StitchedSprite(ResourceLocation loc) { this.location = location;
this.loc = loc; ALL.computeIfAbsent(atlasLocation, SingleAtlasSpriteHolder::new).add(this);
} }
public ResourceLocation getLoc() { public StitchedSprite(ResourceLocation location) {
return loc; this(InventoryMenu.BLOCK_ATLAS, location);
} }
public TextureAtlasSprite getSprite() { public static void onTextureStitchPost(TextureAtlas atlas) {
if (sprite == null) { ResourceLocation atlasLocation = atlas.location();
sprite = Minecraft.getInstance() SingleAtlasSpriteHolder holder = ALL.get(atlasLocation);
.getTextureAtlas(InventoryMenu.BLOCK_ATLAS) if (holder != null) {
.apply(loc); 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; return sprite;
} }
void reset() { private static class SingleAtlasSpriteHolder implements ClientSpriteRegistryCallback {
sprite = null; private final ResourceLocation atlasLocation;
private final List<StitchedSprite> 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);
}
}
} }
} }

View file

@ -1,24 +1,27 @@
package com.jozufozu.flywheel.core.materials.model; package com.jozufozu.flywheel.core.materials.model;
import java.nio.FloatBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.core.materials.BasicData; 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.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Quaternion;
public class ModelData extends BasicData { import net.minecraft.util.Mth;
private static final float[] empty = new float[25];
public final float[] matrices = empty.clone(); public class ModelData extends BasicData implements Translate<ModelData>, Rotate<ModelData>, Scale<ModelData> {
private final FloatBuffer wrap = FloatBuffer.wrap(matrices); public final Matrix4f model = new Matrix4f();
public final Matrix3f normal = new Matrix3f();
public ModelData setTransform(PoseStack stack) { 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(); markDirty();
this.model.load(stack.last().pose());
this.normal.load(stack.last().normal());
return this; return this;
} }
@ -30,15 +33,63 @@ public class ModelData extends BasicData {
* </p> * </p>
*/ */
public ModelData setEmptyTransform() { public ModelData setEmptyTransform() {
this.wrap.position(0)
.put(empty);
markDirty(); 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; return this;
} }
@Override @Override
public void write(VecBuffer buf) { public void write(VecBuffer buf) {
super.write(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;
} }
} }

View file

@ -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.StructType;
import com.jozufozu.flywheel.backend.struct.UnsafeBufferWriter; import com.jozufozu.flywheel.backend.struct.UnsafeBufferWriter;
import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.jozufozu.flywheel.util.WriteUnsafe;
public class UnsafeModelWriter extends UnsafeBufferWriter<ModelData> { public class UnsafeModelWriter extends UnsafeBufferWriter<ModelData> {
@ -25,10 +26,9 @@ public class UnsafeModelWriter extends UnsafeBufferWriter<ModelData> {
addr += 6; addr += 6;
float[] matrices = d.matrices; ((WriteUnsafe) (Object) d.model).writeUnsafe(addr);
for (int i = 0; i < matrices.length; i++) { addr += 4 * 16;
MemoryUtil.memPutFloat(addr + i * 4L, matrices[i]); ((WriteUnsafe) (Object) d.normal).writeUnsafe(addr);
}
advance(); advance();
} }

View file

@ -83,6 +83,15 @@ public class OrientedData extends BasicData {
return this; return this;
} }
public OrientedData resetRotation() {
this.qX = 0;
this.qY = 0;
this.qZ = 0;
this.qW = 1;
markDirty();
return this;
}
@Override @Override
public void write(VecBuffer buf) { public void write(VecBuffer buf) {
super.write(buf); super.write(buf);

View file

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.light.LightUpdater; import com.jozufozu.flywheel.light.LightUpdater;
import com.jozufozu.flywheel.util.ChunkIter; import com.jozufozu.flywheel.util.ChunkIter;
import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
@ -33,6 +34,7 @@ public class ForgeEvents {
public static void unloadWorld(ClientLevel world) { public static void unloadWorld(ClientLevel world) {
ChunkIter._unload(world); ChunkIter._unload(world);
WorldAttached.invalidateWorld(world);
} }
public static void tickLight(Minecraft mc) { public static void tickLight(Minecraft mc) {

View file

@ -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);
}
}

View file

@ -1,15 +1,16 @@
package com.jozufozu.flywheel.mixin.matrix; 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.Mixin;
import org.spongepowered.asm.mixin.Shadow; 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; import com.mojang.math.Matrix3f;
@Mixin(Matrix3f.class) @Mixin(Matrix3f.class)
public abstract class Matrix3fMixin implements Attribute { public abstract class Matrix3fMixin implements WriteUnsafe, WriteSafe {
@Shadow protected float m00; @Shadow protected float m00;
@Shadow protected float m01; @Shadow protected float m01;
@ -22,15 +23,28 @@ public abstract class Matrix3fMixin implements Attribute {
@Shadow protected float m22; @Shadow protected float m22;
@Override @Override
public void append(FloatBuffer buffer) { public void writeUnsafe(long addr) {
buffer.put(m00); MemoryUtil.memPutFloat(addr, m00);
buffer.put(m10); MemoryUtil.memPutFloat(addr += 4L, m10);
buffer.put(m20); MemoryUtil.memPutFloat(addr += 4L, m20);
buffer.put(m01); MemoryUtil.memPutFloat(addr += 4L, m01);
buffer.put(m11); MemoryUtil.memPutFloat(addr += 4L, m11);
buffer.put(m21); MemoryUtil.memPutFloat(addr += 4L, m21);
buffer.put(m02); MemoryUtil.memPutFloat(addr += 4L, m02);
buffer.put(m12); MemoryUtil.memPutFloat(addr += 4L, m12);
buffer.put(m22); 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);
} }
} }

View file

@ -1,15 +1,16 @@
package com.jozufozu.flywheel.mixin.matrix; 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.Mixin;
import org.spongepowered.asm.mixin.Shadow; 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; import com.mojang.math.Matrix4f;
@Mixin(Matrix4f.class) @Mixin(Matrix4f.class)
public abstract class Matrix4fMixin implements Attribute { public abstract class Matrix4fMixin implements WriteUnsafe, WriteSafe {
@Shadow protected float m00; @Shadow protected float m00;
@Shadow protected float m01; @Shadow protected float m01;
@ -29,22 +30,42 @@ public abstract class Matrix4fMixin implements Attribute {
@Shadow protected float m33; @Shadow protected float m33;
@Override @Override
public void append(FloatBuffer buffer) { public void writeUnsafe(long addr) {
buffer.put(m00); MemoryUtil.memPutFloat(addr, m00);
buffer.put(m10); MemoryUtil.memPutFloat(addr += 4L, m10);
buffer.put(m20); MemoryUtil.memPutFloat(addr += 4L, m20);
buffer.put(m30); MemoryUtil.memPutFloat(addr += 4L, m30);
buffer.put(m01); MemoryUtil.memPutFloat(addr += 4L, m01);
buffer.put(m11); MemoryUtil.memPutFloat(addr += 4L, m11);
buffer.put(m21); MemoryUtil.memPutFloat(addr += 4L, m21);
buffer.put(m31); MemoryUtil.memPutFloat(addr += 4L, m31);
buffer.put(m02); MemoryUtil.memPutFloat(addr += 4L, m02);
buffer.put(m12); MemoryUtil.memPutFloat(addr += 4L, m12);
buffer.put(m22); MemoryUtil.memPutFloat(addr += 4L, m22);
buffer.put(m32); MemoryUtil.memPutFloat(addr += 4L, m32);
buffer.put(m03); MemoryUtil.memPutFloat(addr += 4L, m03);
buffer.put(m13); MemoryUtil.memPutFloat(addr += 4L, m13);
buffer.put(m23); MemoryUtil.memPutFloat(addr += 4L, m23);
buffer.put(m33); 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);
} }
} }

View file

@ -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;
}
}

View file

@ -5,19 +5,7 @@ import net.minecraft.core.Direction.Axis;
public class AngleHelper { public class AngleHelper {
/**
* Legacy method. See {@link #horizontalAngleNew(Direction)} for new method.
*/
public static float horizontalAngle(Direction facing) { 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() if (facing.getAxis()
.isVertical()) { .isVertical()) {
return 0; return 0;

View file

@ -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);
}

View file

@ -31,7 +31,7 @@ public class ChunkIter {
} }
} }
// INTERNAL MAINTENENCE METHODS BELOW // INTERNAL MAINTENANCE METHODS BELOW
public static void _putStorageReference(BlockGetter level, AtomicReferenceArray<LevelChunk> storage) { public static void _putStorageReference(BlockGetter level, AtomicReferenceArray<LevelChunk> storage) {
storages.put(level, storage); storages.put(level, storage);

View file

@ -1,6 +1,10 @@
package com.jozufozu.flywheel.util; package com.jozufozu.flywheel.util;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -12,12 +16,30 @@ import net.minecraft.world.level.LevelAccessor;
public class WorldAttached<T> { public class WorldAttached<T> {
// weak references to prevent leaking hashmaps when a WorldAttached is GC'd during runtime
static List<WeakReference<Map<LevelAccessor, ?>>> allMaps = new ArrayList<>();
private final Map<LevelAccessor, T> attached; private final Map<LevelAccessor, T> attached;
private final Function<LevelAccessor, T> factory; private final Function<LevelAccessor, T> factory;
public WorldAttached(Function<LevelAccessor, T> factory) { public WorldAttached(Function<LevelAccessor, T> factory) {
this.factory = factory; this.factory = factory;
attached = new HashMap<>(); attached = new HashMap<>();
allMaps.add(new WeakReference<>(attached));
}
public static void invalidateWorld(LevelAccessor world) {
Iterator<WeakReference<Map<LevelAccessor, ?>>> i = allMaps.iterator();
while (i.hasNext()) {
Map<LevelAccessor, ?> 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 @Nonnull

View file

@ -0,0 +1,7 @@
package com.jozufozu.flywheel.util;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
public interface WriteSafe {
void write(VecBuffer buf);
}

View file

@ -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);
}

View file

@ -15,10 +15,6 @@ public class MatrixTransformStack implements TransformStack {
this.internal = internal; this.internal = internal;
} }
public static MatrixTransformStack of(PoseStack ms) {
return new MatrixTransformStack(ms);
}
public PoseStack unwrap() { public PoseStack unwrap() {
return internal; return internal;
} }
@ -58,13 +54,13 @@ public class MatrixTransformStack implements TransformStack {
} }
@Override @Override
public TransformStack push() { public TransformStack pushPose() {
internal.pushPose(); internal.pushPose();
return this; return this;
} }
@Override @Override
public TransformStack pop() { public TransformStack popPose() {
internal.popPose(); internal.popPose();
return this; return this;
} }

View file

@ -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> {
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;
}
}

View file

@ -0,0 +1,9 @@
package com.jozufozu.flywheel.util.transform;
public interface Scale<Self> {
Self scale(float factorX, float factorY, float factorZ);
default Self scale(float factor) {
return scale(factor, factor, factor);
}
}

View file

@ -0,0 +1,7 @@
package com.jozufozu.flywheel.util.transform;
public interface TStack<Self> {
Self pushPose();
Self popPose();
}

View file

@ -1,152 +1,9 @@
package com.jozufozu.flywheel.util.transform; package com.jozufozu.flywheel.util.transform;
import com.mojang.math.Quaternion; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import net.minecraft.core.Direction; public interface TransformStack extends Scale<TransformStack>, Translate<TransformStack>, Rotate<TransformStack>, TStack<TransformStack> {
import net.minecraft.core.Vec3i; static TransformStack cast(PoseStack stack) {
import net.minecraft.world.phys.Vec3; return (TransformStack) stack;
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;
} }
} }

View file

@ -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> {
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);
}
}

View file

@ -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.materials.oriented.OrientedData;
import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.core.model.ModelPart;
import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
import com.mojang.math.Quaternion; import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f; import com.mojang.math.Vector3f;
@ -31,7 +30,6 @@ import net.minecraft.world.level.block.state.properties.ChestType;
public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileEntityInstance<T> implements IDynamicInstance { public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileEntityInstance<T> implements IDynamicInstance {
private final MatrixTransformStack stack = new MatrixTransformStack();
private final OrientedData body; private final OrientedData body;
private final ModelData lid; private final ModelData lid;
@ -57,9 +55,6 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileE
if (block instanceof AbstractChestBlock) { if (block instanceof AbstractChestBlock) {
// MatrixStack stack = new MatrixStack();
//
// stack.push();
float horizontalAngle = blockState.getValue(ChestBlock.FACING).toYRot(); float horizontalAngle = blockState.getValue(ChestBlock.FACING).toYRot();
baseRotation = Vector3f.YP.rotationDegrees(-horizontalAngle); baseRotation = Vector3f.YP.rotationDegrees(-horizontalAngle);
@ -92,7 +87,7 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileE
float angleX = -(progress * ((float) Math.PI / 2F)); float angleX = -(progress * ((float) Math.PI / 2F));
stack.setIdentity() lid.loadIdentity()
.translate(getInstancePosition()) .translate(getInstancePosition())
.translate(0, 9f/16f, 0) .translate(0, 9f/16f, 0)
.centre() .centre()
@ -101,9 +96,6 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileE
.translate(0, 0, 1f / 16f) .translate(0, 0, 1f / 16f)
.multiply(Vector3f.XP.rotation(angleX)) .multiply(Vector3f.XP.rotation(angleX))
.translate(0, 0, -1f / 16f); .translate(0, 0, -1f / 16f);
lid.setTransform(stack.unwrap());
} }
@Override @Override

View file

@ -111,12 +111,12 @@ public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance
int j = entity.getDisplayOffset(); int j = entity.getDisplayOffset();
if (contents != null) { if (contents != null) {
stack.push(); stack.pushPose();
stack.scale(0.75F); stack.scale(0.75F);
stack.translate(-0.5D, (float)(j - 8) / 16, 0.5D); stack.translate(-0.5D, (float)(j - 8) / 16, 0.5D);
stack.multiply(Vector3f.YP.rotationDegrees(90)); stack.multiply(Vector3f.YP.rotationDegrees(90));
contents.setTransform(stack.unwrap()); contents.setTransform(stack.unwrap());
stack.pop(); stack.popPose();
} }
body.setTransform(stack.unwrap()); body.setTransform(stack.unwrap());

View file

@ -24,7 +24,7 @@ public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxBlockEntity
private final ModelData base; private final ModelData base;
private final ModelData lid; private final ModelData lid;
private final MatrixTransformStack stack; private final MatrixTransformStack stack = new MatrixTransformStack();
private float lastProgress = Float.NaN; private float lastProgress = Float.NaN;
@ -39,8 +39,6 @@ public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxBlockEntity
} }
Quaternion rotation = getDirection().getRotation(); Quaternion rotation = getDirection().getRotation();
stack = new MatrixTransformStack();
stack.translate(getInstancePosition()) stack.translate(getInstancePosition())
.scale(0.9995f) .scale(0.9995f)
.translateAll(0.00025) .translateAll(0.00025)
@ -64,7 +62,7 @@ public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxBlockEntity
Quaternion spin = Vector3f.YP.rotationDegrees(270.0F * progress); Quaternion spin = Vector3f.YP.rotationDegrees(270.0F * progress);
stack.push() stack.pushPose()
.centre() .centre()
.multiply(spin) .multiply(spin)
.unCentre() .unCentre()
@ -72,7 +70,7 @@ public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxBlockEntity
lid.setTransform(stack.unwrap()); lid.setTransform(stack.unwrap());
stack.pop(); stack.popPose();
} }
@Override @Override

View file

@ -4,12 +4,6 @@
"package": "com.jozufozu.flywheel.mixin", "package": "com.jozufozu.flywheel.mixin",
"compatibilityLevel": "JAVA_16", "compatibilityLevel": "JAVA_16",
"client": [ "client": [
"atlas.AtlasDataMixin",
"atlas.SheetDataAccessor",
"light.LightUpdateMixin",
"light.NetworkLightUpdateMixin",
"matrix.Matrix3fMixin",
"matrix.Matrix4fMixin",
"CancelEntityRenderMixin", "CancelEntityRenderMixin",
"ChunkRebuildHooksMixin", "ChunkRebuildHooksMixin",
"FixFabulousDepthMixin", "FixFabulousDepthMixin",
@ -20,13 +14,21 @@
"PausedPartialTickAccessor", "PausedPartialTickAccessor",
"RenderHooksMixin", "RenderHooksMixin",
"ShaderCloseMixin", "ShaderCloseMixin",
"ShaderInstanceMixin" "ShaderInstanceMixin",
"atlas.AtlasDataMixin",
"atlas.SheetDataAccessor",
"light.LightUpdateMixin",
"light.NetworkLightUpdateMixin",
"matrix.Matrix3fMixin",
"matrix.Matrix4fMixin",
"matrix.PoseStackMixin"
, ,
"fabric.BufferBuilderAccessor", "fabric.BufferBuilderAccessor",
"fabric.ClientLevelMixin", "fabric.ClientLevelMixin",
"fabric.DebugScreenOverlayMixin", "fabric.DebugScreenOverlayMixin",
"fabric.Matrix4fMixin", "fabric.Matrix4fMixin",
"fabric.MinecraftMixin", "fabric.MinecraftMixin",
"fabric.TextureAtlasMixin",
"fabric.VertexFormatAccessor" "fabric.VertexFormatAccessor"
], ],
"injectors": { "injectors": {