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}" : '')
group = 'com.jozufozu.flywheel'
archivesBaseName = 'flywheel'
archivesBaseName = 'flywheel-fabric'
sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16

View file

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

View file

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

View file

@ -40,7 +40,6 @@ public class Backend {
private boolean instancedArrays;
private boolean enabled;
public boolean chunkCachingEnabled;
private final List<IShaderContext<?>> contexts = new ArrayList<>();
private final Map<ResourceLocation, MaterialSpec<?>> 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) {

View file

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

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

View file

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

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;
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<ResourceLocation, SingleAtlasSpriteHolder> 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<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;
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<ModelData>, Rotate<ModelData>, Scale<ModelData> {
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 {
* </p>
*/
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;
}
}

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.UnsafeBufferWriter;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.jozufozu.flywheel.util.WriteUnsafe;
public class UnsafeModelWriter extends UnsafeBufferWriter<ModelData> {
@ -25,10 +26,9 @@ public class UnsafeModelWriter extends UnsafeBufferWriter<ModelData> {
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();
}

View file

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

View file

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

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

View file

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

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 {
/**
* 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;

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) {
storages.put(level, storage);

View file

@ -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<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 Function<LevelAccessor, T> factory;
public WorldAttached(Function<LevelAccessor, T> factory) {
this.factory = factory;
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

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

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;
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<TransformStack>, Translate<TransformStack>, Rotate<TransformStack>, TStack<TransformStack> {
static TransformStack cast(PoseStack stack) {
return (TransformStack) stack;
}
}

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.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<T extends BlockEntity & LidBlockEntity> extends TileEntityInstance<T> implements IDynamicInstance {
private final MatrixTransformStack stack = new MatrixTransformStack();
private final OrientedData body;
private final ModelData lid;
@ -57,9 +55,6 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> 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<T extends BlockEntity & LidBlockEntity> 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<T extends BlockEntity & LidBlockEntity> extends TileE
.translate(0, 0, 1f / 16f)
.multiply(Vector3f.XP.rotation(angleX))
.translate(0, 0, -1f / 16f);
lid.setTransform(stack.unwrap());
}
@Override

View file

@ -111,12 +111,12 @@ public class MinecartInstance<T extends AbstractMinecart> 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());

View file

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

View file

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