Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/19.2/forge' into 18.x/forge
Browse files Browse the repository at this point in the history
  • Loading branch information
embeddedt committed Apr 2, 2024
2 parents f991a1a + 2782125 commit 76c68f1
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 15 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx3G
loader_version=0.13.3

# Mod Properties
mod_version = 0.3.10
mod_version = 0.3.11
maven_group = org.embeddedt
archives_base_name = embeddium

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.extensions.IForgeBlockEntity;
import net.minecraftforge.fml.loading.FMLLoader;

import java.util.Collection;
import java.util.Collections;
Expand All @@ -52,6 +53,8 @@
* Provides an extension to vanilla's {@link LevelRenderer}.
*/
public class SodiumWorldRenderer {
private static final boolean ENABLE_BLOCKENTITY_CULLING = FMLLoader.getLoadingModList().getModFileById("valkyrienskies") == null;

private final Minecraft client;

private ClientLevel world;
Expand Down Expand Up @@ -268,6 +271,9 @@ private void initRenderer(CommandList commandList) {
}

private boolean checkBEVisibility(BlockEntity entity) {
if(!ENABLE_BLOCKENTITY_CULLING) {
return true;
}
AABB box = entity.getRenderBoundingBox();
if(box.equals(IForgeBlockEntity.INFINITE_EXTENT_AABB))
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,13 @@ public void renderChunkLayer(RenderType renderLayer, PoseStack matrices, double
}
Frustum frustrum = this.capturedFrustum != null ? this.capturedFrustum : this.cullingFrustum;
Camera camera = this.minecraft.gameRenderer.getMainCamera();

// TODO: Avoid setting up and clearing the state a second time
renderLayer.setupRenderState();
ForgeHooksClient.dispatchRenderStage(
renderLayer, (LevelRenderer) (Object) this, matrices, matrix, this.ticks, camera, frustrum
);
renderLayer.clearRenderState();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package me.jellysquid.mods.sodium.mixin.features.model;

import com.mojang.math.Vector3f;
import me.jellysquid.mods.sodium.client.SodiumClientMod;
import net.minecraft.client.renderer.block.model.BlockElement;
import org.embeddedt.embeddium.util.PlatformUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;

@Mixin(BlockElement.class)
public class BlockElementMixin {
@ModifyVariable(method = "<init>",
at = @At("HEAD"), argsOnly = true, index = 1)
private static Vector3f epsilonizeFrom(Vector3f vector) {
return embeddium$epsilonize(vector);
}

@ModifyVariable(method = "<init>",
at = @At("HEAD"), argsOnly = true, index = 2)
private static Vector3f epsilonizeTo(Vector3f vector) {
return embeddium$epsilonize(vector);
}

private static Vector3f embeddium$epsilonize(Vector3f v) {
if (v == null || !PlatformUtil.isLoadValid() || !SodiumClientMod.options().performance.useCompactVertexFormat) {
return v;
}
v.setX(embeddium$epsilonize(v.x()));
v.setY(embeddium$epsilonize(v.y()));
v.setZ(embeddium$epsilonize(v.z()));
return v;
}

private static final float EMBEDDIUM$MINIMUM_EPSILON = 0.008f;

private static float embeddium$epsilonize(float f) {
int roundedCoord = Math.round(f);
float difference = f - roundedCoord;
// Ignore components that are integers or far enough away from a texel for epsilonizing to be unnecessary
if(difference == 0 || Math.abs(difference) >= EMBEDDIUM$MINIMUM_EPSILON) {
return f;
} else {
// "Push" the coordinate slightly further away from the texel so z-fighting is less likely
// This maps e.g. 0.001 -> 0.01, which should be enough
return roundedCoord + (difference * 10);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.SimpleBakedModel;
import net.minecraft.client.resources.model.WeightedBakedModel;
import net.minecraft.core.Direction;
import net.minecraft.util.random.WeightedEntry;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.IModelData;

import org.embeddedt.embeddium.model.UnwrappableBakedModel;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -17,7 +18,7 @@
import java.util.*;

@Mixin(WeightedBakedModel.class)
public class MixinWeightedBakedModel {
public class MixinWeightedBakedModel implements UnwrappableBakedModel {
@Shadow
@Final
private List<WeightedEntry.Wrapper<BakedModel>> list;
Expand Down Expand Up @@ -59,4 +60,15 @@ private static <T extends WeightedEntry> T getAt(List<T> pool, int totalWeight)

return weighted;
}

@Override
public @Nullable BakedModel embeddium$getInnerModel(Random rand) {
WeightedEntry.Wrapper<BakedModel> quad = getAt(this.list, Math.abs((int) rand.nextLong()) % this.totalWeight);

if (quad != null && quad.getData().getClass() == SimpleBakedModel.class) {
return quad.getData();
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

import me.jellysquid.mods.sodium.client.render.texture.SpriteExtended;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(TextureAtlasSprite.class)
public abstract class MixinSprite implements SpriteExtended {
@Shadow @Final private float u0;
private boolean active;

@Override
Expand All @@ -17,4 +22,15 @@ public void setActive(boolean active) {
public boolean isActive() {
return this.active;
}

/**
* @author embeddedt
* @reason Mark sprite as active for animation when U0 coordinate is retrieved. This catches some more render
* paths not caught by the other mixins.
*/
@Redirect(method = "getU0", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;u0:F"))
private float embeddium$markActive(TextureAtlasSprite sprite) {
this.active = true;
return this.u0;
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,98 @@
package me.jellysquid.mods.sodium.mixin.features.world_ticking;

import me.jellysquid.mods.sodium.client.util.rand.XoRoShiRoRandom;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Holder;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.AmbientParticleSettings;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.storage.WritableLevelData;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import javax.annotation.Nullable;
import java.util.Optional;

import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Supplier;

// Use a very low priority so most injects into doAnimateTick will still work
@Mixin(value = ClientLevel.class, priority = 500)
public abstract class MixinClientLevel extends Level {
protected MixinClientLevel(WritableLevelData p_204149_, ResourceKey<Level> p_204150_, Holder<DimensionType> p_204151_, Supplier<ProfilerFiller> p_204152_, boolean p_204153_, boolean p_204154_, long p_204155_) {
super(p_204149_, p_204150_, p_204151_, p_204152_, p_204153_, p_204154_, p_204155_);
}

@Mixin(ClientLevel.class)
public class MixinClientLevel {
@Shadow
private void lambda$doAnimateTick$8(BlockPos.MutableBlockPos pos, AmbientParticleSettings settings) {
throw new AssertionError();
}

@Shadow
protected abstract void trySpawnDripParticles(BlockPos p_104690_, BlockState p_104691_, ParticleOptions p_104692_, boolean p_104693_);

/**
* @author embeddedt
* @reason Avoid allocating a capturing lambda for each ticked block position. The original allocated method arg
* is discarded by the JIT.
* @reason Use singlethreaded random to avoid AtomicLong overhead
*/
@Redirect(method = "doAnimateTick", at = @At(value = "INVOKE", target = "Ljava/util/Optional;ifPresent(Ljava/util/function/Consumer;)V"))
private void addBiomeParticleWithoutAlloc(Optional<AmbientParticleSettings> particleSettings, Consumer<AmbientParticleSettings> allocatedLambda, int p_233613_, int p_233614_, int p_233615_, int p_233616_, Random p_233617_, @Nullable Block p_233618_, BlockPos.MutableBlockPos p_233619_) {
//noinspection OptionalIsPresent
if(particleSettings.isPresent()) {
lambda$doAnimateTick$8(p_233619_, particleSettings.get());
@Redirect(method = "animateTick", at = @At(value = "NEW", target = "()Ljava/util/Random;"))
private Random createLocal() {
return new XoRoShiRoRandom();
}

/**
* @author embeddedt
* @reason Avoid allocations & do some misc optimizations. Partially based on old Sodium 0.2 mixin
*/
@Overwrite
public void doAnimateTick(int xCenter, int yCenter, int zCenter, int radius, Random random, @Nullable Block markerBlock, BlockPos.MutableBlockPos pos) {
int x = xCenter + (random.nextInt(radius) - random.nextInt(radius));
int y = yCenter + (random.nextInt(radius) - random.nextInt(radius));
int z = zCenter + (random.nextInt(radius) - random.nextInt(radius));

pos.set(x, y, z);

BlockState blockState = this.getBlockState(pos);

if (!blockState.isAir()) {
blockState.getBlock().animateTick(blockState, this, pos, random);
}

FluidState fluidState = blockState.getFluidState();

if (!fluidState.isEmpty()) {
fluidState.animateTick(this, pos, random);
ParticleOptions particleoptions = fluidState.getDripParticle();
if (particleoptions != null && random.nextInt(10) == 0) {
boolean flag = blockState.isFaceSturdy(this, pos, Direction.DOWN);
BlockPos blockpos = pos.below();
this.trySpawnDripParticles(blockpos, this.getBlockState(blockpos), particleoptions, flag);
}
}

if (blockState.getBlock() == markerBlock) {
this.addParticle(new BlockParticleOption(ParticleTypes.BLOCK_MARKER, blockState), (double)x + 0.5D, (double)y + 0.5D, (double)z + 0.5D, 0.0D, 0.0D, 0.0D);
}

if (!blockState.isCollisionShapeFullBlock(this, pos)) {
var particleOpt = this.getBiome(pos).value().getAmbientParticle();

//noinspection OptionalIsPresent
if(particleOpt.isPresent()) {
lambda$doAnimateTick$8(pos, particleOpt.get());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.embeddedt.embeddium.model;

import net.minecraft.client.resources.model.BakedModel;
import org.jetbrains.annotations.Nullable;

import java.util.Random;

/**
* Represents a model that may be "unwrapped" given sufficient context.
*/
public interface UnwrappableBakedModel {
/**
* Return the "inner model" of this model. Note that any calls made to the inner model will not have the RandomSource
* adjusted to accommodate any changes the wrapping model would normally be making to it. As such, you should
* only return a non-null value if the RandomSource is not used by the inner model.
*/
@Nullable BakedModel embeddium$getInnerModel(Random rand);

static BakedModel unwrapIfPossible(BakedModel incoming, Random rand) {
if(incoming instanceof UnwrappableBakedModel) {
BakedModel m = ((UnwrappableBakedModel)incoming).embeddium$getInnerModel(rand);
if(m != null) {
return m;
}
}
return incoming;
}
}
9 changes: 9 additions & 0 deletions src/main/java/org/embeddedt/embeddium/util/PlatformUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.embeddedt.embeddium.util;

import net.minecraftforge.fml.loading.FMLLoader;

public class PlatformUtil {
public static boolean isLoadValid() {
return FMLLoader.getLoadingModList().getErrors().isEmpty();
}
}
4 changes: 4 additions & 0 deletions src/main/resources/assets/embeddium/lang/de_de.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"embeddium.conflicting_mod": "Embeddium hat die Mods erkannt, die Renderingprobleme/Abstürze verursachen mögen. Es wird empfohlen, sie zu deinstallieren. Schau dir die Liste unten an.",
"embeddium.conflicting_mod_list": "[{2}]"
}

0 comments on commit 76c68f1

Please sign in to comment.