[WIP] start 1.15 port
reorganize packages to match Fabric version use util classes from Fabric version
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm").version("1.3.61")
|
kotlin("jvm").version("1.3.61")
|
||||||
id("net.minecraftforge.gradle").version("3.0.157")
|
id("net.minecraftforge.gradle").version("3.0.194")
|
||||||
id("org.spongepowered.mixin").version("0.7-SNAPSHOT")
|
id("org.spongepowered.mixin").version("0.7-SNAPSHOT")
|
||||||
}
|
}
|
||||||
apply(plugin = "org.spongepowered.mixin")
|
apply(plugin = "org.spongepowered.mixin")
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ jarName = BetterFoliage-Forge
|
|||||||
|
|
||||||
version = 2.5.1
|
version = 2.5.1
|
||||||
|
|
||||||
mcVersion = 1.14.4
|
mcVersion = 1.15.2
|
||||||
forgeVersion = 28.2.0
|
forgeVersion = 31.2.0
|
||||||
mappingsChannel = snapshot
|
mappingsChannel = snapshot
|
||||||
mappingsVersion = 20190719-1.14.3
|
mappingsVersion = 20200514-1.15.1
|
||||||
|
|
||||||
kottleVersion = 1.4.0
|
kottleVersion = 1.4.0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.client.Hooks;
|
import mods.betterfoliage.Hooks;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
@@ -21,8 +21,9 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
public class MixinBlock {
|
public class MixinBlock {
|
||||||
private static final String shouldSideBeRendered = "Lnet/minecraft/block/Block;shouldSideBeRendered(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Z";
|
private static final String shouldSideBeRendered = "Lnet/minecraft/block/Block;shouldSideBeRendered(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Z";
|
||||||
private static final String getVoxelShape = "Lnet/minecraft/block/BlockState;func_215702_a(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
private static final String getVoxelShape = "Lnet/minecraft/block/BlockState;func_215702_a(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
||||||
|
private static final String getFaceOcclusionShape = "Lnet/minecraft/block/BlockState;getFaceOcclusionShape(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
||||||
|
|
||||||
@Redirect(method = shouldSideBeRendered, at = @At(value = "INVOKE", target = getVoxelShape, ordinal = 1))
|
@Redirect(method = shouldSideBeRendered, at = @At(value = "INVOKE", target = getFaceOcclusionShape, ordinal = 1))
|
||||||
private static VoxelShape getVoxelShapeOverride(BlockState state, IBlockReader reader, BlockPos pos, Direction dir) {
|
private static VoxelShape getVoxelShapeOverride(BlockState state, IBlockReader reader, BlockPos pos, Direction dir) {
|
||||||
return Hooks.getVoxelShapeOverride(state, reader, pos, dir);
|
return Hooks.getVoxelShapeOverride(state, reader, pos, dir);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.client.Hooks;
|
import mods.betterfoliage.Hooks;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -15,13 +15,13 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
* Needed to avoid excessive darkening of Round Logs at the corners, now that they are not full blocks.
|
* Needed to avoid excessive darkening of Round Logs at the corners, now that they are not full blocks.
|
||||||
*/
|
*/
|
||||||
@Mixin(BlockState.class)
|
@Mixin(BlockState.class)
|
||||||
@SuppressWarnings({"UnnecessaryQualifiedMemberReference", "deprecation"})
|
@SuppressWarnings({"deprecation"})
|
||||||
public class MixinBlockState {
|
public class MixinBlockState {
|
||||||
private static final String callFrom = "Lnet/minecraft/block/BlockState;func_215703_d(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
private static final String callFrom = "Lnet/minecraft/block/BlockState;getAmbientOcclusionLightValue(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
||||||
private static final String callTo = "Lnet/minecraft/block/Block;func_220080_a(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
private static final String callTo = "Lnet/minecraft/block/Block;getAmbientOcclusionLightValue(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
||||||
|
|
||||||
@Redirect(method = callFrom, at = @At(value = "INVOKE", target = callTo))
|
@Redirect(method = callFrom, at = @At(value = "INVOKE", target = callTo))
|
||||||
float getAmbientOcclusionValue(Block block, BlockState state, IBlockReader reader, BlockPos pos) {
|
float getAmbientOcclusionValue(Block block, BlockState state, IBlockReader reader, BlockPos pos) {
|
||||||
return Hooks.getAmbientOcclusionLightValueOverride(block.func_220080_a(state, reader, pos), state);
|
return Hooks.getAmbientOcclusionLightValueOverride(block.getAmbientOcclusionLightValue(state, reader, pos), state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.client.Hooks;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
|
import mods.betterfoliage.Hooks;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.chunk.ChunkRender;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IEnviromentBlockReader;
|
import net.minecraft.world.ILightReader;
|
||||||
import net.minecraftforge.client.MinecraftForgeClient;
|
import net.minecraftforge.client.MinecraftForgeClient;
|
||||||
import net.minecraftforge.client.model.data.IModelData;
|
import net.minecraftforge.client.model.data.IModelData;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -15,14 +15,13 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@Mixin(ChunkRender.class)
|
@Mixin(targets = {"net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$ChunkRender$RebuildTask"})
|
||||||
public class MixinChunkRender {
|
public class MixinChunkRender {
|
||||||
|
|
||||||
private static final String rebuildChunk = "rebuildChunk(FFFLnet/minecraft/client/renderer/chunk/ChunkRenderTask;)V";
|
private static final String compile = "Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$RebuildTask;compile(FFFLnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$CompiledChunk;Lnet/minecraft/client/renderer/RegionRenderCacheBuilder;)Ljava/util/Set;";
|
||||||
private static final String renderBlock = "Lnet/minecraft/client/renderer/BlockRendererDispatcher;renderBlock(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/IEnviromentBlockReader;Lnet/minecraft/client/renderer/BufferBuilder;Ljava/util/Random;Lnet/minecraftforge/client/model/data/IModelData;)Z";
|
private static final String renderModel = "Lnet/minecraft/client/renderer/BlockRendererDispatcher;renderModel(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/ILightReader;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;Lnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||||
|
@Redirect(method = compile, at = @At(value = "INVOKE", target = renderModel))
|
||||||
@Redirect(method = rebuildChunk, at = @At(value = "INVOKE", target = renderBlock))
|
public boolean renderModel(BlockRendererDispatcher dispatcher, BlockState state, BlockPos pos, ILightReader reader, MatrixStack matrixStack, IVertexBuilder vertexBuilder, boolean checkSides, Random random, IModelData modelData) {
|
||||||
public boolean renderBlock(BlockRendererDispatcher dispatcher, BlockState state, BlockPos pos, IEnviromentBlockReader reader, BufferBuilder buffer, Random random, IModelData modelData) {
|
return Hooks.renderWorldBlock(dispatcher, state, pos, reader, matrixStack, vertexBuilder, checkSides, random, modelData, MinecraftForgeClient.getRenderLayer());
|
||||||
return Hooks.renderWorldBlock(dispatcher, state, pos, reader, buffer, random, modelData, MinecraftForgeClient.getRenderLayer());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.client.Hooks;
|
import mods.betterfoliage.Hooks;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.chunk.ChunkRender;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
@Mixin(ChunkRender.class)
|
@Mixin(targets = {"net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$ChunkRender$RebuildTask"})
|
||||||
public class MixinChunkRenderVanilla {
|
public class MixinChunkRenderVanilla {
|
||||||
|
|
||||||
private static final String rebuildChunk = "rebuildChunk(FFFLnet/minecraft/client/renderer/chunk/ChunkRenderTask;)V";
|
private static final String compile = "Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$RebuildTask;compile(FFFLnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$CompiledChunk;Lnet/minecraft/client/renderer/RegionRenderCacheBuilder;)Ljava/util/Set;";
|
||||||
private static final String canRenderInLayer = "Lnet/minecraft/block/BlockState;canRenderInLayer(Lnet/minecraft/util/BlockRenderLayer;)Z";
|
private static final String canRenderInLayer = "Lnet/minecraft/client/renderer/RenderTypeLookup;canRenderInLayer(Lnet/minecraft/block/BlockState;Lnet/minecraft/client/renderer/RenderType;)Z";
|
||||||
|
|
||||||
@Redirect(method = rebuildChunk, at = @At(value = "INVOKE", target = canRenderInLayer))
|
@Redirect(method = compile, at = @At(value = "INVOKE", target = canRenderInLayer))
|
||||||
boolean canRenderInLayer(BlockState state, BlockRenderLayer layer) {
|
boolean canRenderInLayer(BlockState state, RenderType layer) {
|
||||||
return Hooks.canRenderInLayerOverride(state, layer);
|
return Hooks.canRenderInLayerOverride(state, layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.client.Hooks;
|
import mods.betterfoliage.Hooks;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
@@ -17,7 +17,7 @@ import java.util.Random;
|
|||||||
@Mixin(ClientWorld.class)
|
@Mixin(ClientWorld.class)
|
||||||
public class MixinClientWorld {
|
public class MixinClientWorld {
|
||||||
|
|
||||||
private static final String worldAnimateTick = "Lnet/minecraft/client/world/ClientWorld;animateTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$MutableBlockPos;)V";
|
private static final String worldAnimateTick = "Lnet/minecraft/client/world/ClientWorld;animateTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V";
|
||||||
private static final String blockAnimateTick = "Lnet/minecraft/block/Block;animateTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V";
|
private static final String blockAnimateTick = "Lnet/minecraft/block/Block;animateTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V";
|
||||||
|
|
||||||
private static final String worldNotify = "Lnet/minecraft/client/world/ClientWorld;notifyBlockUpdate(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
private static final String worldNotify = "Lnet/minecraft/client/world/ClientWorld;notifyBlockUpdate(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
||||||
@@ -34,7 +34,7 @@ public class MixinClientWorld {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject callback to get notified of client-side blockstate changes.
|
* Inject callback to get notified of client-side blockstate changes.
|
||||||
* Used to invalidate caches in the {@link mods.betterfoliage.client.chunk.ChunkOverlayManager}
|
* Used to invalidate caches in the {@link mods.betterfoliage.chunk.ChunkOverlayManager}
|
||||||
*/
|
*/
|
||||||
@Redirect(method = worldNotify, at = @At(value = "INVOKE", target = rendererNotify))
|
@Redirect(method = worldNotify, at = @At(value = "INVOKE", target = rendererNotify))
|
||||||
void onClientBlockChanged(WorldRenderer renderer, IBlockReader world, BlockPos pos, BlockState oldState, BlockState newState, int flags) {
|
void onClientBlockChanged(WorldRenderer renderer, IBlockReader world, BlockPos pos, BlockState oldState, BlockState newState, int flags) {
|
||||||
|
|||||||
@@ -1,29 +1,43 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import mods.betterfoliage.BetterFoliage;
|
import mods.betterfoliage.BetterFoliage;
|
||||||
|
import net.minecraft.client.renderer.model.IUnbakedModel;
|
||||||
import net.minecraft.client.renderer.model.ModelBakery;
|
import net.minecraft.client.renderer.model.ModelBakery;
|
||||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
import net.minecraft.profiler.IProfiler;
|
import net.minecraft.profiler.IProfiler;
|
||||||
import net.minecraft.resources.IResourceManager;
|
import net.minecraft.resources.IResourceManager;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
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.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Mixin(ModelBakery.class)
|
@Mixin(ModelBakery.class)
|
||||||
abstract public class MixinModelBakery {
|
abstract public class MixinModelBakery {
|
||||||
|
|
||||||
private static final String processLoading = "processLoading(Lnet/minecraft/profiler/IProfiler;)V";
|
private static final String processLoading = "Lnet/minecraft/client/renderer/model/ModelBakery;processLoading(Lnet/minecraft/profiler/IProfiler;I)V";
|
||||||
private static final String stitch = "Lnet/minecraft/client/renderer/texture/AtlasTexture;stitch(Lnet/minecraft/resources/IResourceManager;Ljava/lang/Iterable;Lnet/minecraft/profiler/IProfiler;)Lnet/minecraft/client/renderer/texture/AtlasTexture$SheetData;";
|
private static final String stitch = "Lnet/minecraft/client/renderer/texture/AtlasTexture;stitch(Lnet/minecraft/resources/IResourceManager;Ljava/util/stream/Stream;Lnet/minecraft/profiler/IProfiler;I)Lnet/minecraft/client/renderer/texture/AtlasTexture$SheetData;";
|
||||||
|
private static final String profilerSection = "Lnet/minecraft/profiler/IProfiler;endStartSection(Ljava/lang/String;)V";
|
||||||
|
|
||||||
@Redirect(method = processLoading, at = @At(value = "INVOKE", target = stitch))
|
@Redirect(method = processLoading, at = @At(value = "INVOKE", target = stitch))
|
||||||
AtlasTexture.SheetData onStitchModelTextures(AtlasTexture atlas, IResourceManager manager, Iterable<ResourceLocation> idList, IProfiler profiler) {
|
AtlasTexture.SheetData onStitchModelTextures(AtlasTexture atlas, IResourceManager manager, Stream<ResourceLocation> idStream, IProfiler profiler, int maxMipmapLevel) {
|
||||||
return BetterFoliage.INSTANCE.getBlockSprites().finish(
|
Set<ResourceLocation> idSetIn = idStream.collect(Collectors.toSet());
|
||||||
atlas.stitch(
|
Set<ResourceLocation> idSetOut = BetterFoliage.INSTANCE.getBlockSprites().prepare(this, manager, idSetIn, profiler);
|
||||||
manager,
|
AtlasTexture.SheetData sheetData = atlas.stitch(manager, idSetOut.stream(), profiler, maxMipmapLevel);
|
||||||
BetterFoliage.INSTANCE.getBlockSprites().prepare(this, manager, idList, profiler),
|
return BetterFoliage.INSTANCE.getBlockSprites().finish(sheetData, profiler);
|
||||||
profiler
|
}
|
||||||
), profiler
|
|
||||||
);
|
@Inject(method = processLoading, at = @At(value = "INVOKE", target = profilerSection, ordinal = 4))
|
||||||
|
void onBeforeTextures(IProfiler profiler, int maxMipmapLevel, CallbackInfo ci) {
|
||||||
|
profiler.endStartSection("betterfoliage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.client.Hooks;
|
import mods.betterfoliage.Hooks;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -14,10 +14,10 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
@Mixin(BlockUtils.class)
|
@Mixin(BlockUtils.class)
|
||||||
public class MixinOptifineBlockUtils {
|
public class MixinOptifineBlockUtils {
|
||||||
private static final String shouldSideBeRenderedCached = "shouldSideBeRenderedCached(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;Lnet/optifine/render/RenderEnv;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)Z";
|
private static final String shouldSideBeRenderedCached = "shouldSideBeRenderedCached(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;Lnet/optifine/render/RenderEnv;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)Z";
|
||||||
private static final String getVoxelShape = "Lnet/minecraft/block/BlockState;func_215702_a(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
private static final String getFaceOcclusionShape = "Lnet/minecraft/block/BlockState;getFaceOcclusionShape(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
||||||
|
|
||||||
@SuppressWarnings("UnresolvedMixinReference")
|
@SuppressWarnings("UnresolvedMixinReference")
|
||||||
@Redirect(method = shouldSideBeRenderedCached, at = @At(value = "INVOKE", target = getVoxelShape, ordinal = 1))
|
@Redirect(method = shouldSideBeRenderedCached, at = @At(value = "INVOKE", target = getFaceOcclusionShape, ordinal = 1))
|
||||||
private static VoxelShape getVoxelShapeOverride(BlockState state, IBlockReader reader, BlockPos pos, Direction dir) {
|
private static VoxelShape getVoxelShapeOverride(BlockState state, IBlockReader reader, BlockPos pos, Direction dir) {
|
||||||
return Hooks.getVoxelShapeOverride(state, reader, pos, dir);
|
return Hooks.getVoxelShapeOverride(state, reader, pos, dir);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.client.Hooks;
|
import mods.betterfoliage.Hooks;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.chunk.ChunkRender;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Coerce;
|
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.Slice;
|
import org.spongepowered.asm.mixin.injection.Slice;
|
||||||
|
|
||||||
@Mixin(ChunkRender.class)
|
@Mixin(targets = {"net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$ChunkRender$RebuildTask"})
|
||||||
public class MixinOptifineChunkRender {
|
public class MixinOptifineChunkRender {
|
||||||
|
|
||||||
private static final String rebuildChunk = "rebuildChunk(FFFLnet/minecraft/client/renderer/chunk/ChunkRenderTask;)V";
|
private static final String compile = "Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$RebuildTask;compile(FFFLnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$CompiledChunk;Lnet/minecraft/client/renderer/RegionRenderCacheBuilder;)Ljava/util/Set;";
|
||||||
private static final String invokeReflector = "Lnet/optifine/reflect/Reflector;callBoolean(Ljava/lang/Object;Lnet/optifine/reflect/ReflectorMethod;[Ljava/lang/Object;)Z";
|
private static final String invokeReflector = "Lnet/optifine/reflect/Reflector;callBoolean(Ljava/lang/Object;Lnet/optifine/reflect/ReflectorMethod;[Ljava/lang/Object;)Z";
|
||||||
private static final String forgeBlockCanRender = "Lnet/minecraft/client/renderer/chunk/ChunkRender;FORGE_BLOCK_CAN_RENDER_IN_LAYER:Z";
|
private static final String forgeBlockCanRender = "Lnet/minecraft/client/renderer/chunk/ChunkRender;FORGE_BLOCK_CAN_RENDER_IN_LAYER:Z";
|
||||||
|
|
||||||
@Redirect(
|
@Redirect(
|
||||||
method = rebuildChunk,
|
method = compile,
|
||||||
at = @At(value = "INVOKE", target = invokeReflector),
|
at = @At(value = "INVOKE", target = invokeReflector),
|
||||||
slice = @Slice(
|
slice = @Slice(
|
||||||
from = @At(value = "FIELD", target = forgeBlockCanRender)
|
from = @At(value = "FIELD", target = forgeBlockCanRender)
|
||||||
@@ -26,6 +25,6 @@ public class MixinOptifineChunkRender {
|
|||||||
)
|
)
|
||||||
@SuppressWarnings("UnresolvedMixinReference")
|
@SuppressWarnings("UnresolvedMixinReference")
|
||||||
boolean canRenderInLayer(Object state, @Coerce Object reflector, Object[] layer) {
|
boolean canRenderInLayer(Object state, @Coerce Object reflector, Object[] layer) {
|
||||||
return Hooks.canRenderInLayerOverride((BlockState) state, (BlockRenderLayer) layer[0]);
|
return Hooks.canRenderInLayerOverride((BlockState) state, (RenderType) layer[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,23 +11,23 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Mixin(ParticleManager.class)
|
@Mixin(ParticleManager.class)
|
||||||
public class MixinParticleManager {
|
public class MixinParticleManager {
|
||||||
|
|
||||||
private static final String reload = "reload(Lnet/minecraft/resources/IFutureReloadListener$IStage;Lnet/minecraft/resources/IResourceManager;Lnet/minecraft/profiler/IProfiler;Lnet/minecraft/profiler/IProfiler;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;";
|
private static final String reload = "reload(Lnet/minecraft/resources/IFutureReloadListener$IStage;Lnet/minecraft/resources/IResourceManager;Lnet/minecraft/profiler/IProfiler;Lnet/minecraft/profiler/IProfiler;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;";
|
||||||
private static final String stitch = "Lnet/minecraft/client/renderer/texture/AtlasTexture;stitch(Lnet/minecraft/resources/IResourceManager;Ljava/lang/Iterable;Lnet/minecraft/profiler/IProfiler;)Lnet/minecraft/client/renderer/texture/AtlasTexture$SheetData;";
|
private static final String stitch = "Lnet/minecraft/client/renderer/texture/AtlasTexture;stitch(Lnet/minecraft/resources/IResourceManager;Ljava/util/stream/Stream;Lnet/minecraft/profiler/IProfiler;I)Lnet/minecraft/client/renderer/texture/AtlasTexture$SheetData;";
|
||||||
|
|
||||||
// ewww :S
|
// ewww :S
|
||||||
@SuppressWarnings("UnresolvedMixinReference")
|
@SuppressWarnings("UnresolvedMixinReference")
|
||||||
@Redirect(method = "*", at = @At(value = "INVOKE", target = stitch))
|
@Redirect(method = "*", at = @At(value = "INVOKE", target = stitch))
|
||||||
AtlasTexture.SheetData onStitchModelTextures(AtlasTexture atlas, IResourceManager manager, Iterable<ResourceLocation> idList, IProfiler profiler) {
|
AtlasTexture.SheetData onStitchModelTextures(AtlasTexture atlas, IResourceManager manager, Stream<ResourceLocation> idStream, IProfiler profiler, int maxMipmapLevel) {
|
||||||
return BetterFoliage.INSTANCE.getParticleSprites().finish(
|
Set<ResourceLocation> idSetIn = idStream.collect(Collectors.toSet());
|
||||||
atlas.stitch(
|
Set<ResourceLocation> idSetOut = BetterFoliage.INSTANCE.getParticleSprites().prepare(this, manager, idSetIn, profiler);
|
||||||
manager,
|
AtlasTexture.SheetData sheetData = atlas.stitch(manager, idSetOut.stream(), profiler, maxMipmapLevel);
|
||||||
BetterFoliage.INSTANCE.getParticleSprites().prepare(this, manager, idList, profiler),
|
return BetterFoliage.INSTANCE.getParticleSprites().finish(sheetData, profiler);
|
||||||
profiler
|
|
||||||
), profiler
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package mods.betterfoliage.mixin;
|
package mods.betterfoliage.mixin;
|
||||||
|
|
||||||
import mods.betterfoliage.client.integration.ShadersModIntegration;
|
import mods.betterfoliage.integration.ShadersModIntegration;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IEnviromentBlockReader;
|
import net.minecraft.world.ILightReader;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||||
@@ -18,7 +18,7 @@ public class MixinShadersBlockModelRenderer {
|
|||||||
|
|
||||||
@SuppressWarnings("UnresolvedMixinReference")
|
@SuppressWarnings("UnresolvedMixinReference")
|
||||||
@ModifyArg(method = renderModel, at = @At(value = "INVOKE", target = pushEntity), remap = false)
|
@ModifyArg(method = renderModel, at = @At(value = "INVOKE", target = pushEntity), remap = false)
|
||||||
BlockState overrideBlockState(BlockState state, BlockPos pos, IEnviromentBlockReader world, BufferBuilder buffer) {
|
BlockState overrideBlockState(BlockState state, BlockPos pos, ILightReader world, BufferBuilder buffer) {
|
||||||
return ShadersModIntegration.getBlockStateOverride(state, world, pos);
|
return ShadersModIntegration.getBlockStateOverride(state, world, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
package mods.betterfoliage
|
package mods.betterfoliage
|
||||||
|
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.util.textComponent
|
||||||
import mods.betterfoliage.client.render.RisingSoulTextures
|
|
||||||
import mods.octarinecore.client.gui.textComponent
|
|
||||||
import mods.octarinecore.client.resource.AsnycSpriteProviderManager
|
import mods.octarinecore.client.resource.AsnycSpriteProviderManager
|
||||||
import mods.octarinecore.client.resource.AsyncSpriteProvider
|
import mods.betterfoliage.resource.generated.GeneratedBlockTexturePack
|
||||||
import mods.octarinecore.client.resource.Atlas
|
import mods.betterfoliage.util.Atlas
|
||||||
import mods.octarinecore.client.resource.GeneratedBlockTexturePack
|
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.particle.ParticleManager
|
import net.minecraft.client.particle.ParticleManager
|
||||||
|
|||||||
@@ -1,24 +1,12 @@
|
|||||||
package mods.betterfoliage
|
package mods.betterfoliage
|
||||||
|
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.Config
|
|
||||||
import mods.octarinecore.client.resource.AsnycSpriteProviderManager
|
|
||||||
import mods.octarinecore.client.resource.GeneratedBlockTexturePack
|
|
||||||
import net.alexwells.kottle.FMLKotlinModLoadingContext
|
import net.alexwells.kottle.FMLKotlinModLoadingContext
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.particle.ParticleManager
|
|
||||||
import net.minecraft.client.renderer.model.ModelBakery
|
|
||||||
import net.minecraftforge.fml.ModLoadingContext
|
import net.minecraftforge.fml.ModLoadingContext
|
||||||
import net.minecraftforge.fml.common.Mod
|
import net.minecraftforge.fml.common.Mod
|
||||||
import net.minecraftforge.fml.config.ModConfig
|
import net.minecraftforge.fml.config.ModConfig
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
import org.apache.logging.log4j.LogManager
|
|
||||||
import org.apache.logging.log4j.simple.SimpleLogger
|
|
||||||
import org.apache.logging.log4j.util.PropertiesUtil
|
|
||||||
import java.io.File
|
|
||||||
import java.io.PrintStream
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
@Mod(BetterFoliageMod.MOD_ID)
|
@Mod(BetterFoliageMod.MOD_ID)
|
||||||
object BetterFoliageMod {
|
object BetterFoliageMod {
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
package mods.betterfoliage.client
|
package mods.betterfoliage
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.chunk.ChunkOverlayManager
|
||||||
import mods.betterfoliage.client.chunk.ChunkOverlayManager
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.integration.*
|
||||||
import mods.betterfoliage.client.integration.*
|
import mods.betterfoliage.render.*
|
||||||
import mods.betterfoliage.client.render.*
|
import mods.betterfoliage.render.block.vanillaold.AsyncCactusDiscovery
|
||||||
import mods.betterfoliage.client.texture.AsyncGrassDiscovery
|
import mods.betterfoliage.render.block.vanillaold.AsyncLogDiscovery
|
||||||
import mods.betterfoliage.client.texture.AsyncLeafDiscovery
|
import mods.betterfoliage.render.block.vanillaold.RenderAlgae
|
||||||
import mods.betterfoliage.client.texture.LeafParticleRegistry
|
import mods.betterfoliage.render.block.vanillaold.RenderCactus
|
||||||
import mods.octarinecore.client.gui.textComponent
|
import mods.betterfoliage.render.block.vanillaold.RenderConnectedGrass
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.block.vanillaold.RenderConnectedGrassLog
|
||||||
import mods.octarinecore.client.resource.IConfigChangeListener
|
import mods.betterfoliage.render.block.vanillaold.RenderCoral
|
||||||
|
import mods.betterfoliage.render.block.vanillaold.RenderGrass
|
||||||
|
import mods.betterfoliage.render.block.vanillaold.RenderLeaves
|
||||||
|
import mods.betterfoliage.render.block.vanillaold.RenderLilypad
|
||||||
|
import mods.betterfoliage.render.block.vanillaold.RenderLog
|
||||||
|
import mods.betterfoliage.render.block.vanillaold.RenderMycelium
|
||||||
|
import mods.betterfoliage.render.block.vanillaold.RenderNetherrack
|
||||||
|
import mods.betterfoliage.render.block.vanillaold.RenderReeds
|
||||||
|
import mods.betterfoliage.texture.AsyncGrassDiscovery
|
||||||
|
import mods.betterfoliage.texture.AsyncLeafDiscovery
|
||||||
|
import mods.betterfoliage.texture.LeafParticleRegistry
|
||||||
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
|
import mods.betterfoliage.resource.IConfigChangeListener
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.Minecraft
|
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.util.text.TextFormatting
|
|
||||||
import net.minecraft.util.text.TranslationTextComponent
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries
|
|
||||||
import org.apache.logging.log4j.Level
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object responsible for initializing (and holding a reference to) all the infrastructure of the mod
|
* Object responsible for initializing (and holding a reference to) all the infrastructure of the mod
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package mods.octarinecore
|
package mods.octarinecore
|
||||||
|
|
||||||
import mods.octarinecore.metaprog.ClassRef
|
import mods.betterfoliage.util.ClassRef
|
||||||
import mods.octarinecore.metaprog.ClassRef.Companion.void
|
import mods.betterfoliage.util.ClassRef.Companion.void
|
||||||
import mods.octarinecore.metaprog.FieldRef
|
import mods.betterfoliage.util.FieldRef
|
||||||
import mods.octarinecore.metaprog.MethodRef
|
import mods.betterfoliage.util.MethodRef
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||||
@@ -11,11 +11,10 @@ import net.minecraft.client.renderer.BufferBuilder
|
|||||||
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
||||||
import net.minecraft.client.renderer.model.BakedQuad
|
import net.minecraft.client.renderer.model.BakedQuad
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
import net.minecraft.util.BlockRenderLayer
|
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
import net.minecraft.world.ILightReader
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
// Java
|
// Java
|
||||||
@@ -26,10 +25,9 @@ val Random = ClassRef<Random>("java.util.Random")
|
|||||||
|
|
||||||
// Minecraft
|
// Minecraft
|
||||||
val IBlockReader = ClassRef<IBlockReader>("net.minecraft.world.IBlockReader")
|
val IBlockReader = ClassRef<IBlockReader>("net.minecraft.world.IBlockReader")
|
||||||
val IEnvironmentBlockReader = ClassRef<IEnviromentBlockReader>("net.minecraft.world.IEnviromentBlockReader")
|
val ILightReader = ClassRef<ILightReader>("net.minecraft.world.ILightReader")
|
||||||
val BlockState = ClassRef<BlockState>("net.minecraft.block.BlockState")
|
val BlockState = ClassRef<BlockState>("net.minecraft.block.BlockState")
|
||||||
val BlockPos = ClassRef<BlockPos>("net.minecraft.util.math.BlockPos")
|
val BlockPos = ClassRef<BlockPos>("net.minecraft.util.math.BlockPos")
|
||||||
val BlockRenderLayer = ClassRef<BlockRenderLayer>("net.minecraft.util.BlockRenderLayer")
|
|
||||||
val Block = ClassRef<Block>("net.minecraft.block.Block")
|
val Block = ClassRef<Block>("net.minecraft.block.Block")
|
||||||
|
|
||||||
val TextureAtlasSprite = ClassRef<TextureAtlasSprite>("net.minecraft.client.renderer.texture.TextureAtlasSprite")
|
val TextureAtlasSprite = ClassRef<TextureAtlasSprite>("net.minecraft.client.renderer.texture.TextureAtlasSprite")
|
||||||
@@ -55,7 +53,7 @@ object RenderEnv : ClassRef<Any>("net.optifine.render.RenderEnv") {
|
|||||||
// Optifine custom colors
|
// Optifine custom colors
|
||||||
val IColorizer = ClassRef<Any>("net.optifine.CustomColors\$IColorizer")
|
val IColorizer = ClassRef<Any>("net.optifine.CustomColors\$IColorizer")
|
||||||
object CustomColors : ClassRef<Any>("net.optifine.CustomColors") {
|
object CustomColors : ClassRef<Any>("net.optifine.CustomColors") {
|
||||||
val getColorMultiplier = MethodRef(this, "getColorMultiplier", int, BakedQuad, BlockState, IEnvironmentBlockReader, BlockPos, RenderEnv)
|
val getColorMultiplier = MethodRef(this, "getColorMultiplier", int, BakedQuad, BlockState, ILightReader, BlockPos, RenderEnv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optifine shaders
|
// Optifine shaders
|
||||||
@@ -1,33 +1,42 @@
|
|||||||
@file:JvmName("Hooks")
|
@file:JvmName("Hooks")
|
||||||
package mods.betterfoliage.client
|
package mods.betterfoliage
|
||||||
|
|
||||||
import mods.betterfoliage.client.chunk.ChunkOverlayManager
|
import com.mojang.blaze3d.matrix.MatrixStack
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import com.mojang.blaze3d.vertex.IVertexBuilder
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.chunk.ChunkOverlayManager
|
||||||
import mods.betterfoliage.client.render.*
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.octarinecore.ThreadLocalDelegate
|
import mods.betterfoliage.config.Config
|
||||||
import mods.octarinecore.client.render.*
|
import mods.betterfoliage.render.EntityFallingLeavesFX
|
||||||
import mods.octarinecore.client.render.lighting.DefaultLightingCtx
|
import mods.betterfoliage.render.EntityRisingSoulFX
|
||||||
import mods.octarinecore.common.plus
|
import mods.betterfoliage.render.block.vanillaold.LogRegistry
|
||||||
|
import mods.betterfoliage.render.canRenderInLayer
|
||||||
|
import mods.betterfoliage.render.down1
|
||||||
|
import mods.betterfoliage.render.isCutout
|
||||||
|
import mods.betterfoliage.render.up1
|
||||||
|
import mods.betterfoliage.render.old.BasicBlockCtx
|
||||||
|
import mods.betterfoliage.render.old.CachedBlockCtx
|
||||||
|
import mods.betterfoliage.render.old.NonNullWorld
|
||||||
|
import mods.betterfoliage.render.old.RenderCtx
|
||||||
|
import mods.betterfoliage.render.lighting.DefaultLightingCtx
|
||||||
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
|
import mods.betterfoliage.util.ThreadLocalDelegate
|
||||||
|
import mods.betterfoliage.util.plus
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||||
import net.minecraft.client.renderer.BufferBuilder
|
import net.minecraft.client.renderer.RenderType
|
||||||
import net.minecraft.client.world.ClientWorld
|
import net.minecraft.client.world.ClientWorld
|
||||||
import net.minecraft.util.BlockRenderLayer
|
|
||||||
import net.minecraft.util.BlockRenderLayer.CUTOUT
|
|
||||||
import net.minecraft.util.BlockRenderLayer.CUTOUT_MIPPED
|
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.shapes.VoxelShape
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes
|
import net.minecraft.util.math.shapes.VoxelShapes
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
import net.minecraft.world.ILightReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import net.minecraftforge.client.model.data.IModelData
|
import net.minecraftforge.client.model.data.IModelData
|
||||||
import java.util.*
|
import java.util.Random
|
||||||
|
|
||||||
fun getAmbientOcclusionLightValueOverride(original: Float, state: BlockState): Float {
|
fun getAmbientOcclusionLightValueOverride(original: Float, state: BlockState): Float {
|
||||||
if (Config.enabled && Config.roundLogs.enabled && BlockConfig.logBlocks.matchesClass(state.block)) return Config.roundLogs.dimming.toFloat();
|
if (Config.enabled && Config.roundLogs.enabled && BlockConfig.logBlocks.matchesClass(state.block)) return Config.roundLogs.dimming.toFloat();
|
||||||
@@ -62,27 +71,34 @@ fun onRandomDisplayTick(block: Block, state: BlockState, world: World, pos: Bloc
|
|||||||
|
|
||||||
fun getVoxelShapeOverride(state: BlockState, reader: IBlockReader, pos: BlockPos, dir: Direction): VoxelShape {
|
fun getVoxelShapeOverride(state: BlockState, reader: IBlockReader, pos: BlockPos, dir: Direction): VoxelShape {
|
||||||
if (LogRegistry[state, reader, pos] != null) return VoxelShapes.empty()
|
if (LogRegistry[state, reader, pos] != null) return VoxelShapes.empty()
|
||||||
return state.func_215702_a(reader, pos, dir)
|
return state.getFaceOcclusionShape(reader, pos, dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
val lightingCtx by ThreadLocalDelegate { DefaultLightingCtx(BasicBlockCtx(NonNullWorld, BlockPos.ZERO)) }
|
val lightingCtx by ThreadLocalDelegate { DefaultLightingCtx(BasicBlockCtx(NonNullWorld, BlockPos.ZERO)) }
|
||||||
fun renderWorldBlock(dispatcher: BlockRendererDispatcher,
|
fun renderWorldBlock(dispatcher: BlockRendererDispatcher,
|
||||||
state: BlockState,
|
state: BlockState,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
reader: IEnviromentBlockReader,
|
reader: ILightReader,
|
||||||
buffer: BufferBuilder,
|
matrixStack: MatrixStack,
|
||||||
|
buffer: IVertexBuilder,
|
||||||
|
checkSides: Boolean,
|
||||||
random: Random,
|
random: Random,
|
||||||
modelData: IModelData,
|
modelData: IModelData,
|
||||||
layer: BlockRenderLayer
|
layer: RenderType
|
||||||
): Boolean {
|
): Boolean {
|
||||||
// build context
|
// build context
|
||||||
val blockCtx = CachedBlockCtx(reader, pos)
|
val blockCtx = CachedBlockCtx(reader, pos)
|
||||||
val renderCtx = RenderCtx(dispatcher, buffer, layer, random, modelData)
|
val renderCtx = RenderCtx(dispatcher, buffer, matrixStack, layer, checkSides, random, modelData)
|
||||||
lightingCtx.reset(blockCtx)
|
lightingCtx.reset(blockCtx)
|
||||||
val combinedCtx = CombinedContext(blockCtx, renderCtx, lightingCtx)
|
val combinedCtx = CombinedContext(blockCtx, renderCtx, lightingCtx)
|
||||||
|
|
||||||
|
combinedCtx.render()
|
||||||
|
return combinedCtx.hasRendered
|
||||||
|
|
||||||
// loop render decorators
|
// loop render decorators
|
||||||
val doBaseRender = state.canRenderInLayer(layer) || (layer == targetCutoutLayer && state.canRenderInLayer(otherCutoutLayer))
|
val doBaseRender = state.canRenderInLayer(layer) || (layer == targetCutoutLayer && state.canRenderInLayer(
|
||||||
|
otherCutoutLayer
|
||||||
|
))
|
||||||
Client.renderers.forEach { renderer ->
|
Client.renderers.forEach { renderer ->
|
||||||
if (renderer.isEligible(combinedCtx)) {
|
if (renderer.isEligible(combinedCtx)) {
|
||||||
// render on the block's default layer
|
// render on the block's default layer
|
||||||
@@ -103,10 +119,10 @@ fun renderWorldBlock(dispatcher: BlockRendererDispatcher,
|
|||||||
return combinedCtx.hasRendered
|
return combinedCtx.hasRendered
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canRenderInLayerOverride(state: BlockState, layer: BlockRenderLayer) = state.canRenderInLayer(layer) || layer == targetCutoutLayer
|
fun canRenderInLayerOverride(state: BlockState, layer: RenderType) = state.canRenderInLayer(layer) || layer == targetCutoutLayer
|
||||||
|
|
||||||
fun canRenderInLayerOverrideOptifine(state: BlockState, optifineReflector: Any?, layerArray: Array<Any>) =
|
fun canRenderInLayerOverrideOptifine(state: BlockState, optifineReflector: Any?, layerArray: Array<Any>) =
|
||||||
canRenderInLayerOverride(state, layerArray[0] as BlockRenderLayer)
|
canRenderInLayerOverride(state, layerArray[0] as RenderType)
|
||||||
|
|
||||||
val targetCutoutLayer: BlockRenderLayer get() = if (Minecraft.getInstance().gameSettings.mipmapLevels > 0) CUTOUT_MIPPED else CUTOUT
|
val targetCutoutLayer: RenderType get() = if (Minecraft.getInstance().gameSettings.mipmapLevels > 0) RenderType.getCutoutMipped() else RenderType.getCutout()
|
||||||
val otherCutoutLayer: BlockRenderLayer get() = if (Minecraft.getInstance().gameSettings.mipmapLevels > 0) CUTOUT else CUTOUT_MIPPED
|
val otherCutoutLayer: RenderType get() = if (Minecraft.getInstance().gameSettings.mipmapLevels > 0) RenderType.getCutout() else RenderType.getCutoutMipped()
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package mods.betterfoliage.client.chunk
|
package mods.betterfoliage.chunk
|
||||||
|
|
||||||
import mods.octarinecore.ChunkCacheOF
|
import mods.octarinecore.ChunkCacheOF
|
||||||
import mods.octarinecore.client.render.BlockCtx
|
import mods.betterfoliage.render.old.BlockCtx
|
||||||
import mods.octarinecore.metaprog.get
|
import mods.betterfoliage.util.get
|
||||||
import mods.octarinecore.metaprog.isInstance
|
import mods.betterfoliage.util.isInstance
|
||||||
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
||||||
import net.minecraft.client.world.ClientWorld
|
import net.minecraft.client.world.ClientWorld
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.ChunkPos
|
import net.minecraft.util.math.ChunkPos
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
import net.minecraft.world.ILightReader
|
||||||
import net.minecraft.world.IWorldReader
|
import net.minecraft.world.IWorldReader
|
||||||
import net.minecraft.world.dimension.DimensionType
|
import net.minecraft.world.dimension.DimensionType
|
||||||
import net.minecraftforge.common.MinecraftForge
|
import net.minecraftforge.common.MinecraftForge
|
||||||
@@ -24,7 +24,7 @@ import kotlin.collections.mutableListOf
|
|||||||
import kotlin.collections.mutableMapOf
|
import kotlin.collections.mutableMapOf
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
val IEnviromentBlockReader.dimType: DimensionType get() = when {
|
val ILightReader.dimType: DimensionType get() = when {
|
||||||
this is IWorldReader -> dimension.type
|
this is IWorldReader -> dimension.type
|
||||||
this is ChunkRenderCache -> world.dimension.type
|
this is ChunkRenderCache -> world.dimension.type
|
||||||
this.isInstance(ChunkCacheOF) -> this[ChunkCacheOF.chunkCache].world.dimension.type
|
this.isInstance(ChunkCacheOF) -> this[ChunkCacheOF.chunkCache].world.dimension.type
|
||||||
@@ -36,7 +36,7 @@ val IEnviromentBlockReader.dimType: DimensionType get() = when {
|
|||||||
*/
|
*/
|
||||||
interface ChunkOverlayLayer<T> {
|
interface ChunkOverlayLayer<T> {
|
||||||
fun calculate(ctx: BlockCtx): T
|
fun calculate(ctx: BlockCtx): T
|
||||||
fun onBlockUpdate(world: IEnviromentBlockReader, pos: BlockPos)
|
fun onBlockUpdate(world: ILightReader, pos: BlockPos)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
package mods.betterfoliage.client.config
|
package mods.betterfoliage.config
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
|
||||||
import mods.octarinecore.common.config.*
|
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
import net.minecraftforge.fml.config.ModConfig
|
import net.minecraftforge.fml.config.ModConfig
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
@file:JvmName("DelegatingConfigKt")
|
@file:JvmName("DelegatingConfigKt")
|
||||||
|
|
||||||
package mods.octarinecore.common.config
|
package mods.betterfoliage.config
|
||||||
|
|
||||||
import mods.octarinecore.metaprog.reflectDelegates
|
import mods.betterfoliage.util.reflectDelegates
|
||||||
import mods.octarinecore.metaprog.reflectNestedObjects
|
import mods.betterfoliage.util.reflectNestedObjects
|
||||||
import net.minecraftforge.common.ForgeConfigSpec
|
import net.minecraftforge.common.ForgeConfigSpec
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package mods.octarinecore.common.config
|
package mods.betterfoliage.config
|
||||||
|
|
||||||
import mods.octarinecore.client.resource.getLines
|
import mods.betterfoliage.util.getLines
|
||||||
import mods.octarinecore.client.resource.resourceManager
|
import mods.betterfoliage.util.resourceManager
|
||||||
import mods.octarinecore.metaprog.getJavaClass
|
import mods.betterfoliage.util.getJavaClass
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import org.apache.logging.log4j.Logger
|
import org.apache.logging.log4j.Logger
|
||||||
@@ -1,20 +1,27 @@
|
|||||||
package mods.betterfoliage.client.integration
|
package mods.betterfoliage.integration
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.render.AsyncLogDiscovery
|
import mods.betterfoliage.render.block.vanillaold.AsyncLogDiscovery
|
||||||
import mods.betterfoliage.client.render.column.ColumnTextureInfo
|
import mods.betterfoliage.render.column.ColumnTextureInfo
|
||||||
import mods.betterfoliage.client.render.column.SimpleColumnInfo
|
import mods.betterfoliage.render.column.SimpleColumnInfo
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.betterfoliage.client.texture.LeafInfo
|
import mods.betterfoliage.resource.discovery.ModelDiscovery
|
||||||
import mods.betterfoliage.client.texture.defaultRegisterLeaf
|
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
|
||||||
import mods.octarinecore.HasLogger
|
import mods.betterfoliage.resource.discovery.ModelRenderRegistry
|
||||||
|
import mods.betterfoliage.texture.LeafInfo
|
||||||
|
import mods.betterfoliage.texture.defaultRegisterLeaf
|
||||||
|
import mods.betterfoliage.util.ClassRef
|
||||||
import mods.octarinecore.Map
|
import mods.octarinecore.Map
|
||||||
import mods.octarinecore.ResourceLocation
|
import mods.octarinecore.ResourceLocation
|
||||||
import mods.octarinecore.String
|
import mods.octarinecore.String
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.octarinecore.client.resource.*
|
||||||
import mods.octarinecore.metaprog.*
|
import mods.betterfoliage.util.ClassRef.Companion.boolean
|
||||||
import mods.octarinecore.metaprog.ClassRef.Companion.boolean
|
import mods.betterfoliage.util.FieldRef
|
||||||
|
import mods.betterfoliage.util.HasLogger
|
||||||
|
import mods.betterfoliage.util.MethodRef
|
||||||
|
import mods.betterfoliage.util.allAvailable
|
||||||
|
import mods.betterfoliage.util.get
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.model.ModelBakery
|
import net.minecraft.client.renderer.model.ModelBakery
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package mods.betterfoliage.client.integration
|
package mods.betterfoliage.integration
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
|
import mods.betterfoliage.util.ThreadLocalDelegate
|
||||||
import mods.octarinecore.*
|
import mods.octarinecore.*
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.util.allAvailable
|
||||||
import mods.octarinecore.metaprog.allAvailable
|
import mods.betterfoliage.util.reflectField
|
||||||
import mods.octarinecore.metaprog.reflectField
|
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.model.BakedQuad
|
import net.minecraft.client.renderer.model.BakedQuad
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import org.apache.logging.log4j.Level
|
import org.apache.logging.log4j.Level
|
||||||
@@ -26,7 +26,7 @@ object OptifineCustomColors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val renderEnv by ThreadLocalDelegate { OptifineRenderEnv() }
|
val renderEnv by ThreadLocalDelegate { OptifineRenderEnv() }
|
||||||
val fakeQuad = BakedQuad(IntArray(0), 1, UP, null, true, DefaultVertexFormats.BLOCK)
|
val fakeQuad = BakedQuad(IntArray(0), 1, UP, null, true)
|
||||||
|
|
||||||
fun getBlockColor(ctx: CombinedContext): Int {
|
fun getBlockColor(ctx: CombinedContext): Int {
|
||||||
val ofColor = if (isColorAvailable && Minecraft.getInstance().gameSettings.reflectField<Boolean>("ofCustomColors") == true) {
|
val ofColor = if (isColorAvailable && Minecraft.getInstance().gameSettings.reflectField<Boolean>("ofCustomColors") == true) {
|
||||||
@@ -1,23 +1,25 @@
|
|||||||
package mods.betterfoliage.client.integration
|
package mods.betterfoliage.integration
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.client.render.LogRegistry
|
import mods.betterfoliage.render.column.ColumnTextureInfo
|
||||||
import mods.betterfoliage.client.render.column.ColumnTextureInfo
|
import mods.betterfoliage.render.column.SimpleColumnInfo
|
||||||
import mods.betterfoliage.client.render.column.SimpleColumnInfo
|
import mods.betterfoliage.resource.Sprite
|
||||||
import mods.betterfoliage.client.resource.Sprite
|
import mods.betterfoliage.render.old.Quad
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.lighting.QuadIconResolver
|
||||||
import mods.octarinecore.client.render.Quad
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.client.render.lighting.QuadIconResolver
|
import mods.betterfoliage.resource.discovery.ModelDiscovery
|
||||||
|
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
|
||||||
|
import mods.betterfoliage.resource.discovery.derivesFrom
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.octarinecore.client.resource.*
|
||||||
import mods.octarinecore.common.rotate
|
import mods.betterfoliage.util.rotate
|
||||||
import mods.octarinecore.metaprog.ClassRef
|
import mods.betterfoliage.util.ClassRef
|
||||||
import mods.octarinecore.metaprog.allAvailable
|
import mods.betterfoliage.util.allAvailable
|
||||||
import net.minecraft.client.renderer.model.BlockModel
|
import net.minecraft.client.renderer.model.BlockModel
|
||||||
|
import net.minecraft.client.renderer.texture.MissingTextureSprite
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraftforge.fml.ModList
|
import net.minecraftforge.fml.ModList
|
||||||
import org.apache.logging.log4j.Level
|
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
|
|
||||||
@@ -86,8 +88,8 @@ object IC2LogDiscovery : ModelDiscovery<ColumnTextureInfo>() {
|
|||||||
"plain_z" -> Axis.Z
|
"plain_z" -> Axis.Z
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
val textureNames = listOf("end", "side").map { blockLoc.first.resolveTextureName(it) }
|
val textureNames = listOf("end", "side").map { blockLoc.first.resolveTextureName(it).textureLocation }
|
||||||
if (textureNames.any { it == "missingno" }) return null
|
if (textureNames.any { it == MissingTextureSprite.getLocation() }) return null
|
||||||
log("IC2LogSupport: block state ${ctx.state.toString()}")
|
log("IC2LogSupport: block state ${ctx.state.toString()}")
|
||||||
log("IC2LogSupport: axis=$axis, end=${textureNames[0]}, side=${textureNames[1]}")
|
log("IC2LogSupport: axis=$axis, end=${textureNames[0]}, side=${textureNames[1]}")
|
||||||
val endSprite = atlas.sprite(textureNames[0])
|
val endSprite = atlas.sprite(textureNames[0])
|
||||||
@@ -105,9 +107,9 @@ object IC2LogDiscovery : ModelDiscovery<ColumnTextureInfo>() {
|
|||||||
"dry_east", "wet_east" -> EAST
|
"dry_east", "wet_east" -> EAST
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
val textureNames = listOf("up", "down", "north", "south").map { blockLoc.first.resolveTextureName(it) }
|
val textureNames = listOf("up", "down", "north", "south").map { blockLoc.first.resolveTextureName(it).textureLocation }
|
||||||
if (textureNames.any { it == "missingno" }) return null
|
if (textureNames.any { it == MissingTextureSprite.getLocation() }) return null
|
||||||
log("IC2LogSupport: block state ${ctx.state.toString()}")
|
log("IC2LogSupport: block state ${ctx.state}")
|
||||||
log("IC2LogSupport: spotDir=$spotDir, up=${textureNames[0]}, down=${textureNames[1]}, side=${textureNames[2]}, spot=${textureNames[3]}")
|
log("IC2LogSupport: spotDir=$spotDir, up=${textureNames[0]}, down=${textureNames[1]}, side=${textureNames[2]}, spot=${textureNames[3]}")
|
||||||
val upSprite = atlas.sprite(textureNames[0])
|
val upSprite = atlas.sprite(textureNames[0])
|
||||||
val downSprite = atlas.sprite(textureNames[1])
|
val downSprite = atlas.sprite(textureNames[1])
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
package mods.betterfoliage.client.integration
|
package mods.betterfoliage.integration
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.texture.LeafRegistry
|
import mods.betterfoliage.texture.LeafRegistry
|
||||||
import mods.octarinecore.*
|
import mods.octarinecore.*
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.metaprog.allAvailable
|
import mods.betterfoliage.util.allAvailable
|
||||||
import mods.octarinecore.metaprog.get
|
import mods.betterfoliage.util.get
|
||||||
import net.minecraft.block.BlockRenderType
|
import net.minecraft.block.BlockRenderType
|
||||||
import net.minecraft.block.BlockRenderType.MODEL
|
import net.minecraft.block.BlockRenderType.MODEL
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
import net.minecraft.world.ILightReader
|
||||||
import org.apache.logging.log4j.Level.INFO
|
import org.apache.logging.log4j.Level.INFO
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +29,7 @@ object ShadersModIntegration {
|
|||||||
* Called from transformed ShadersMod code.
|
* Called from transformed ShadersMod code.
|
||||||
* @see mods.betterfoliage.loader.BetterFoliageTransformer
|
* @see mods.betterfoliage.loader.BetterFoliageTransformer
|
||||||
*/
|
*/
|
||||||
@JvmStatic fun getBlockStateOverride(state: BlockState, world: IEnviromentBlockReader, pos: BlockPos): BlockState {
|
@JvmStatic fun getBlockStateOverride(state: BlockState, world: ILightReader, pos: BlockPos): BlockState {
|
||||||
if (LeafRegistry[state, world, pos] != null) return defaultLeaves
|
if (LeafRegistry[state, world, pos] != null) return defaultLeaves
|
||||||
if (BlockConfig.crops.matchesClass(state.block)) return defaultGrass
|
if (BlockConfig.crops.matchesClass(state.block)) return defaultGrass
|
||||||
return state
|
return state
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render
|
||||||
|
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.texture.LeafParticleRegistry
|
import mods.betterfoliage.texture.LeafParticleRegistry
|
||||||
import mods.betterfoliage.client.texture.LeafRegistry
|
import mods.betterfoliage.texture.LeafRegistry
|
||||||
import mods.octarinecore.PI2
|
import mods.betterfoliage.render.old.AbstractEntityFX
|
||||||
import mods.octarinecore.client.render.AbstractEntityFX
|
import mods.betterfoliage.render.lighting.HSB
|
||||||
import mods.octarinecore.client.render.lighting.HSB
|
import mods.betterfoliage.util.Double3
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.util.PI2
|
||||||
import mods.octarinecore.minmax
|
import mods.betterfoliage.util.minmax
|
||||||
import mods.octarinecore.random
|
import mods.betterfoliage.util.randomD
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.BufferBuilder
|
import net.minecraft.client.renderer.BufferBuilder
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
@@ -18,7 +18,6 @@ import net.minecraftforge.common.MinecraftForge
|
|||||||
import net.minecraftforge.event.TickEvent
|
import net.minecraftforge.event.TickEvent
|
||||||
import net.minecraftforge.event.world.WorldEvent
|
import net.minecraftforge.event.world.WorldEvent
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
import org.lwjgl.opengl.GL11
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
@@ -42,7 +41,7 @@ class EntityFallingLeavesFX(
|
|||||||
var wasCollided = false
|
var wasCollided = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
maxAge = MathHelper.floor(random(0.6, 1.0) * Config.fallingLeaves.lifetime * 20.0)
|
maxAge = MathHelper.floor(randomD(0.6, 1.0) * Config.fallingLeaves.lifetime * 20.0)
|
||||||
motionY = -Config.fallingLeaves.speed
|
motionY = -Config.fallingLeaves.speed
|
||||||
|
|
||||||
particleScale = Config.fallingLeaves.size.toFloat() * 0.1f
|
particleScale = Config.fallingLeaves.size.toFloat() * 0.1f
|
||||||
@@ -68,7 +67,7 @@ class EntityFallingLeavesFX(
|
|||||||
if (onGround || wasCollided) {
|
if (onGround || wasCollided) {
|
||||||
velocity.setTo(0.0, 0.0, 0.0)
|
velocity.setTo(0.0, 0.0, 0.0)
|
||||||
if (!wasCollided) {
|
if (!wasCollided) {
|
||||||
age = Math.max(age, maxAge - 20)
|
age = age.coerceAtLeast(maxAge - 20)
|
||||||
wasCollided = true
|
wasCollided = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -80,8 +79,8 @@ class EntityFallingLeavesFX(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) {
|
override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) {
|
||||||
if (Config.fallingLeaves.opacityHack) GL11.glDepthMask(true)
|
// if (Config.fallingLeaves.opacityHack) GL11.glDepthMask(true)
|
||||||
renderParticleQuad(worldRenderer, partialTickTime, rotation = particleRot, isMirrored = isMirrored)
|
// renderParticleQuad(worldRenderer, partialTickTime, rotation = particleRot, isMirrored = isMirrored)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun calculateParticleColor(textureAvgColor: Int, blockColor: Int) {
|
fun calculateParticleColor(textureAvgColor: Int, blockColor: Int) {
|
||||||
@@ -1,21 +1,17 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.render.old.AbstractEntityFX
|
||||||
import mods.octarinecore.client.render.AbstractEntityFX
|
import mods.betterfoliage.resource.ResourceHandler
|
||||||
import mods.octarinecore.client.resource.Atlas
|
import mods.betterfoliage.util.Atlas
|
||||||
import mods.octarinecore.client.resource.ResourceHandler
|
import mods.betterfoliage.util.Double3
|
||||||
import mods.octarinecore.common.Double3
|
|
||||||
import mods.octarinecore.forEachPairIndexed
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder
|
import net.minecraft.client.renderer.BufferBuilder
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.MathHelper
|
import net.minecraft.util.math.MathHelper
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class EntityRisingSoulFX(world: World, pos: BlockPos) :
|
class EntityRisingSoulFX(world: World, pos: BlockPos) :
|
||||||
@@ -44,26 +40,26 @@ AbstractEntityFX(world, pos.x.toDouble() + 0.5, pos.y.toDouble() + 1.0, pos.z.to
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) {
|
override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) {
|
||||||
var alpha = Config.risingSoul.opacity.toFloat()
|
// var alpha = Config.risingSoul.opacity.toFloat()
|
||||||
if (age > maxAge - 40) alpha *= (maxAge - age) / 40.0f
|
// if (age > maxAge - 40) alpha *= (maxAge - age) / 40.0f
|
||||||
|
//
|
||||||
renderParticleQuad(worldRenderer, partialTickTime,
|
// renderParticleQuad(worldRenderer, partialTickTime,
|
||||||
size = Config.risingSoul.headSize * 0.25,
|
// size = Config.risingSoul.headSize * 0.25,
|
||||||
alpha = alpha
|
// alpha = alpha
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
var scale = Config.risingSoul.trailSize * 0.25
|
// var scale = Config.risingSoul.trailSize * 0.25
|
||||||
particleTrail.forEachPairIndexed { idx, current, previous ->
|
// particleTrail.forEachPairIndexed { idx, current, previous ->
|
||||||
scale *= Config.risingSoul.sizeDecay
|
// scale *= Config.risingSoul.sizeDecay
|
||||||
alpha *= Config.risingSoul.opacityDecay.toFloat()
|
// alpha *= Config.risingSoul.opacityDecay.toFloat()
|
||||||
if (idx % Config.risingSoul.trailDensity == 0) renderParticleQuad(worldRenderer, partialTickTime,
|
// if (idx % Config.risingSoul.trailDensity == 0) renderParticleQuad(worldRenderer, partialTickTime,
|
||||||
currentPos = current,
|
// currentPos = current,
|
||||||
prevPos = previous,
|
// prevPos = previous,
|
||||||
size = scale,
|
// size = scale,
|
||||||
alpha = alpha,
|
// alpha = alpha,
|
||||||
icon = RisingSoulTextures.trackIcon
|
// icon = RisingSoulTextures.trackIcon
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,11 +1,22 @@
|
|||||||
@file:JvmName("ModelColumn")
|
@file:JvmName("ModelColumn")
|
||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render
|
||||||
|
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.octarinecore.client.render.*
|
import mods.betterfoliage.render.lighting.CornerSingleFallback
|
||||||
import mods.octarinecore.client.render.lighting.*
|
import mods.betterfoliage.render.lighting.EdgeInterpolateFallback
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.render.lighting.FaceCenter
|
||||||
import mods.octarinecore.exchange
|
import mods.betterfoliage.render.lighting.FaceFlat
|
||||||
|
import mods.betterfoliage.render.lighting.cornerAo
|
||||||
|
import mods.betterfoliage.render.lighting.cornerFlat
|
||||||
|
import mods.betterfoliage.render.lighting.cornerInterpolate
|
||||||
|
import mods.betterfoliage.render.lighting.faceOrientedAuto
|
||||||
|
import mods.betterfoliage.render.lighting.faceOrientedInterpolate
|
||||||
|
import mods.betterfoliage.render.old.Model
|
||||||
|
import mods.betterfoliage.render.old.Quad
|
||||||
|
import mods.betterfoliage.render.old.UV
|
||||||
|
import mods.betterfoliage.render.old.Vertex
|
||||||
|
import mods.betterfoliage.util.Double3
|
||||||
|
import mods.betterfoliage.util.exchange
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
|
|
||||||
/** Weight of the same-side AO values on the outer edges of the 45deg chamfered column faces. */
|
/** Weight of the same-side AO values on the outer edges of the 45deg chamfered column faces. */
|
||||||
@@ -37,7 +48,8 @@ fun Model.columnSide(radius: Double, yBottom: Double, yTop: Double, transform: (
|
|||||||
verticalRectangle(x1 = 0.5 - halfRadius, z1 = 0.5 - halfRadius, x2 = 0.5, z2 = 0.5 - radius, yBottom = yBottom, yTop = yTop)
|
verticalRectangle(x1 = 0.5 - halfRadius, z1 = 0.5 - halfRadius, x2 = 0.5, z2 = 0.5 - radius, yBottom = yBottom, yTop = yTop)
|
||||||
.clampUV(maxU = radius - 0.5)
|
.clampUV(maxU = radius - 0.5)
|
||||||
.setAoShader(
|
.setAoShader(
|
||||||
faceOrientedAuto(overrideFace = EAST, corner = cornerInterpolate(Axis.Y, chamferAffinity, Config.roundLogs.dimming.toFloat())))
|
faceOrientedAuto(overrideFace = EAST, corner = cornerInterpolate(Axis.Y, chamferAffinity, Config.roundLogs.dimming.toFloat()))
|
||||||
|
)
|
||||||
.setAoShader(
|
.setAoShader(
|
||||||
faceOrientedAuto(overrideFace = EAST, corner = cornerInterpolate(Axis.Y, 0.5f, Config.roundLogs.dimming.toFloat())),
|
faceOrientedAuto(overrideFace = EAST, corner = cornerInterpolate(Axis.Y, 0.5f, Config.roundLogs.dimming.toFloat())),
|
||||||
predicate = { v, vi -> vi == 0 || vi == 3}
|
predicate = { v, vi -> vi == 0 || vi == 3}
|
||||||
@@ -1,19 +1,27 @@
|
|||||||
@file:JvmName("Utils")
|
@file:JvmName("Utils")
|
||||||
package mods.betterfoliage.client.render
|
|
||||||
|
|
||||||
import mods.octarinecore.PI2
|
package mods.betterfoliage.render
|
||||||
import mods.octarinecore.client.render.Model
|
|
||||||
import mods.octarinecore.client.render.lighting.PostProcessLambda
|
import mods.betterfoliage.render.lighting.PostProcessLambda
|
||||||
import mods.octarinecore.client.render.Quad
|
import mods.betterfoliage.render.old.Model
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.render.old.Quad
|
||||||
import mods.octarinecore.common.Int3
|
import mods.betterfoliage.util.Double3
|
||||||
import mods.octarinecore.common.Rotation
|
import mods.betterfoliage.util.Int3
|
||||||
import mods.octarinecore.common.times
|
import mods.betterfoliage.util.PI2
|
||||||
|
import mods.betterfoliage.util.Rotation
|
||||||
|
import mods.betterfoliage.util.times
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.block.material.Material
|
import net.minecraft.block.material.Material
|
||||||
import net.minecraft.util.BlockRenderLayer
|
import net.minecraft.client.renderer.RenderType
|
||||||
|
import net.minecraft.client.renderer.RenderTypeLookup
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.DOWN
|
||||||
|
import net.minecraft.util.Direction.EAST
|
||||||
|
import net.minecraft.util.Direction.NORTH
|
||||||
|
import net.minecraft.util.Direction.SOUTH
|
||||||
|
import net.minecraft.util.Direction.UP
|
||||||
|
import net.minecraft.util.Direction.WEST
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
@@ -30,10 +38,13 @@ val greywash: PostProcessLambda = { _, _, _, _, _ -> setGrey(1.0f) }
|
|||||||
|
|
||||||
val BlockState.isSnow: Boolean get() = material.let { it == Material.SNOW }
|
val BlockState.isSnow: Boolean get() = material.let { it == Material.SNOW }
|
||||||
|
|
||||||
|
val DIRT_BLOCKS = listOf(Blocks.DIRT, Blocks.COARSE_DIRT)
|
||||||
|
|
||||||
fun Quad.toCross(rotAxis: Direction, trans: (Quad) -> Quad) =
|
fun Quad.toCross(rotAxis: Direction, trans: (Quad) -> Quad) =
|
||||||
(0..3).map { rotIdx ->
|
(0..3).map { rotIdx ->
|
||||||
trans(rotate(Rotation.rot90[rotAxis.ordinal] * rotIdx).mirrorUV(rotIdx > 1, false))
|
trans(rotate(Rotation.rot90[rotAxis.ordinal] * rotIdx).mirrorUV(rotIdx > 1, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Quad.toCross(rotAxis: Direction) = toCross(rotAxis) { it }
|
fun Quad.toCross(rotAxis: Direction) = toCross(rotAxis) { it }
|
||||||
|
|
||||||
fun xzDisk(modelIdx: Int) = (PI2 * modelIdx / 64.0).let { Double3(cos(it), 0.0, sin(it)) }
|
fun xzDisk(modelIdx: Int) = (PI2 * modelIdx / 64.0).let { Double3(cos(it), 0.0, sin(it)) }
|
||||||
@@ -59,7 +70,9 @@ fun Model.mix(first: Model, second: Model, predicate: (Int)->Boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val BlockRenderLayer.isCutout: Boolean get() = (this == BlockRenderLayer.CUTOUT) || (this == BlockRenderLayer.CUTOUT_MIPPED)
|
val RenderType.isCutout: Boolean get() = (this == RenderType.getCutout()) || (this == RenderType.getCutoutMipped())
|
||||||
|
|
||||||
fun BlockState.canRenderInLayer(layer: BlockRenderLayer) = this.block.canRenderInLayer(this, layer)
|
fun BlockState.canRenderInLayer(layer: RenderType) = RenderTypeLookup.canRenderInLayer(this, layer)
|
||||||
fun BlockState.canRenderInCutout() = this.block.canRenderInLayer(this, BlockRenderLayer.CUTOUT) || this.block.canRenderInLayer(this, BlockRenderLayer.CUTOUT_MIPPED)
|
fun BlockState.canRenderInCutout() =
|
||||||
|
RenderTypeLookup.canRenderInLayer(this, RenderType.getCutout()) ||
|
||||||
|
RenderTypeLookup.canRenderInLayer(this, RenderType.getCutoutMipped())
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.integration.ShadersModIntegration
|
||||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
import mods.betterfoliage.render.DIRT_BLOCKS
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.up1
|
||||||
|
import mods.betterfoliage.render.up2
|
||||||
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import net.minecraft.block.material.Material
|
import net.minecraft.block.material.Material
|
||||||
import net.minecraft.tags.BlockTags
|
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.world.biome.Biome
|
import net.minecraft.world.biome.Biome
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
|
|
||||||
class RenderAlgae : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
class RenderAlgae : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
||||||
|
|
||||||
@@ -24,8 +23,9 @@ class RenderAlgae : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bu
|
|||||||
Config.enabled && Config.algae.enabled &&
|
Config.enabled && Config.algae.enabled &&
|
||||||
ctx.state(up2).material == Material.WATER &&
|
ctx.state(up2).material == Material.WATER &&
|
||||||
ctx.state(up1).material == Material.WATER &&
|
ctx.state(up1).material == Material.WATER &&
|
||||||
BlockTags.DIRT_LIKE.contains(ctx.state.block) &&
|
DIRT_BLOCKS.contains(ctx.state.block) &&
|
||||||
ctx.biome.category.let { it == Biome.Category.OCEAN || it == Biome.Category.BEACH || it == Biome.Category.RIVER } &&
|
ctx.biome?.category
|
||||||
|
.let { it == Biome.Category.OCEAN || it == Biome.Category.BEACH || it == Biome.Category.RIVER } &&
|
||||||
noise[ctx.pos] < Config.algae.population
|
noise[ctx.pos] < Config.algae.population
|
||||||
|
|
||||||
override fun render(ctx: CombinedContext) {
|
override fun render(ctx: CombinedContext) {
|
||||||
@@ -1,29 +1,36 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.render.column.ColumnTextureInfo
|
import mods.betterfoliage.render.column.ColumnTextureInfo
|
||||||
import mods.betterfoliage.client.render.column.SimpleColumnInfo
|
import mods.betterfoliage.render.column.SimpleColumnInfo
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.render.lighting.cornerAo
|
||||||
import mods.octarinecore.client.render.*
|
import mods.betterfoliage.render.lighting.cornerAoMaxGreen
|
||||||
import mods.octarinecore.client.render.lighting.*
|
import mods.betterfoliage.render.lighting.edgeOrientedAuto
|
||||||
|
import mods.betterfoliage.render.lighting.faceOrientedAuto
|
||||||
|
import mods.betterfoliage.render.toCross
|
||||||
|
import mods.betterfoliage.render.xzDisk
|
||||||
|
import mods.betterfoliage.resource.Identifier
|
||||||
|
import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.octarinecore.client.resource.*
|
||||||
import mods.octarinecore.common.Rotation
|
import mods.betterfoliage.util.Rotation
|
||||||
import mods.octarinecore.common.config.ModelTextureList
|
import mods.betterfoliage.config.ModelTextureList
|
||||||
import mods.octarinecore.common.config.SimpleBlockMatcher
|
import mods.betterfoliage.config.SimpleBlockMatcher
|
||||||
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
|
import mods.betterfoliage.render.old.Vertex
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.CactusBlock
|
import net.minecraft.block.CactusBlock
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
object AsyncCactusDiscovery : ConfigurableModelDiscovery<ColumnTextureInfo>() {
|
object AsyncCactusDiscovery : ConfigurableModelDiscovery<ColumnTextureInfo>() {
|
||||||
override val logger = BetterFoliage.logDetail
|
override val logger = BetterFoliage.logDetail
|
||||||
override val matchClasses = SimpleBlockMatcher(CactusBlock::class.java)
|
override val matchClasses = SimpleBlockMatcher(CactusBlock::class.java)
|
||||||
override val modelTextures = listOf(ModelTextureList("block/cactus", "top", "bottom", "side"))
|
override val modelTextures = listOf(ModelTextureList("block/cactus", "top", "bottom", "side"))
|
||||||
override fun processModel(state: BlockState, textures: List<String>, atlas: AtlasFuture): CompletableFuture<ColumnTextureInfo>? {
|
override fun processModel(state: BlockState, textures: List<Identifier>, atlas: AtlasFuture): CompletableFuture<ColumnTextureInfo>? {
|
||||||
val sprites = textures.map { atlas.sprite(Identifier(it)) }
|
val sprites = textures.map { atlas.sprite(it) }
|
||||||
return atlas.mapAfter {
|
return atlas.mapAfter {
|
||||||
SimpleColumnInfo(
|
SimpleColumnInfo(
|
||||||
Axis.Y,
|
Axis.Y,
|
||||||
@@ -1,19 +1,22 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.texture.GrassRegistry
|
import mods.betterfoliage.render.DIRT_BLOCKS
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.isSnow
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.common.Int3
|
import mods.betterfoliage.render.up1
|
||||||
import mods.octarinecore.common.horizontalDirections
|
import mods.betterfoliage.render.up2
|
||||||
import mods.octarinecore.common.offset
|
import mods.betterfoliage.texture.GrassRegistry
|
||||||
import net.minecraft.tags.BlockTags
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
|
import mods.betterfoliage.util.Int3
|
||||||
|
import mods.betterfoliage.util.horizontalDirections
|
||||||
|
import mods.betterfoliage.util.offset
|
||||||
|
|
||||||
class RenderConnectedGrass : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
class RenderConnectedGrass : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
||||||
override fun isEligible(ctx: CombinedContext) =
|
override fun isEligible(ctx: CombinedContext) =
|
||||||
Config.enabled && Config.connectedGrass.enabled &&
|
Config.enabled && Config.connectedGrass.enabled &&
|
||||||
BlockTags.DIRT_LIKE.contains(ctx.state.block) &&
|
DIRT_BLOCKS.contains(ctx.state.block) &&
|
||||||
GrassRegistry[ctx, up1] != null &&
|
GrassRegistry[ctx, up1] != null &&
|
||||||
(Config.connectedGrass.snowEnabled || !ctx.state(up2).isSnow)
|
(Config.connectedGrass.snowEnabled || !ctx.state(up2).isSnow)
|
||||||
|
|
||||||
@@ -31,7 +34,7 @@ class RenderConnectedGrassLog : RenderDecorator(BetterFoliageMod.MOD_ID, BetterF
|
|||||||
|
|
||||||
override fun isEligible(ctx: CombinedContext) =
|
override fun isEligible(ctx: CombinedContext) =
|
||||||
Config.enabled && Config.roundLogs.enabled && Config.roundLogs.connectGrass &&
|
Config.enabled && Config.roundLogs.enabled && Config.roundLogs.connectGrass &&
|
||||||
BlockTags.DIRT_LIKE.contains(ctx.state.block) &&
|
DIRT_BLOCKS.contains(ctx.state.block) &&
|
||||||
LogRegistry[ctx, up1] != null
|
LogRegistry[ctx, up1] != null
|
||||||
|
|
||||||
override fun render(ctx: CombinedContext) {
|
override fun render(ctx: CombinedContext) {
|
||||||
@@ -1,21 +1,25 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.render.lighting.cornerAo
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.render.lighting.cornerFlat
|
||||||
import mods.octarinecore.client.render.*
|
import mods.betterfoliage.render.lighting.faceOrientedAuto
|
||||||
import mods.octarinecore.client.render.lighting.*
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.common.allDirections
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import mods.octarinecore.random
|
import mods.betterfoliage.render.rotationFromUp
|
||||||
|
import mods.betterfoliage.render.toCross
|
||||||
|
import mods.betterfoliage.render.up1
|
||||||
|
import mods.betterfoliage.render.up2
|
||||||
|
import mods.betterfoliage.render.xzDisk
|
||||||
|
import mods.betterfoliage.util.allDirections
|
||||||
|
import mods.betterfoliage.util.randomD
|
||||||
import net.minecraft.block.material.Material
|
import net.minecraft.block.material.Material
|
||||||
import net.minecraft.tags.BlockTags
|
import net.minecraft.tags.BlockTags
|
||||||
import net.minecraft.util.Direction.Axis
|
import net.minecraft.util.Direction.Axis
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.world.biome.Biome
|
import net.minecraft.world.biome.Biome
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
|
|
||||||
class RenderCoral : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
class RenderCoral : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
||||||
|
|
||||||
@@ -28,7 +32,7 @@ class RenderCoral : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bu
|
|||||||
.scale(Config.coral.size).move(0.5 to UP)
|
.scale(Config.coral.size).move(0.5 to UP)
|
||||||
.toCross(UP) { it.move(xzDisk(modelIdx) * Config.coral.hOffset) }.addAll()
|
.toCross(UP) { it.move(xzDisk(modelIdx) * Config.coral.hOffset) }.addAll()
|
||||||
|
|
||||||
val separation = random(0.01, Config.coral.vOffset)
|
val separation = randomD(0.01, Config.coral.vOffset)
|
||||||
horizontalRectangle(x1 = -0.5, x2 = 0.5, z1 = -0.5, z2 = 0.5, y = 0.0)
|
horizontalRectangle(x1 = -0.5, x2 = 0.5, z1 = -0.5, z2 = 0.5, y = 0.0)
|
||||||
.scale(Config.coral.crustSize).move(0.5 + separation to UP).add()
|
.scale(Config.coral.crustSize).move(0.5 + separation to UP).add()
|
||||||
|
|
||||||
@@ -43,7 +47,8 @@ class RenderCoral : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bu
|
|||||||
(ctx.state(up2).material == Material.WATER || Config.coral.shallowWater) &&
|
(ctx.state(up2).material == Material.WATER || Config.coral.shallowWater) &&
|
||||||
ctx.state(up1).material == Material.WATER &&
|
ctx.state(up1).material == Material.WATER &&
|
||||||
BlockTags.SAND.contains(ctx.state.block) &&
|
BlockTags.SAND.contains(ctx.state.block) &&
|
||||||
ctx.biome.category.let { it == Biome.Category.OCEAN || it == Biome.Category.BEACH } &&
|
ctx.biome?.category
|
||||||
|
.let { it == Biome.Category.OCEAN || it == Biome.Category.BEACH } &&
|
||||||
noise[ctx.pos] < Config.coral.population
|
noise[ctx.pos] < Config.coral.population
|
||||||
|
|
||||||
override fun render(ctx: CombinedContext) {
|
override fun render(ctx: CombinedContext) {
|
||||||
@@ -1,34 +1,37 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.integration.OptifineCustomColors
|
||||||
import mods.betterfoliage.client.integration.OptifineCustomColors
|
import mods.betterfoliage.integration.ShadersModIntegration
|
||||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
import mods.betterfoliage.render.DIRT_BLOCKS
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.render.down1
|
||||||
import mods.betterfoliage.client.texture.GeneratedGrass
|
import mods.betterfoliage.render.isSnow
|
||||||
import mods.betterfoliage.client.texture.GrassRegistry
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.resource.generated.GeneratedGrass
|
||||||
import mods.octarinecore.client.render.Model
|
import mods.betterfoliage.texture.GrassRegistry
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.old.Model
|
||||||
import mods.octarinecore.client.render.fullCube
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import mods.octarinecore.client.render.lighting.cornerAo
|
import mods.betterfoliage.render.old.fullCube
|
||||||
import mods.octarinecore.client.render.lighting.cornerFlat
|
import mods.betterfoliage.render.lighting.cornerAo
|
||||||
import mods.octarinecore.client.render.lighting.faceOrientedAuto
|
import mods.betterfoliage.render.lighting.cornerFlat
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.render.lighting.faceOrientedAuto
|
||||||
import mods.octarinecore.common.allDirections
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.random
|
import mods.betterfoliage.render.snowOffset
|
||||||
import net.minecraft.tags.BlockTags
|
import mods.betterfoliage.render.toCross
|
||||||
|
import mods.betterfoliage.render.xzDisk
|
||||||
|
import mods.betterfoliage.util.Double3
|
||||||
|
import mods.betterfoliage.util.allDirections
|
||||||
|
import mods.betterfoliage.util.randomD
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
|
|
||||||
class RenderGrass : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
class RenderGrass : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic fun grassTopQuads(heightMin: Double, heightMax: Double): Model.(Int)->Unit = { modelIdx ->
|
@JvmStatic fun grassTopQuads(heightMin: Double, heightMax: Double): Model.(Int)->Unit = { modelIdx ->
|
||||||
verticalRectangle(x1 = -0.5, z1 = 0.5, x2 = 0.5, z2 = -0.5, yBottom = 0.5,
|
verticalRectangle(x1 = -0.5, z1 = 0.5, x2 = 0.5, z2 = -0.5, yBottom = 0.5,
|
||||||
yTop = 0.5 + random(heightMin, heightMax)
|
yTop = 0.5 + randomD(heightMin, heightMax)
|
||||||
)
|
)
|
||||||
.setAoShader(faceOrientedAuto(overrideFace = UP, corner = cornerAo(Axis.Y)))
|
.setAoShader(faceOrientedAuto(overrideFace = UP, corner = cornerAo(Axis.Y)))
|
||||||
.setFlatShader(faceOrientedAuto(overrideFace = UP, corner = cornerFlat))
|
.setFlatShader(faceOrientedAuto(overrideFace = UP, corner = cornerFlat))
|
||||||
@@ -53,7 +56,7 @@ class RenderGrass : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bu
|
|||||||
override val onlyOnCutout get() = true
|
override val onlyOnCutout get() = true
|
||||||
|
|
||||||
override fun render(ctx: CombinedContext) {
|
override fun render(ctx: CombinedContext) {
|
||||||
val isConnected = BlockTags.DIRT_LIKE.contains(ctx.state(DOWN).block) || GrassRegistry[ctx, down1] != null
|
val isConnected = DIRT_BLOCKS.contains(ctx.state(DOWN).block) || GrassRegistry[ctx, down1] != null
|
||||||
val isSnowed = ctx.state(UP).isSnow
|
val isSnowed = ctx.state(UP).isSnow
|
||||||
val connectedGrass = isConnected && Config.connectedGrass.enabled && (!isSnowed || Config.connectedGrass.snowEnabled)
|
val connectedGrass = isConnected && Config.connectedGrass.enabled && (!isSnowed || Config.connectedGrass.snowEnabled)
|
||||||
|
|
||||||
@@ -1,22 +1,27 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.integration.OptifineCustomColors
|
import mods.betterfoliage.integration.OptifineCustomColors
|
||||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
import mods.betterfoliage.integration.ShadersModIntegration
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.render.denseLeavesRot
|
||||||
import mods.betterfoliage.client.texture.LeafRegistry
|
import mods.betterfoliage.render.isSnow
|
||||||
import mods.octarinecore.PI2
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.texture.LeafRegistry
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import mods.octarinecore.client.render.lighting.FlatOffset
|
import mods.betterfoliage.render.lighting.FlatOffset
|
||||||
import mods.octarinecore.client.render.lighting.cornerAoMaxGreen
|
import mods.betterfoliage.render.lighting.cornerAoMaxGreen
|
||||||
import mods.octarinecore.client.render.lighting.edgeOrientedAuto
|
import mods.betterfoliage.render.lighting.edgeOrientedAuto
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.render.normalLeavesRot
|
||||||
import mods.octarinecore.common.Int3
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.common.allDirections
|
import mods.betterfoliage.render.toCross
|
||||||
import mods.octarinecore.common.vec
|
import mods.betterfoliage.render.whitewash
|
||||||
import mods.octarinecore.random
|
import mods.betterfoliage.util.Double3
|
||||||
|
import mods.betterfoliage.util.Int3
|
||||||
|
import mods.betterfoliage.util.PI2
|
||||||
|
import mods.betterfoliage.util.allDirections
|
||||||
|
import mods.betterfoliage.util.randomD
|
||||||
|
import mods.betterfoliage.util.vec
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import java.lang.Math.cos
|
import java.lang.Math.cos
|
||||||
import java.lang.Math.sin
|
import java.lang.Math.sin
|
||||||
@@ -35,7 +40,7 @@ class RenderLeaves : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.b
|
|||||||
val perturbs = vectorSet(64) { idx ->
|
val perturbs = vectorSet(64) { idx ->
|
||||||
val angle = PI2 * idx / 64.0
|
val angle = PI2 * idx / 64.0
|
||||||
Double3(cos(angle), 0.0, sin(angle)) * Config.leaves.hOffset +
|
Double3(cos(angle), 0.0, sin(angle)) * Config.leaves.hOffset +
|
||||||
UP.vec * random(-1.0, 1.0) * Config.leaves.vOffset
|
UP.vec * randomD(-1.0, 1.0) * Config.leaves.vOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isEligible(ctx: CombinedContext) =
|
override fun isEligible(ctx: CombinedContext) =
|
||||||
@@ -1,19 +1,18 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.integration.ShadersModIntegration
|
||||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.lighting.FlatOffsetNoColor
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.client.render.lighting.FlatOffsetNoColor
|
import mods.betterfoliage.render.toCross
|
||||||
import mods.octarinecore.common.Int3
|
import mods.betterfoliage.render.xzDisk
|
||||||
|
import mods.betterfoliage.util.Int3
|
||||||
import net.minecraft.util.Direction.DOWN
|
import net.minecraft.util.Direction.DOWN
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
|
|
||||||
class RenderLilypad : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
class RenderLilypad : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
||||||
|
|
||||||
@@ -1,20 +1,23 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.chunk.ChunkOverlayManager
|
import mods.betterfoliage.chunk.ChunkOverlayManager
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.render.column.AbstractRenderColumn
|
import mods.betterfoliage.render.column.AbstractRenderColumn
|
||||||
import mods.betterfoliage.client.render.column.ColumnRenderLayer
|
import mods.betterfoliage.render.column.ColumnRenderLayer
|
||||||
import mods.betterfoliage.client.render.column.ColumnTextureInfo
|
import mods.betterfoliage.render.column.ColumnTextureInfo
|
||||||
import mods.betterfoliage.client.render.column.SimpleColumnInfo
|
import mods.betterfoliage.render.column.SimpleColumnInfo
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
|
||||||
|
import mods.betterfoliage.resource.discovery.ModelRenderRegistry
|
||||||
|
import mods.betterfoliage.resource.discovery.ModelRenderRegistryRoot
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.octarinecore.client.resource.*
|
||||||
import mods.octarinecore.common.config.ConfigurableBlockMatcher
|
import mods.betterfoliage.config.ConfigurableBlockMatcher
|
||||||
import mods.octarinecore.common.config.ModelTextureList
|
import mods.betterfoliage.config.ModelTextureList
|
||||||
import mods.octarinecore.tryDefault
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
|
import mods.betterfoliage.util.tryDefault
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.LogBlock
|
import net.minecraft.block.LogBlock
|
||||||
import net.minecraft.util.Direction.Axis
|
import net.minecraft.util.Direction.Axis
|
||||||
@@ -54,10 +57,10 @@ object AsyncLogDiscovery : ConfigurableModelDiscovery<ColumnTextureInfo>() {
|
|||||||
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.logBlocks
|
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.logBlocks
|
||||||
override val modelTextures: List<ModelTextureList> get() = BlockConfig.logModels.modelList
|
override val modelTextures: List<ModelTextureList> get() = BlockConfig.logModels.modelList
|
||||||
|
|
||||||
override fun processModel(state: BlockState, textures: List<String>, atlas: AtlasFuture): CompletableFuture<ColumnTextureInfo> {
|
override fun processModel(state: BlockState, textures: List<Identifier>, atlas: AtlasFuture): CompletableFuture<ColumnTextureInfo> {
|
||||||
val axis = getAxis(state)
|
val axis = getAxis(state)
|
||||||
logger.log(Level.DEBUG, "$logName: axis $axis")
|
logger.log(Level.DEBUG, "$logName: axis $axis")
|
||||||
val spriteList = textures.map { atlas.sprite(Identifier(it)) }
|
val spriteList = textures.map { atlas.sprite(it) }
|
||||||
return atlas.mapAfter {
|
return atlas.mapAfter {
|
||||||
SimpleColumnInfo(
|
SimpleColumnInfo(
|
||||||
axis,
|
axis,
|
||||||
@@ -1,22 +1,25 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.render.isSnow
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.old.noPost
|
||||||
import mods.octarinecore.client.render.noPost
|
import mods.betterfoliage.render.snowOffset
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.render.whitewash
|
||||||
|
import mods.betterfoliage.resource.Identifier
|
||||||
|
import mods.betterfoliage.util.Double3
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
|
|
||||||
class RenderMycelium : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
class RenderMycelium : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
||||||
|
|
||||||
val myceliumIcon = spriteSet { idx -> Identifier(BetterFoliageMod.MOD_ID, "blocks/better_mycel_$idx") }
|
val myceliumIcon = spriteSet { idx -> Identifier(BetterFoliageMod.MOD_ID, "blocks/better_mycel_$idx") }
|
||||||
val myceliumModel = modelSet(64) { idx -> RenderGrass.grassTopQuads(Config.shortGrass.heightMin, Config.shortGrass.heightMax)(idx) }
|
val myceliumModel = modelSet(64) { idx -> RenderGrass.grassTopQuads(
|
||||||
|
Config.shortGrass.heightMin,
|
||||||
|
Config.shortGrass.heightMax
|
||||||
|
)(idx) }
|
||||||
|
|
||||||
override fun isEligible(ctx: CombinedContext): Boolean {
|
override fun isEligible(ctx: CombinedContext): Boolean {
|
||||||
if (!Config.enabled || !Config.shortGrass.myceliumEnabled) return false
|
if (!Config.enabled || !Config.shortGrass.myceliumEnabled) return false
|
||||||
@@ -1,25 +1,26 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.render.lighting.cornerAo
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.render.lighting.cornerFlat
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.render.lighting.faceOrientedAuto
|
||||||
import mods.octarinecore.client.render.*
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.client.render.lighting.*
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import mods.octarinecore.random
|
import mods.betterfoliage.render.toCross
|
||||||
|
import mods.betterfoliage.render.xzDisk
|
||||||
|
import mods.betterfoliage.resource.Identifier
|
||||||
|
import mods.betterfoliage.util.randomD
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.util.Direction.Axis
|
import net.minecraft.util.Direction.Axis
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
|
|
||||||
class RenderNetherrack : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
class RenderNetherrack : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
||||||
|
|
||||||
val netherrackIcon = spriteSet { idx -> Identifier(BetterFoliageMod.MOD_ID, "blocks/better_netherrack_$idx") }
|
val netherrackIcon = spriteSet { idx -> Identifier(BetterFoliageMod.MOD_ID, "blocks/better_netherrack_$idx") }
|
||||||
val netherrackModel = modelSet(64) { modelIdx ->
|
val netherrackModel = modelSet(64) { modelIdx ->
|
||||||
verticalRectangle(x1 = -0.5, z1 = 0.5, x2 = 0.5, z2 = -0.5, yTop = -0.5,
|
verticalRectangle(x1 = -0.5, z1 = 0.5, x2 = 0.5, z2 = -0.5, yTop = -0.5,
|
||||||
yBottom = -0.5 - random(Config.netherrack.heightMin, Config.netherrack.heightMax))
|
yBottom = -0.5 - randomD(Config.netherrack.heightMin, Config.netherrack.heightMax))
|
||||||
.setAoShader(faceOrientedAuto(overrideFace = DOWN, corner = cornerAo(Axis.Y)))
|
.setAoShader(faceOrientedAuto(overrideFace = DOWN, corner = cornerAo(Axis.Y)))
|
||||||
.setFlatShader(faceOrientedAuto(overrideFace = DOWN, corner = cornerFlat))
|
.setFlatShader(faceOrientedAuto(overrideFace = DOWN, corner = cornerFlat))
|
||||||
.toCross(UP) { it.move(xzDisk(modelIdx) * Config.shortGrass.hOffset) }.addAll()
|
.toCross(UP) { it.move(xzDisk(modelIdx) * Config.shortGrass.hOffset) }.addAll()
|
||||||
@@ -1,20 +1,22 @@
|
|||||||
package mods.betterfoliage.client.render
|
package mods.betterfoliage.render.block.vanillaold
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.integration.ShadersModIntegration
|
||||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
import mods.betterfoliage.render.DIRT_BLOCKS
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.lighting.FlatOffsetNoColor
|
||||||
import mods.octarinecore.client.render.lighting.FlatOffsetNoColor
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.client.resource.CenteredSprite
|
import mods.betterfoliage.render.toCross
|
||||||
import mods.octarinecore.random
|
import mods.betterfoliage.render.up1
|
||||||
|
import mods.betterfoliage.render.up2
|
||||||
|
import mods.betterfoliage.render.xzDisk
|
||||||
|
import mods.betterfoliage.resource.generated.CenteredSprite
|
||||||
|
import mods.betterfoliage.util.randomD
|
||||||
import net.minecraft.block.material.Material
|
import net.minecraft.block.material.Material
|
||||||
import net.minecraft.tags.BlockTags
|
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
|
||||||
|
|
||||||
class RenderReeds : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
class RenderReeds : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bus) {
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ class RenderReeds : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bu
|
|||||||
register = { CenteredSprite(it).register(BetterFoliage.asyncPack) }
|
register = { CenteredSprite(it).register(BetterFoliage.asyncPack) }
|
||||||
)
|
)
|
||||||
val reedModels = modelSet(64) { modelIdx ->
|
val reedModels = modelSet(64) { modelIdx ->
|
||||||
val height = random(Config.reed.heightMin, Config.reed.heightMax)
|
val height = randomD(Config.reed.heightMin, Config.reed.heightMax)
|
||||||
val waterline = 0.875f
|
val waterline = 0.875f
|
||||||
val vCutLine = 0.5 - waterline / height
|
val vCutLine = 0.5 - waterline / height
|
||||||
listOf(
|
listOf(
|
||||||
@@ -45,8 +47,9 @@ class RenderReeds : RenderDecorator(BetterFoliageMod.MOD_ID, BetterFoliageMod.bu
|
|||||||
Config.enabled && Config.reed.enabled &&
|
Config.enabled && Config.reed.enabled &&
|
||||||
ctx.state(up2).material == Material.AIR &&
|
ctx.state(up2).material == Material.AIR &&
|
||||||
ctx.state(UP).material == Material.WATER &&
|
ctx.state(UP).material == Material.WATER &&
|
||||||
BlockTags.DIRT_LIKE.contains(ctx.state.block) &&
|
DIRT_BLOCKS.contains(ctx.state.block) &&
|
||||||
ctx.biome.let { it.downfall > Config.reed.minBiomeRainfall && it.defaultTemperature >= Config.reed.minBiomeTemp } &&
|
ctx.biome
|
||||||
|
?.let { it.downfall > Config.reed.minBiomeRainfall && it.defaultTemperature >= Config.reed.minBiomeTemp } ?: false &&
|
||||||
noise[ctx.pos] < Config.reed.population
|
noise[ctx.pos] < Config.reed.population
|
||||||
|
|
||||||
override val onlyOnCutout get() = false
|
override val onlyOnCutout get() = false
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
package mods.betterfoliage.client.render.column
|
package mods.betterfoliage.render.column
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.chunk.ChunkOverlayManager
|
||||||
import mods.betterfoliage.client.chunk.ChunkOverlayManager
|
import mods.betterfoliage.integration.ShadersModIntegration.renderAs
|
||||||
import mods.betterfoliage.client.integration.ShadersModIntegration.renderAs
|
import mods.betterfoliage.render.*
|
||||||
import mods.betterfoliage.client.render.*
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.*
|
||||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.BlockType.*
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType
|
||||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.QuadrantType
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.*
|
||||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.QuadrantType.*
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.old.Model
|
||||||
import mods.octarinecore.client.render.Model
|
import mods.betterfoliage.render.old.RenderDecorator
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.betterfoliage.render.old.noPost
|
||||||
import mods.octarinecore.client.render.noPost
|
import mods.betterfoliage.util.Rotation
|
||||||
import mods.octarinecore.common.Rotation
|
import mods.betterfoliage.util.face
|
||||||
import mods.octarinecore.common.face
|
import mods.betterfoliage.util.rot
|
||||||
import mods.octarinecore.common.rot
|
|
||||||
import net.minecraft.block.BlockRenderType.MODEL
|
import net.minecraft.block.BlockRenderType.MODEL
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import net.minecraftforge.eventbus.api.IEventBus
|
import net.minecraftforge.eventbus.api.IEventBus
|
||||||
@@ -1,22 +1,25 @@
|
|||||||
package mods.betterfoliage.client.render.column
|
package mods.betterfoliage.render.column
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.chunk.ChunkOverlayLayer
|
||||||
import mods.betterfoliage.client.chunk.ChunkOverlayLayer
|
import mods.betterfoliage.chunk.ChunkOverlayManager
|
||||||
import mods.betterfoliage.client.chunk.ChunkOverlayManager
|
import mods.betterfoliage.chunk.dimType
|
||||||
import mods.betterfoliage.client.chunk.dimType
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.*
|
||||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.BlockType.*
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType
|
||||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.QuadrantType
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.*
|
||||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.QuadrantType.*
|
import mods.betterfoliage.render.rotationFromUp
|
||||||
import mods.betterfoliage.client.render.rotationFromUp
|
import mods.betterfoliage.render.old.BlockCtx
|
||||||
import mods.octarinecore.client.render.BlockCtx
|
import mods.betterfoliage.resource.discovery.ModelRenderRegistry
|
||||||
import mods.octarinecore.client.resource.ModelRenderRegistry
|
import mods.betterfoliage.util.Int3
|
||||||
import mods.octarinecore.common.*
|
import mods.betterfoliage.util.Rotation
|
||||||
|
import mods.betterfoliage.util.allDirections
|
||||||
|
import mods.betterfoliage.util.face
|
||||||
|
import mods.betterfoliage.util.plus
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.util.Direction.Axis
|
import net.minecraft.util.Direction.Axis
|
||||||
import net.minecraft.util.Direction.AxisDirection
|
import net.minecraft.util.Direction.AxisDirection
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
import net.minecraft.world.ILightReader
|
||||||
|
|
||||||
/** Index of SOUTH-EAST quadrant. */
|
/** Index of SOUTH-EAST quadrant. */
|
||||||
const val SE = 0
|
const val SE = 0
|
||||||
@@ -68,7 +71,7 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
|
|||||||
|
|
||||||
val allNeighborOffsets = (-1..1).flatMap { offsetX -> (-1..1).flatMap { offsetY -> (-1..1).map { offsetZ -> Int3(offsetX, offsetY, offsetZ) }}}
|
val allNeighborOffsets = (-1..1).flatMap { offsetX -> (-1..1).flatMap { offsetY -> (-1..1).map { offsetZ -> Int3(offsetX, offsetY, offsetZ) }}}
|
||||||
|
|
||||||
override fun onBlockUpdate(world: IEnviromentBlockReader, pos: BlockPos) {
|
override fun onBlockUpdate(world: ILightReader, pos: BlockPos) {
|
||||||
allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(world.dimType, this, pos + offset) }
|
allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(world.dimType, this, pos + offset) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package mods.betterfoliage.client.render.column
|
package mods.betterfoliage.render.column
|
||||||
|
|
||||||
import mods.octarinecore.client.render.lighting.QuadIconResolver
|
import mods.betterfoliage.render.lighting.QuadIconResolver
|
||||||
import mods.octarinecore.common.rotate
|
import mods.betterfoliage.util.rotate
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
|
|
||||||
@@ -1,7 +1,18 @@
|
|||||||
package mods.octarinecore.client.render.lighting
|
package mods.betterfoliage.render.lighting
|
||||||
|
|
||||||
import mods.octarinecore.client.render.*
|
import mods.betterfoliage.render.old.Quad
|
||||||
import mods.octarinecore.common.*
|
import mods.betterfoliage.render.old.Vertex
|
||||||
|
import mods.betterfoliage.util.Double3
|
||||||
|
import mods.betterfoliage.util.Rotation
|
||||||
|
import mods.betterfoliage.util.axes
|
||||||
|
import mods.betterfoliage.util.boxEdges
|
||||||
|
import mods.betterfoliage.util.boxFaces
|
||||||
|
import mods.betterfoliage.util.face
|
||||||
|
import mods.betterfoliage.util.get
|
||||||
|
import mods.betterfoliage.util.nearestAngle
|
||||||
|
import mods.betterfoliage.util.nearestPosition
|
||||||
|
import mods.betterfoliage.util.perpendiculars
|
||||||
|
import mods.betterfoliage.util.vec
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import java.lang.Math.min
|
import java.lang.Math.min
|
||||||
@@ -124,7 +135,8 @@ fun faceOrientedAuto(overrideFace: Direction? = null,
|
|||||||
* @param[corner] ModelLighter instantiation lambda
|
* @param[corner] ModelLighter instantiation lambda
|
||||||
*/
|
*/
|
||||||
fun edgeOrientedAuto(overrideEdge: Pair<Direction, Direction>? = null,
|
fun edgeOrientedAuto(overrideEdge: Pair<Direction, Direction>? = null,
|
||||||
corner: CornerShaderFactory) =
|
corner: CornerShaderFactory
|
||||||
|
) =
|
||||||
fun(quad: Quad, vertex: Vertex): ModelLighter {
|
fun(quad: Quad, vertex: Vertex): ModelLighter {
|
||||||
val edgeDir = overrideEdge ?: nearestAngle(quad.normal, boxEdges) { it.first.vec + it.second.vec }.first
|
val edgeDir = overrideEdge ?: nearestAngle(quad.normal, boxEdges) { it.first.vec + it.second.vec }.first
|
||||||
val nearestFace = nearestPosition(vertex.xyz, edgeDir.toList()) { it.vec }.first
|
val nearestFace = nearestPosition(vertex.xyz, edgeDir.toList()) { it.vec }.first
|
||||||
@@ -1,11 +1,18 @@
|
|||||||
package mods.octarinecore.client.render.lighting
|
package mods.betterfoliage.render.lighting
|
||||||
|
|
||||||
import mods.octarinecore.client.render.BlockCtx
|
import mods.betterfoliage.render.old.BlockCtx
|
||||||
import mods.octarinecore.common.*
|
import mods.betterfoliage.util.Int3
|
||||||
|
import mods.betterfoliage.util.Rotation
|
||||||
|
import mods.betterfoliage.util.allDirections
|
||||||
|
import mods.betterfoliage.util.boxFaces
|
||||||
|
import mods.betterfoliage.util.get
|
||||||
|
import mods.betterfoliage.util.offset
|
||||||
|
import mods.betterfoliage.util.plus
|
||||||
|
import mods.betterfoliage.util.rotate
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.BlockModelRenderer
|
import net.minecraft.client.renderer.BlockModelRenderer
|
||||||
|
import net.minecraft.client.renderer.WorldRenderer
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val Direction.aoMultiplier: Float get() = when(this) {
|
val Direction.aoMultiplier: Float get() = when(this) {
|
||||||
@@ -26,7 +33,7 @@ interface LightingCtx {
|
|||||||
fun color(face: Direction) = color(face.offset)
|
fun color(face: Direction) = color(face.offset)
|
||||||
|
|
||||||
fun brightness(offset: Int3) = offset.rotate(modelRotation).let {
|
fun brightness(offset: Int3) = offset.rotate(modelRotation).let {
|
||||||
blockContext.state(it).getPackedLightmapCoords(blockContext.world, blockContext.pos + it)
|
WorldRenderer.getCombinedLight(blockContext.world, blockContext.pos + it)
|
||||||
}
|
}
|
||||||
fun color(offset: Int3) = blockContext.offset(offset.rotate(modelRotation)).let { Minecraft.getInstance().blockColors.getColor(it.state, it.world, it.pos, 0) }
|
fun color(offset: Int3) = blockContext.offset(offset.rotate(modelRotation)).let { Minecraft.getInstance().blockColors.getColor(it.state, it.world, it.pos, 0) }
|
||||||
|
|
||||||
@@ -94,7 +101,7 @@ class FaceLightData(val face: Direction) {
|
|||||||
fun update(blockCtx: BlockCtx, multiplier: Float) {
|
fun update(blockCtx: BlockCtx, multiplier: Float) {
|
||||||
val quadBounds = FloatArray(12)
|
val quadBounds = FloatArray(12)
|
||||||
val flags = BitSet(3).apply { set(0) }
|
val flags = BitSet(3).apply { set(0) }
|
||||||
delegate.updateVertexBrightness(blockCtx.world, blockCtx.state, blockCtx.pos, face, quadBounds, flags)
|
// delegate.updateVertexBrightness(blockCtx.world, blockCtx.state, blockCtx.pos, face, quadBounds, flags)
|
||||||
vanillaOrdered.forEachIndexed { idx, corner -> corner.set(delegate.vertexBrightness[idx], delegate.vertexColorMultiplier[idx] * multiplier) }
|
vanillaOrdered.forEachIndexed { idx, corner -> corner.set(delegate.vertexBrightness[idx], delegate.vertexColorMultiplier[idx] * multiplier) }
|
||||||
isValid = true
|
isValid = true
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
package mods.octarinecore.client.render.lighting
|
package mods.betterfoliage.render.lighting
|
||||||
|
|
||||||
import mods.octarinecore.common.*
|
import mods.betterfoliage.util.Int3
|
||||||
|
import mods.betterfoliage.util.Rotation
|
||||||
|
import mods.betterfoliage.util.axes
|
||||||
|
import mods.betterfoliage.util.boxFaces
|
||||||
|
import mods.betterfoliage.util.face
|
||||||
|
import mods.betterfoliage.util.get
|
||||||
|
import mods.betterfoliage.util.offset
|
||||||
|
import mods.betterfoliage.util.rotate
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
|
|
||||||
|
|
||||||
@@ -34,7 +41,8 @@ object NoLighting : ModelLighter {
|
|||||||
override fun rotate(rot: Rotation) = this
|
override fun rotate(rot: Rotation) = this
|
||||||
}
|
}
|
||||||
|
|
||||||
class CornerSingleFallback(val face: Direction, val dir1: Direction, val dir2: Direction, val fallbackDir: Direction, val fallbackDimming: Float = defaultCornerDimming) : ModelLighter {
|
class CornerSingleFallback(val face: Direction, val dir1: Direction, val dir2: Direction, val fallbackDir: Direction, val fallbackDimming: Float = defaultCornerDimming) :
|
||||||
|
ModelLighter {
|
||||||
val offset = Int3(fallbackDir)
|
val offset = Int3(fallbackDir)
|
||||||
override fun shade(context: LightingCtx, vertex: RenderVertex) {
|
override fun shade(context: LightingCtx, vertex: RenderVertex) {
|
||||||
val shading = context.lighting(face, dir1, dir2)
|
val shading = context.lighting(face, dir1, dir2)
|
||||||
@@ -72,7 +80,8 @@ class CornerTri(val face: Direction, val dir1: Direction, val dir2: Direction,
|
|||||||
override fun rotate(rot: Rotation) = CornerTri(face.rotate(rot), dir1.rotate(rot), dir2.rotate(rot), func)
|
override fun rotate(rot: Rotation) = CornerTri(face.rotate(rot), dir1.rotate(rot), dir2.rotate(rot), func)
|
||||||
}
|
}
|
||||||
|
|
||||||
class EdgeInterpolateFallback(val face: Direction, val edgeDir: Direction, val pos: Double, val fallbackDimming: Float = defaultEdgeDimming): ModelLighter {
|
class EdgeInterpolateFallback(val face: Direction, val edgeDir: Direction, val pos: Double, val fallbackDimming: Float = defaultEdgeDimming):
|
||||||
|
ModelLighter {
|
||||||
val offset = Int3(edgeDir)
|
val offset = Int3(edgeDir)
|
||||||
val edgeAxis = axes.find { it != face.axis && it != edgeDir.axis }!!
|
val edgeAxis = axes.find { it != face.axis && it != edgeDir.axis }!!
|
||||||
val weightN = (0.5 - pos).toFloat()
|
val weightN = (0.5 - pos).toFloat()
|
||||||
@@ -92,7 +101,8 @@ class EdgeInterpolateFallback(val face: Direction, val edgeDir: Direction, val p
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CornerInterpolateDimming(val face1: Direction, val face2: Direction, val edgeDir: Direction,
|
class CornerInterpolateDimming(val face1: Direction, val face2: Direction, val edgeDir: Direction,
|
||||||
val weight: Float, val dimming: Float, val fallbackDimming: Float = defaultCornerDimming) : ModelLighter {
|
val weight: Float, val dimming: Float, val fallbackDimming: Float = defaultCornerDimming
|
||||||
|
) : ModelLighter {
|
||||||
val offset = Int3(edgeDir)
|
val offset = Int3(edgeDir)
|
||||||
override fun shade(context: LightingCtx, vertex: RenderVertex) {
|
override fun shade(context: LightingCtx, vertex: RenderVertex) {
|
||||||
var shading1 = context.lighting(face1, edgeDir, face2)
|
var shading1 = context.lighting(face1, edgeDir, face2)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
@file:JvmName("PixelFormat")
|
||||||
|
package mods.betterfoliage.render.lighting
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package mods.octarinecore.client.render.lighting
|
package mods.betterfoliage.render.lighting
|
||||||
|
|
||||||
import mods.octarinecore.client.render.CombinedContext
|
import mods.betterfoliage.render.old.CombinedContext
|
||||||
import mods.octarinecore.client.render.Quad
|
import mods.betterfoliage.render.old.Quad
|
||||||
import mods.octarinecore.client.render.Vertex
|
import mods.betterfoliage.render.old.Vertex
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.util.Double3
|
||||||
import mods.octarinecore.common.Rotation
|
import mods.betterfoliage.util.Rotation
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
package mods.betterfoliage.render.old
|
||||||
|
|
||||||
|
import mods.betterfoliage.util.Double3
|
||||||
|
import mods.betterfoliage.util.PI2
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
|
import net.minecraft.client.particle.IParticleRenderType
|
||||||
|
import net.minecraft.client.particle.SpriteTexturedParticle
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
abstract class AbstractEntityFX(world: World, x: Double, y: Double, z: Double) : SpriteTexturedParticle(world, x, y, z) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic val sin = Array(64) { idx -> sin(PI2 / 64.0 * idx) }
|
||||||
|
@JvmStatic val cos = Array(64) { idx -> cos(PI2 / 64.0 * idx) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val billboardRot = Pair(Double3.zero, Double3.zero)
|
||||||
|
val currentPos = Double3.zero
|
||||||
|
val prevPos = Double3.zero
|
||||||
|
val velocity = Double3.zero
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
super.tick()
|
||||||
|
currentPos.setTo(posX, posY, posZ)
|
||||||
|
prevPos.setTo(prevPosX, prevPosY, prevPosZ)
|
||||||
|
velocity.setTo(motionX, motionY, motionZ)
|
||||||
|
update()
|
||||||
|
posX = currentPos.x; posY = currentPos.y; posZ = currentPos.z;
|
||||||
|
motionX = velocity.x; motionY = velocity.y; motionZ = velocity.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Render the particle. */
|
||||||
|
abstract fun render(worldRenderer: BufferBuilder, partialTickTime: Float)
|
||||||
|
|
||||||
|
/** Update particle on world tick. */
|
||||||
|
abstract fun update()
|
||||||
|
|
||||||
|
/** True if the particle is renderable. */
|
||||||
|
abstract val isValid: Boolean
|
||||||
|
|
||||||
|
/** Add the particle to the effect renderer if it is valid. */
|
||||||
|
fun addIfValid() { if (isValid) Minecraft.getInstance().particles.addEffect(this) }
|
||||||
|
|
||||||
|
// override fun renderParticle(buffer: BufferBuilder, entity: ActiveRenderInfo, partialTicks: Float, rotX: Float, rotZ: Float, rotYZ: Float, rotXY: Float, rotXZ: Float) {
|
||||||
|
// billboardRot.first.setTo(rotX + rotXY, rotZ, rotYZ + rotXZ)
|
||||||
|
// billboardRot.second.setTo(rotX - rotXY, -rotZ, rotYZ - rotXZ)
|
||||||
|
// render(buffer, partialTicks)
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
* Render a particle quad.
|
||||||
|
*
|
||||||
|
* @param[tessellator] the [Tessellator] instance to use
|
||||||
|
* @param[partialTickTime] partial tick time
|
||||||
|
* @param[currentPos] render position
|
||||||
|
* @param[prevPos] previous tick position for interpolation
|
||||||
|
* @param[size] particle size
|
||||||
|
* @param[rotation] viewpoint-dependent particle rotation (64 steps)
|
||||||
|
* @param[icon] particle texture
|
||||||
|
* @param[isMirrored] mirror particle texture along V-axis
|
||||||
|
* @param[alpha] aplha blending
|
||||||
|
*/
|
||||||
|
// fun renderParticleQuad(worldRenderer: BufferBuilder,
|
||||||
|
// partialTickTime: Float,
|
||||||
|
// currentPos: Double3 = this.currentPos,
|
||||||
|
// prevPos: Double3 = this.prevPos,
|
||||||
|
// size: Double = particleScale.toDouble(),
|
||||||
|
// rotation: Int = 0,
|
||||||
|
// icon: TextureAtlasSprite = sprite,
|
||||||
|
// isMirrored: Boolean = false,
|
||||||
|
// alpha: Float = this.particleAlpha) {
|
||||||
|
//
|
||||||
|
// val minU = (if (isMirrored) icon.minU else icon.maxU).toDouble()
|
||||||
|
// val maxU = (if (isMirrored) icon.maxU else icon.minU).toDouble()
|
||||||
|
// val minV = icon.minV.toDouble()
|
||||||
|
// val maxV = icon.maxV.toDouble()
|
||||||
|
//
|
||||||
|
// val center = currentPos.copy().sub(prevPos).mul(partialTickTime.toDouble()).add(prevPos).sub(interpPosX, interpPosY, interpPosZ)
|
||||||
|
// val v1 = if (rotation == 0) billboardRot.first * size else
|
||||||
|
// Double3.weight(billboardRot.first, cos[rotation and 63] * size, billboardRot.second, sin[rotation and 63] * size)
|
||||||
|
// val v2 = if (rotation == 0) billboardRot.second * size else
|
||||||
|
// Double3.weight(billboardRot.first, -sin[rotation and 63] * size, billboardRot.second, cos[rotation and 63] * size)
|
||||||
|
//
|
||||||
|
// val renderBrightness = this.getBrightnessForRender(partialTickTime)
|
||||||
|
// val brLow = renderBrightness shr 16 and 65535
|
||||||
|
// val brHigh = renderBrightness and 65535
|
||||||
|
//
|
||||||
|
// worldRenderer
|
||||||
|
// .pos(center.x - v1.x, center.y - v1.y, center.z - v1.z)
|
||||||
|
// .tex(maxU, maxV)
|
||||||
|
// .color(particleRed, particleGreen, particleBlue, alpha)
|
||||||
|
// .lightmap(brLow, brHigh)
|
||||||
|
// .endVertex()
|
||||||
|
//
|
||||||
|
// worldRenderer
|
||||||
|
// .pos(center.x - v2.x, center.y - v2.y, center.z - v2.z)
|
||||||
|
// .tex(maxU, minV)
|
||||||
|
// .color(particleRed, particleGreen, particleBlue, alpha)
|
||||||
|
// .lightmap(brLow, brHigh)
|
||||||
|
// .endVertex()
|
||||||
|
//
|
||||||
|
// worldRenderer
|
||||||
|
// .pos(center.x + v1.x, center.y + v1.y, center.z + v1.z)
|
||||||
|
// .tex(minU, minV)
|
||||||
|
// .color(particleRed, particleGreen, particleBlue, alpha)
|
||||||
|
// .lightmap(brLow, brHigh)
|
||||||
|
// .endVertex()
|
||||||
|
//
|
||||||
|
// worldRenderer
|
||||||
|
// .pos(center.x + v2.x, center.y + v2.y, center.z + v2.z)
|
||||||
|
// .tex(minU, maxV)
|
||||||
|
// .color(particleRed, particleGreen, particleBlue, alpha)
|
||||||
|
// .lightmap(brLow, brHigh)
|
||||||
|
// .endVertex()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// override fun getFXLayer() = 1
|
||||||
|
override fun getRenderType(): IParticleRenderType = IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT
|
||||||
|
|
||||||
|
fun setColor(color: Int) {
|
||||||
|
particleBlue = (color and 255) / 256.0f
|
||||||
|
particleGreen = ((color shr 8) and 255) / 256.0f
|
||||||
|
particleRed = ((color shr 16) and 255) / 256.0f
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,20 @@
|
|||||||
package mods.octarinecore.client.render
|
package mods.betterfoliage.render.old
|
||||||
|
|
||||||
import mods.octarinecore.common.*
|
import com.mojang.blaze3d.matrix.MatrixStack
|
||||||
import mods.octarinecore.semiRandom
|
import com.mojang.blaze3d.vertex.IVertexBuilder
|
||||||
|
import mods.betterfoliage.util.Int3
|
||||||
|
import mods.betterfoliage.util.allDirections
|
||||||
|
import mods.betterfoliage.util.offset
|
||||||
|
import mods.betterfoliage.util.plus
|
||||||
|
import mods.betterfoliage.util.semiRandom
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||||
import net.minecraft.client.renderer.BufferBuilder
|
import net.minecraft.client.renderer.RenderType
|
||||||
import net.minecraft.util.BlockRenderLayer
|
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.ILightReader
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
import net.minecraft.world.IWorldReader
|
||||||
import net.minecraft.world.World
|
|
||||||
import net.minecraft.world.biome.Biome
|
import net.minecraft.world.biome.Biome
|
||||||
import net.minecraftforge.client.model.data.IModelData
|
import net.minecraftforge.client.model.data.IModelData
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -21,7 +24,7 @@ import java.util.*
|
|||||||
* block-relative coordinates.
|
* block-relative coordinates.
|
||||||
*/
|
*/
|
||||||
interface BlockCtx {
|
interface BlockCtx {
|
||||||
val world: IEnviromentBlockReader
|
val world: ILightReader
|
||||||
val pos: BlockPos
|
val pos: BlockPos
|
||||||
|
|
||||||
fun offset(dir: Direction) = offset(dir.offset)
|
fun offset(dir: Direction) = offset(dir.offset)
|
||||||
@@ -31,21 +34,21 @@ interface BlockCtx {
|
|||||||
fun state(dir: Direction) = world.getBlockState(pos + dir.offset)
|
fun state(dir: Direction) = world.getBlockState(pos + dir.offset)
|
||||||
fun state(offset: Int3) = world.getBlockState(pos + offset)
|
fun state(offset: Int3) = world.getBlockState(pos + offset)
|
||||||
|
|
||||||
val biome: Biome get() = world.getBiome(pos)
|
val biome: Biome? get() = (world as? IWorldReader)?.getBiome(pos)
|
||||||
|
|
||||||
val isNormalCube: Boolean get() = state.isNormalCube(world, pos)
|
val isNormalCube: Boolean get() = state.isNormalCube(world, pos)
|
||||||
|
|
||||||
fun shouldSideBeRendered(side: Direction) = Block.shouldSideBeRendered(state, world, pos, side)
|
fun shouldSideBeRendered(side: Direction) = Block.shouldSideBeRendered(state, world, pos, side)
|
||||||
|
|
||||||
/** Get a semi-random value based on the block coordinate and the given seed. */
|
/** Get a semi-random value based on the block coordinate and the given seed. */
|
||||||
fun semiRandom(seed: Int) = semiRandom(pos.x, pos.y, pos.z, seed)
|
fun semiRandom(seed: Int) = pos.semiRandom(seed)
|
||||||
|
|
||||||
/** Get an array of semi-random values based on the block coordinate. */
|
/** Get an array of semi-random values based on the block coordinate. */
|
||||||
fun semiRandomArray(num: Int): Array<Int> = Array(num) { semiRandom(it) }
|
fun semiRandomArray(num: Int): Array<Int> = Array(num) { semiRandom(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
open class BasicBlockCtx(
|
open class BasicBlockCtx(
|
||||||
override val world: IEnviromentBlockReader,
|
override val world: ILightReader,
|
||||||
override val pos: BlockPos
|
override val pos: BlockPos
|
||||||
) : BlockCtx {
|
) : BlockCtx {
|
||||||
override var state: BlockState = world.getBlockState(pos)
|
override var state: BlockState = world.getBlockState(pos)
|
||||||
@@ -54,20 +57,24 @@ open class BasicBlockCtx(
|
|||||||
fun cache() = CachedBlockCtx(world, pos)
|
fun cache() = CachedBlockCtx(world, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class CachedBlockCtx(world: IEnviromentBlockReader, pos: BlockPos) : BasicBlockCtx(world, pos) {
|
open class CachedBlockCtx(world: ILightReader, pos: BlockPos) : BasicBlockCtx(world, pos) {
|
||||||
var neighbors = Array<BlockState>(6) { world.getBlockState(pos + allDirections[it].offset) }
|
var neighbors = Array<BlockState>(6) { world.getBlockState(pos + allDirections[it].offset) }
|
||||||
override var biome: Biome = world.getBiome(pos)
|
override var biome: Biome? = super.biome
|
||||||
override fun state(dir: Direction) = neighbors[dir.ordinal]
|
override fun state(dir: Direction) = neighbors[dir.ordinal]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
data class RenderCtx(
|
data class RenderCtx(
|
||||||
val dispatcher: BlockRendererDispatcher,
|
val dispatcher: BlockRendererDispatcher,
|
||||||
val renderBuffer: BufferBuilder,
|
val renderBuffer: IVertexBuilder,
|
||||||
val layer: BlockRenderLayer,
|
val matrixStack: MatrixStack,
|
||||||
|
val layer: RenderType,
|
||||||
|
val checkSides: Boolean,
|
||||||
val random: Random,
|
val random: Random,
|
||||||
val modelData: IModelData
|
val modelData: IModelData
|
||||||
) {
|
) {
|
||||||
fun render(worldBlock: BlockCtx) = dispatcher.renderBlock(worldBlock.state, worldBlock.pos, worldBlock.world, renderBuffer, random, modelData)
|
fun render(worldBlock: BlockCtx) =
|
||||||
|
// dispatcher.renderBlock(worldBlock.state, worldBlock.pos, worldBlock.world, renderBuffer, random, modelData)
|
||||||
|
dispatcher.renderModel(worldBlock.state, worldBlock.pos, worldBlock.world, matrixStack, renderBuffer, checkSides, random, modelData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,23 +1,27 @@
|
|||||||
package mods.octarinecore.client.render
|
package mods.betterfoliage.render.old
|
||||||
|
|
||||||
import mods.betterfoliage.client.render.canRenderInCutout
|
import mods.betterfoliage.render.canRenderInCutout
|
||||||
import mods.betterfoliage.client.render.isCutout
|
import mods.betterfoliage.render.isCutout
|
||||||
import mods.octarinecore.BufferBuilder
|
import mods.betterfoliage.render.lighting.DefaultLightingCtx
|
||||||
|
import mods.betterfoliage.render.lighting.LightingCtx
|
||||||
|
import mods.betterfoliage.render.lighting.PostProcessLambda
|
||||||
|
import mods.betterfoliage.render.lighting.QuadIconResolver
|
||||||
|
import mods.betterfoliage.render.lighting.RenderVertex
|
||||||
import mods.octarinecore.BufferBuilder_setSprite
|
import mods.octarinecore.BufferBuilder_setSprite
|
||||||
import mods.octarinecore.client.render.lighting.*
|
import mods.betterfoliage.util.Double3
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.util.Int3
|
||||||
import mods.octarinecore.common.Int3
|
import mods.betterfoliage.util.Rotation
|
||||||
import mods.octarinecore.common.Rotation
|
import mods.betterfoliage.util.plus
|
||||||
import mods.octarinecore.common.plus
|
|
||||||
import mods.octarinecore.metaprog.get
|
|
||||||
import mods.octarinecore.metaprog.set
|
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
|
import net.minecraft.client.renderer.RenderTypeLookup
|
||||||
|
import net.minecraft.client.renderer.Vector3f
|
||||||
|
import net.minecraft.client.renderer.Vector4f
|
||||||
import net.minecraft.fluid.Fluids
|
import net.minecraft.fluid.Fluids
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
import net.minecraft.world.ILightReader
|
||||||
import net.minecraft.world.LightType
|
import net.minecraft.world.LightType
|
||||||
import net.minecraft.world.biome.Biomes
|
import net.minecraft.world.level.ColorResolver
|
||||||
|
|
||||||
class CombinedContext(
|
class CombinedContext(
|
||||||
val blockCtx: BlockCtx, val renderCtx: RenderCtx, val lightingCtx: DefaultLightingCtx
|
val blockCtx: BlockCtx, val renderCtx: RenderCtx, val lightingCtx: DefaultLightingCtx
|
||||||
@@ -26,7 +30,7 @@ class CombinedContext(
|
|||||||
var hasRendered = false
|
var hasRendered = false
|
||||||
|
|
||||||
fun render(force: Boolean = false) = renderCtx.let {
|
fun render(force: Boolean = false) = renderCtx.let {
|
||||||
if (force || state.canRenderInLayer(it.layer) || (state.canRenderInCutout() && it.layer.isCutout)) {
|
if (force || RenderTypeLookup.canRenderInLayer(state, it.layer) || (state.canRenderInCutout() && it.layer.isCutout)) {
|
||||||
it.render(blockCtx)
|
it.render(blockCtx)
|
||||||
hasRendered = true
|
hasRendered = true
|
||||||
}
|
}
|
||||||
@@ -42,7 +46,7 @@ class CombinedContext(
|
|||||||
val isCutout = renderCtx.layer.isCutout
|
val isCutout = renderCtx.layer.isCutout
|
||||||
|
|
||||||
/** Get the centerpoint of the block being rendered. */
|
/** Get the centerpoint of the block being rendered. */
|
||||||
val blockCenter: Double3 get() = Double3(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5)
|
val blockCenter: Double3 get() = Double3((pos.x and 15) + 0.5, (pos.y and 15) + 0.5, (pos.z and 15) + 0.5)
|
||||||
|
|
||||||
/** Holds final vertex data before it goes to the [Tessellator]. */
|
/** Holds final vertex data before it goes to the [Tessellator]. */
|
||||||
val temp = RenderVertex()
|
val temp = RenderVertex()
|
||||||
@@ -56,9 +60,13 @@ class CombinedContext(
|
|||||||
icon: QuadIconResolver,
|
icon: QuadIconResolver,
|
||||||
postProcess: PostProcessLambda = noPost
|
postProcess: PostProcessLambda = noPost
|
||||||
) {
|
) {
|
||||||
|
val cameraTransform = renderCtx.matrixStack.last
|
||||||
lightingCtx.modelRotation = rotation
|
lightingCtx.modelRotation = rotation
|
||||||
model.quads.forEachIndexed { quadIdx, quad ->
|
model.quads.forEachIndexed { quadIdx, quad ->
|
||||||
if (quadFilter(quadIdx, quad)) {
|
if (quadFilter(quadIdx, quad)) {
|
||||||
|
val normal = quad.normal.let { Vector3f(it.x.toFloat(), it.y.toFloat(), it.z.toFloat()) }
|
||||||
|
normal.transform(cameraTransform.normal)
|
||||||
|
|
||||||
val drawIcon = icon(this, quadIdx, quad)
|
val drawIcon = icon(this, quadIdx, quad)
|
||||||
if (drawIcon != null) {
|
if (drawIcon != null) {
|
||||||
// let OptiFine know the texture we're using, so it can
|
// let OptiFine know the texture we're using, so it can
|
||||||
@@ -66,7 +74,10 @@ class CombinedContext(
|
|||||||
BufferBuilder_setSprite.invoke(renderCtx.renderBuffer, drawIcon)
|
BufferBuilder_setSprite.invoke(renderCtx.renderBuffer, drawIcon)
|
||||||
|
|
||||||
quad.verts.forEachIndexed { vertIdx, vert ->
|
quad.verts.forEachIndexed { vertIdx, vert ->
|
||||||
temp.init(vert).rotate(lightingCtx.modelRotation).translate(translation)
|
temp.init(vert).rotate(lightingCtx.modelRotation)
|
||||||
|
.translate(translation)
|
||||||
|
val vertex = temp.let { Vector4f(it.x.toFloat(), it.y.toFloat(), it.z.toFloat(), 0.0F) }
|
||||||
|
.apply { transform(cameraTransform.matrix) }
|
||||||
val shader = if (lightingCtx.aoEnabled && !forceFlat) vert.aoShader else vert.flatShader
|
val shader = if (lightingCtx.aoEnabled && !forceFlat) vert.aoShader else vert.flatShader
|
||||||
shader.shade(lightingCtx, temp)
|
shader.shade(lightingCtx, temp)
|
||||||
temp.postProcess(this, quadIdx, quad, vertIdx, vert)
|
temp.postProcess(this, quadIdx, quad, vertIdx, vert)
|
||||||
@@ -74,9 +85,12 @@ class CombinedContext(
|
|||||||
|
|
||||||
renderCtx.renderBuffer
|
renderCtx.renderBuffer
|
||||||
.pos(temp.x, temp.y, temp.z)
|
.pos(temp.x, temp.y, temp.z)
|
||||||
|
// .pos(vertex.x.toDouble(), vertex.y.toDouble(), vertex.z.toDouble())
|
||||||
.color(temp.red, temp.green, temp.blue, 1.0f)
|
.color(temp.red, temp.green, temp.blue, 1.0f)
|
||||||
.tex(temp.u, temp.v)
|
.tex(temp.u.toFloat(), temp.v.toFloat())
|
||||||
.lightmap(temp.brightness shr 16 and 65535, temp.brightness and 65535)
|
.lightmap(temp.brightness shr 16 and 65535, temp.brightness and 65535)
|
||||||
|
.normal(quad.normal.x.toFloat(), quad.normal.y.toFloat(), quad.normal.z.toFloat())
|
||||||
|
// .normal(normal.x, normal.y, normal.z)
|
||||||
.endVertex()
|
.endVertex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,10 +106,11 @@ val topOnly: (Direction) -> Boolean = { it == Direction.UP }
|
|||||||
/** Perform no post-processing */
|
/** Perform no post-processing */
|
||||||
val noPost: PostProcessLambda = { _, _, _, _, _ -> }
|
val noPost: PostProcessLambda = { _, _, _, _, _ -> }
|
||||||
|
|
||||||
object NonNullWorld : IEnviromentBlockReader {
|
object NonNullWorld : ILightReader {
|
||||||
override fun getBlockState(pos: BlockPos) = Blocks.AIR.defaultState
|
override fun getBlockState(pos: BlockPos) = Blocks.AIR.defaultState
|
||||||
override fun getLightFor(type: LightType, pos: BlockPos) = 0
|
override fun getLightFor(type: LightType, pos: BlockPos) = 0
|
||||||
override fun getFluidState(pos: BlockPos) = Fluids.EMPTY.defaultState
|
override fun getFluidState(pos: BlockPos) = Fluids.EMPTY.defaultState
|
||||||
override fun getTileEntity(pos: BlockPos) = null
|
override fun getTileEntity(pos: BlockPos) = null
|
||||||
override fun getBiome(pos: BlockPos) = Biomes.THE_VOID
|
override fun getLightManager() = null
|
||||||
|
override fun getBlockColor(p0: BlockPos, p1: ColorResolver) = 0
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,20 @@
|
|||||||
package mods.octarinecore.client.render
|
package mods.betterfoliage.render.old
|
||||||
|
|
||||||
import mods.octarinecore.client.render.lighting.*
|
import mods.betterfoliage.render.lighting.ModelLighter
|
||||||
import mods.octarinecore.common.*
|
import mods.betterfoliage.render.lighting.NoLighting
|
||||||
import mods.octarinecore.minmax
|
import mods.betterfoliage.render.lighting.ShaderFactory
|
||||||
import mods.octarinecore.replace
|
import mods.betterfoliage.render.lighting.cornerAo
|
||||||
|
import mods.betterfoliage.render.lighting.cornerFlat
|
||||||
|
import mods.betterfoliage.render.lighting.faceOrientedAuto
|
||||||
|
import mods.betterfoliage.util.Double3
|
||||||
|
import mods.betterfoliage.util.Rotation
|
||||||
|
import mods.betterfoliage.util.allDirections
|
||||||
|
import mods.betterfoliage.util.boxFaces
|
||||||
|
import mods.betterfoliage.util.get
|
||||||
|
import mods.betterfoliage.util.minmax
|
||||||
|
import mods.betterfoliage.util.replace
|
||||||
|
import mods.betterfoliage.util.times
|
||||||
|
import mods.betterfoliage.util.vec
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import java.lang.Math.max
|
import java.lang.Math.max
|
||||||
import java.lang.Math.min
|
import java.lang.Math.min
|
||||||
@@ -47,7 +58,8 @@ data class UV(val u: Double, val v: Double) {
|
|||||||
data class Vertex(val xyz: Double3 = Double3(0.0, 0.0, 0.0),
|
data class Vertex(val xyz: Double3 = Double3(0.0, 0.0, 0.0),
|
||||||
val uv: UV = UV(0.0, 0.0),
|
val uv: UV = UV(0.0, 0.0),
|
||||||
val aoShader: ModelLighter = NoLighting,
|
val aoShader: ModelLighter = NoLighting,
|
||||||
val flatShader: ModelLighter = NoLighting)
|
val flatShader: ModelLighter = NoLighting
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model quad
|
* Model quad
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
package mods.octarinecore.client.render
|
package mods.betterfoliage.render.old
|
||||||
|
|
||||||
import mods.octarinecore.common.Int3
|
|
||||||
import mods.octarinecore.common.plus
|
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
import net.minecraft.world.ILightReader
|
||||||
import net.minecraft.world.LightType
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegating [IBlockAccess] that fakes a _modified_ location to return values from a _target_ location.
|
* Delegating [IBlockAccess] that fakes a _modified_ location to return values from a _target_ location.
|
||||||
@@ -23,16 +20,12 @@ open class OffsetBlockReader(open val original: IBlockReader, val modded: BlockP
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS", "HasPlatformType")
|
@Suppress("NOTHING_TO_INLINE", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS", "HasPlatformType")
|
||||||
class OffsetEnvBlockReader(val original: IEnviromentBlockReader, val modded: BlockPos, val target: BlockPos) : IEnviromentBlockReader by original {
|
class OffsetEnvBlockReader(val original: ILightReader, val modded: BlockPos, val target: BlockPos) : ILightReader by original {
|
||||||
inline fun actualPos(pos: BlockPos) = if (pos != null && pos.x == modded.x && pos.y == modded.y && pos.z == modded.z) target else pos
|
inline fun actualPos(pos: BlockPos) = if (pos.x == modded.x && pos.y == modded.y && pos.z == modded.z) target else pos
|
||||||
|
|
||||||
override fun getBlockState(pos: BlockPos) = original.getBlockState(actualPos(pos))
|
override fun getBlockState(pos: BlockPos) = original.getBlockState(actualPos(pos))
|
||||||
override fun getTileEntity(pos: BlockPos) = original.getTileEntity(actualPos(pos))
|
override fun getTileEntity(pos: BlockPos) = original.getTileEntity(actualPos(pos))
|
||||||
override fun getFluidState(pos: BlockPos) = original.getFluidState(actualPos(pos))
|
override fun getFluidState(pos: BlockPos) = original.getFluidState(actualPos(pos))
|
||||||
|
|
||||||
override fun getLightFor(type: LightType, pos: BlockPos) = original.getLightFor(type, actualPos(pos))
|
|
||||||
override fun getCombinedLight(pos: BlockPos, light: Int) = original.getCombinedLight(actualPos(pos), light)
|
|
||||||
override fun getBiome(pos: BlockPos) = original.getBiome(actualPos(pos))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
@file:JvmName("RendererHolder")
|
||||||
|
package mods.betterfoliage.render.old
|
||||||
|
|
||||||
|
import mods.betterfoliage.resource.ResourceHandler
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus
|
||||||
|
|
||||||
|
abstract class RenderDecorator(modId: String, modBus: IEventBus) : ResourceHandler(modId, modBus) {
|
||||||
|
|
||||||
|
open val renderOnCutout: Boolean get() = true
|
||||||
|
open val onlyOnCutout: Boolean get() = false
|
||||||
|
|
||||||
|
// ============================
|
||||||
|
// Custom rendering
|
||||||
|
// ============================
|
||||||
|
abstract fun isEligible(ctx: CombinedContext): Boolean
|
||||||
|
abstract fun render(ctx: CombinedContext)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data class BlockData(val state: BlockState, val color: Int, val brightness: Int)
|
||||||
|
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package mods.betterfoliage.client.resource
|
package mods.betterfoliage.resource
|
||||||
|
|
||||||
import net.minecraft.client.renderer.model.ModelResourceLocation
|
import net.minecraft.client.renderer.model.ModelResourceLocation
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
@@ -1,21 +1,20 @@
|
|||||||
package mods.octarinecore.client.resource
|
package mods.betterfoliage.resource
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.render.old.Model
|
||||||
import mods.betterfoliage.client.resource.Sprite
|
import mods.betterfoliage.util.Atlas
|
||||||
import mods.octarinecore.client.render.Model
|
import mods.betterfoliage.util.Double3
|
||||||
import mods.octarinecore.common.Double3
|
import mods.betterfoliage.util.Int3
|
||||||
import mods.octarinecore.common.Int3
|
import mods.betterfoliage.util.completedVoid
|
||||||
import mods.octarinecore.common.completedVoid
|
import mods.betterfoliage.util.sink
|
||||||
import mods.octarinecore.common.sink
|
import mods.octarinecore.client.resource.AsyncSpriteProvider
|
||||||
import mods.octarinecore.stripEnd
|
import mods.octarinecore.client.resource.AtlasFuture
|
||||||
import mods.octarinecore.stripStart
|
import mods.octarinecore.client.resource.StitchPhases
|
||||||
import net.minecraft.resources.IResourceManager
|
import net.minecraft.resources.IResourceManager
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.MathHelper
|
import net.minecraft.util.math.MathHelper
|
||||||
import net.minecraft.world.IWorld
|
import net.minecraft.world.IWorld
|
||||||
import net.minecraft.world.gen.SimplexNoiseGenerator
|
import net.minecraft.world.gen.SimplexNoiseGenerator
|
||||||
import net.minecraftforge.client.event.TextureStitchEvent
|
|
||||||
import net.minecraftforge.event.world.WorldEvent
|
import net.minecraftforge.event.world.WorldEvent
|
||||||
import net.minecraftforge.eventbus.api.IEventBus
|
import net.minecraftforge.eventbus.api.IEventBus
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
@@ -25,15 +24,6 @@ import java.util.concurrent.CompletableFuture
|
|||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
enum class Atlas(val basePath: String) {
|
|
||||||
BLOCKS("textures"),
|
|
||||||
PARTICLES("textures/particle");
|
|
||||||
|
|
||||||
fun wrap(resource: Identifier) = Identifier(resource.namespace, "$basePath/${resource.path}.png")
|
|
||||||
fun unwrap(resource: Identifier) = resource.stripStart("$basePath/").stripEnd(".png")
|
|
||||||
fun matches(event: TextureStitchEvent) = event.map.basePath == basePath
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// Resource types
|
// Resource types
|
||||||
// ============================
|
// ============================
|
||||||
@@ -108,7 +98,8 @@ interface SpriteSet {
|
|||||||
operator fun get(idx: Int): Sprite
|
operator fun get(idx: Int): Sprite
|
||||||
}
|
}
|
||||||
|
|
||||||
class AsyncSpriteSet(val targetAtlas: Atlas = Atlas.BLOCKS, val idFunc: (Int)->Identifier, val transform: (Identifier)->Identifier = { it }) : AsyncSpriteProvider<Any> {
|
class AsyncSpriteSet(val targetAtlas: Atlas = Atlas.BLOCKS, val idFunc: (Int)->Identifier, val transform: (Identifier)->Identifier = { it }) :
|
||||||
|
AsyncSpriteProvider<Any> {
|
||||||
var num = 0
|
var num = 0
|
||||||
protected set
|
protected set
|
||||||
protected var sprites: List<Sprite> = emptyList()
|
protected var sprites: List<Sprite> = emptyList()
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package mods.octarinecore.client.resource
|
package mods.octarinecore.client.resource
|
||||||
|
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.betterfoliage.client.resource.Sprite
|
import mods.betterfoliage.resource.Sprite
|
||||||
import mods.octarinecore.common.map
|
import mods.betterfoliage.util.map
|
||||||
import net.minecraft.client.renderer.texture.AtlasTexture
|
import net.minecraft.client.renderer.texture.AtlasTexture
|
||||||
import net.minecraft.client.renderer.texture.MissingTextureSprite
|
import net.minecraft.client.renderer.texture.MissingTextureSprite
|
||||||
import net.minecraft.profiler.IProfiler
|
import net.minecraft.profiler.IProfiler
|
||||||
@@ -1,21 +1,26 @@
|
|||||||
package mods.octarinecore.client.resource
|
package mods.betterfoliage.resource.discovery
|
||||||
|
|
||||||
import com.google.common.base.Joiner
|
import com.google.common.base.Joiner
|
||||||
import mods.betterfoliage.client.resource.ModelIdentifier
|
import mods.betterfoliage.render.old.BlockCtx
|
||||||
import mods.octarinecore.HasLogger
|
import mods.octarinecore.client.resource.AsyncSpriteProvider
|
||||||
import mods.octarinecore.client.render.BlockCtx
|
import mods.octarinecore.client.resource.AtlasFuture
|
||||||
import mods.octarinecore.common.Int3
|
import mods.octarinecore.client.resource.StitchPhases
|
||||||
import mods.octarinecore.common.config.IBlockMatcher
|
import mods.betterfoliage.util.Int3
|
||||||
import mods.octarinecore.common.config.ModelTextureList
|
import mods.betterfoliage.config.IBlockMatcher
|
||||||
import mods.octarinecore.common.plus
|
import mods.betterfoliage.config.ModelTextureList
|
||||||
import mods.octarinecore.findFirst
|
import mods.betterfoliage.util.HasLogger
|
||||||
import mods.octarinecore.common.sinkAsync
|
import mods.betterfoliage.util.findFirst
|
||||||
|
import mods.betterfoliage.util.plus
|
||||||
|
import mods.betterfoliage.util.sinkAsync
|
||||||
|
import mods.betterfoliage.util.stripStart
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.renderer.BlockModelShapes
|
import net.minecraft.client.renderer.BlockModelShapes
|
||||||
import net.minecraft.client.renderer.model.BlockModel
|
import net.minecraft.client.renderer.model.BlockModel
|
||||||
import net.minecraft.client.renderer.model.IUnbakedModel
|
import net.minecraft.client.renderer.model.IUnbakedModel
|
||||||
import net.minecraft.client.renderer.model.ModelBakery
|
import net.minecraft.client.renderer.model.ModelBakery
|
||||||
|
import net.minecraft.client.renderer.model.ModelResourceLocation
|
||||||
import net.minecraft.client.renderer.model.VariantList
|
import net.minecraft.client.renderer.model.VariantList
|
||||||
|
import net.minecraft.client.renderer.texture.MissingTextureSprite
|
||||||
import net.minecraft.resources.IResourceManager
|
import net.minecraft.resources.IResourceManager
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
@@ -40,7 +45,7 @@ abstract class ModelRenderRegistryRoot<T> : ModelRenderRegistry<T> {
|
|||||||
class ModelDiscoveryContext(
|
class ModelDiscoveryContext(
|
||||||
bakery: ModelBakery,
|
bakery: ModelBakery,
|
||||||
val state: BlockState,
|
val state: BlockState,
|
||||||
val modelId: ModelIdentifier
|
val modelId: ModelResourceLocation
|
||||||
) {
|
) {
|
||||||
val models = bakery.unwrapVariants(bakery.getUnbakedModel(modelId) to modelId)
|
val models = bakery.unwrapVariants(bakery.getUnbakedModel(modelId) to modelId)
|
||||||
.filter { it.second != bakery.getUnbakedModel(ModelBakery.MODEL_MISSING) }
|
.filter { it.second != bakery.getUnbakedModel(ModelBakery.MODEL_MISSING) }
|
||||||
@@ -98,11 +103,11 @@ abstract class ConfigurableModelDiscovery<T> : ModelDiscovery<T>() {
|
|||||||
abstract val matchClasses: IBlockMatcher
|
abstract val matchClasses: IBlockMatcher
|
||||||
abstract val modelTextures: List<ModelTextureList>
|
abstract val modelTextures: List<ModelTextureList>
|
||||||
|
|
||||||
abstract fun processModel(state: BlockState, textures: List<String>, atlas: AtlasFuture): CompletableFuture<T>?
|
abstract fun processModel(state: BlockState, textures: List<ResourceLocation>, atlas: AtlasFuture): CompletableFuture<T>?
|
||||||
|
|
||||||
override fun processModel(ctx: ModelDiscoveryContext, atlas: AtlasFuture): CompletableFuture<T>? {
|
override fun processModel(ctx: ModelDiscoveryContext, atlas: AtlasFuture): CompletableFuture<T>? {
|
||||||
val matchClass = matchClasses.matchingClass(ctx.state.block) ?: return null
|
val matchClass = matchClasses.matchingClass(ctx.state.block) ?: return null
|
||||||
log("block state ${ctx.state.toString()}")
|
log("block state ${ctx.state}")
|
||||||
log(" class ${ctx.state.block.javaClass.name} matches ${matchClass.name}")
|
log(" class ${ctx.state.block.javaClass.name} matches ${matchClass.name}")
|
||||||
|
|
||||||
if (ctx.models.isEmpty()) {
|
if (ctx.models.isEmpty()) {
|
||||||
@@ -116,11 +121,11 @@ abstract class ConfigurableModelDiscovery<T> : ModelDiscovery<T>() {
|
|||||||
if (modelMatch != null) {
|
if (modelMatch != null) {
|
||||||
log(" model ${model} matches ${modelMatch.modelLocation}")
|
log(" model ${model} matches ${modelMatch.modelLocation}")
|
||||||
|
|
||||||
val textures = modelMatch.textureNames.map { it to model.resolveTextureName(it) }
|
val textures = modelMatch.textureNames.map { it to model.resolveTextureName(it).textureLocation }
|
||||||
val texMapString = Joiner.on(", ").join(textures.map { "${it.first}=${it.second}" })
|
val texMapString = Joiner.on(", ").join(textures.map { "${it.first}=${it.second}" })
|
||||||
log(" sprites [$texMapString]")
|
log(" sprites [$texMapString]")
|
||||||
|
|
||||||
if (textures.all { it.second != "missingno" }) {
|
if (textures.all { it.second != MissingTextureSprite.getLocation() }) {
|
||||||
// found a valid model (all required textures exist)
|
// found a valid model (all required textures exist)
|
||||||
return processModel(ctx.state, textures.map { it.second}, atlas)
|
return processModel(ctx.state, textures.map { it.second}, atlas)
|
||||||
}
|
}
|
||||||
@@ -128,5 +133,11 @@ abstract class ConfigurableModelDiscovery<T> : ModelDiscovery<T>() {
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Pair<BlockModel, ResourceLocation>.derivesFrom(targetLocation: ResourceLocation): Boolean {
|
||||||
|
if (second.stripStart("models/") == targetLocation) return true
|
||||||
|
if (first.parent != null && first.parentLocation != null)
|
||||||
|
return Pair(first.parent!!, first.parentLocation!!).derivesFrom(targetLocation)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package mods.octarinecore.client.resource
|
package mods.betterfoliage.resource.generated
|
||||||
|
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.betterfoliage.client.texture.loadSprite
|
import mods.betterfoliage.texture.loadSprite
|
||||||
|
import mods.betterfoliage.util.Atlas
|
||||||
|
import mods.betterfoliage.util.bytes
|
||||||
import net.minecraft.resources.IResourceManager
|
import net.minecraft.resources.IResourceManager
|
||||||
import java.awt.image.BufferedImage
|
import java.awt.image.BufferedImage
|
||||||
import java.lang.Math.max
|
import java.lang.Math.max
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
package mods.betterfoliage.client.texture
|
package mods.betterfoliage.resource.generated
|
||||||
|
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
|
import mods.betterfoliage.texture.blendRGB
|
||||||
|
import mods.betterfoliage.texture.loadSprite
|
||||||
|
import mods.betterfoliage.util.Atlas
|
||||||
|
import mods.betterfoliage.util.bytes
|
||||||
|
import mods.betterfoliage.util.get
|
||||||
|
import mods.betterfoliage.util.set
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.octarinecore.client.resource.*
|
||||||
import net.minecraft.resources.IResourceManager
|
import net.minecraft.resources.IResourceManager
|
||||||
import java.awt.image.BufferedImage
|
import java.awt.image.BufferedImage
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
package mods.betterfoliage.client.texture
|
package mods.betterfoliage.resource.generated
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
|
import mods.betterfoliage.texture.loadSprite
|
||||||
|
import mods.betterfoliage.util.Atlas
|
||||||
|
import mods.betterfoliage.util.bytes
|
||||||
|
import mods.betterfoliage.util.get
|
||||||
|
import mods.betterfoliage.util.loadImage
|
||||||
|
import mods.betterfoliage.util.resourceManager
|
||||||
|
import mods.betterfoliage.util.set
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.octarinecore.client.resource.*
|
||||||
import net.minecraft.resources.IResource
|
import net.minecraft.resources.IResource
|
||||||
import net.minecraft.resources.IResourceManager
|
import net.minecraft.resources.IResourceManager
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
package mods.octarinecore.client.resource
|
package mods.betterfoliage.resource.generated
|
||||||
|
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.octarinecore.HasLogger
|
import mods.betterfoliage.util.Atlas
|
||||||
import mods.octarinecore.common.completedVoid
|
import mods.betterfoliage.util.HasLogger
|
||||||
import mods.octarinecore.common.map
|
import mods.betterfoliage.util.completedVoid
|
||||||
|
import mods.betterfoliage.util.map
|
||||||
|
import mods.octarinecore.client.resource.AsyncSpriteProvider
|
||||||
|
import mods.octarinecore.client.resource.AtlasFuture
|
||||||
|
import mods.octarinecore.client.resource.StitchPhases
|
||||||
import net.minecraft.client.renderer.model.ModelBakery
|
import net.minecraft.client.renderer.model.ModelBakery
|
||||||
import net.minecraft.client.resources.ClientResourcePackInfo
|
import net.minecraft.client.resources.ClientResourcePackInfo
|
||||||
import net.minecraft.resources.*
|
import net.minecraft.resources.*
|
||||||
@@ -12,7 +16,6 @@ import net.minecraft.resources.data.IMetadataSectionSerializer
|
|||||||
import net.minecraft.util.text.StringTextComponent
|
import net.minecraft.util.text.StringTextComponent
|
||||||
import org.apache.logging.log4j.Logger
|
import org.apache.logging.log4j.Logger
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.lang.IllegalStateException
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.ExecutionException
|
import java.util.concurrent.ExecutionException
|
||||||
@@ -25,13 +28,15 @@ import java.util.function.Supplier
|
|||||||
* @param[name] Name of the resource pack
|
* @param[name] Name of the resource pack
|
||||||
* @param[generators] List of resource generators
|
* @param[generators] List of resource generators
|
||||||
*/
|
*/
|
||||||
class GeneratedBlockTexturePack(val nameSpace: String, val packName: String, override val logger: Logger) : HasLogger, IResourcePack, AsyncSpriteProvider<ModelBakery> {
|
class GeneratedBlockTexturePack(val nameSpace: String, val packName: String, override val logger: Logger) : HasLogger, IResourcePack,
|
||||||
|
AsyncSpriteProvider<ModelBakery> {
|
||||||
|
|
||||||
override fun getName() = packName
|
override fun getName() = packName
|
||||||
override fun getResourceNamespaces(type: ResourcePackType) = setOf(nameSpace)
|
override fun getResourceNamespaces(type: ResourcePackType) = setOf(nameSpace)
|
||||||
override fun <T : Any?> getMetadata(deserializer: IMetadataSectionSerializer<T>) = null
|
override fun <T : Any?> getMetadata(deserializer: IMetadataSectionSerializer<T>) = null
|
||||||
override fun getRootResourceStream(id: String) = null
|
override fun getRootResourceStream(id: String) = null
|
||||||
override fun getAllResourceLocations(type: ResourcePackType, path: String, maxDepth: Int, filter: Predicate<String>) = emptyList<Identifier>()
|
override fun getAllResourceLocations(type: ResourcePackType, namespace:String, path: String, maxDepth: Int, filter: Predicate<String>) = emptyList<Identifier>()
|
||||||
|
|
||||||
override fun close() {}
|
override fun close() {}
|
||||||
|
|
||||||
protected var manager: CompletableFuture<IResourceManager>? = null
|
protected var manager: CompletableFuture<IResourceManager>? = null
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
package mods.betterfoliage.client.texture
|
package mods.betterfoliage.texture
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.config.Config
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.octarinecore.client.render.lighting.HSB
|
import mods.betterfoliage.render.lighting.HSB
|
||||||
|
import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
|
||||||
|
import mods.betterfoliage.resource.discovery.ModelRenderRegistryRoot
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.octarinecore.client.resource.*
|
||||||
import mods.octarinecore.common.config.ConfigurableBlockMatcher
|
import mods.betterfoliage.config.ConfigurableBlockMatcher
|
||||||
import mods.octarinecore.common.config.ModelTextureList
|
import mods.betterfoliage.config.ModelTextureList
|
||||||
|
import mods.betterfoliage.util.averageColor
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
import org.apache.logging.log4j.Level
|
import org.apache.logging.log4j.Level
|
||||||
@@ -37,9 +40,9 @@ object AsyncGrassDiscovery : ConfigurableModelDiscovery<GrassInfo>() {
|
|||||||
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.grassBlocks
|
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.grassBlocks
|
||||||
override val modelTextures: List<ModelTextureList> get() = BlockConfig.grassModels.modelList
|
override val modelTextures: List<ModelTextureList> get() = BlockConfig.grassModels.modelList
|
||||||
|
|
||||||
override fun processModel(state: BlockState, textures: List<String>, atlas: AtlasFuture): CompletableFuture<GrassInfo> {
|
override fun processModel(state: BlockState, textures: List<Identifier>, atlas: AtlasFuture): CompletableFuture<GrassInfo> {
|
||||||
val textureName = textures[0]
|
val textureName = textures[0]
|
||||||
val spriteF = atlas.sprite(Identifier(textureName))
|
val spriteF = atlas.sprite(textureName)
|
||||||
logger.log(Level.DEBUG, "$logName: texture $textureName")
|
logger.log(Level.DEBUG, "$logName: texture $textureName")
|
||||||
return atlas.mapAfter {
|
return atlas.mapAfter {
|
||||||
val sprite = spriteF.get()
|
val sprite = spriteF.get()
|
||||||
@@ -1,13 +1,19 @@
|
|||||||
package mods.betterfoliage.client.texture
|
package mods.betterfoliage.texture
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.betterfoliage.client.resource.Sprite
|
import mods.betterfoliage.resource.Sprite
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.betterfoliage.resource.SpriteSet
|
||||||
import mods.octarinecore.stripStart
|
import mods.betterfoliage.util.Atlas
|
||||||
import mods.octarinecore.client.resource.Atlas
|
import mods.betterfoliage.util.get
|
||||||
import mods.octarinecore.common.sinkAsync
|
import mods.betterfoliage.util.getLines
|
||||||
|
import mods.betterfoliage.util.resourceManager
|
||||||
|
import mods.betterfoliage.util.sinkAsync
|
||||||
|
import mods.betterfoliage.util.stripStart
|
||||||
|
import mods.octarinecore.client.resource.AsyncSpriteProvider
|
||||||
|
import mods.octarinecore.client.resource.AtlasFuture
|
||||||
|
import mods.octarinecore.client.resource.StitchPhases
|
||||||
import net.minecraft.client.particle.ParticleManager
|
import net.minecraft.client.particle.ParticleManager
|
||||||
import net.minecraft.resources.IResourceManager
|
import net.minecraft.resources.IResourceManager
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
package mods.betterfoliage.client.texture
|
package mods.betterfoliage.texture
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliage
|
import mods.betterfoliage.BetterFoliage
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.config.BlockConfig
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.config.ConfigurableBlockMatcher
|
||||||
import mods.octarinecore.HasLogger
|
import mods.betterfoliage.config.ModelTextureList
|
||||||
|
import mods.betterfoliage.resource.Identifier
|
||||||
|
import mods.betterfoliage.resource.SpriteSet
|
||||||
|
import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
|
||||||
|
import mods.betterfoliage.resource.discovery.ModelRenderRegistryRoot
|
||||||
|
import mods.betterfoliage.resource.generated.GeneratedLeaf
|
||||||
|
import mods.betterfoliage.util.HasLogger
|
||||||
|
import mods.betterfoliage.util.averageColor
|
||||||
import mods.octarinecore.client.resource.*
|
import mods.octarinecore.client.resource.*
|
||||||
import mods.octarinecore.common.config.ConfigurableBlockMatcher
|
|
||||||
import mods.octarinecore.common.config.ModelTextureList
|
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
@@ -22,7 +27,7 @@ class LeafInfo(
|
|||||||
val leafType: String,
|
val leafType: String,
|
||||||
|
|
||||||
/** Average color of the round leaf texture. */
|
/** Average color of the round leaf texture. */
|
||||||
val averageColor: Int = roundLeafTexture.averageColor
|
val averageColor: Int
|
||||||
) {
|
) {
|
||||||
/** [IconSet] of the textures to use for leaf particles emitted from this block. */
|
/** [IconSet] of the textures to use for leaf particles emitted from this block. */
|
||||||
val particleTextures: SpriteSet get() = LeafParticleRegistry[leafType]
|
val particleTextures: SpriteSet get() = LeafParticleRegistry[leafType]
|
||||||
@@ -35,7 +40,7 @@ object AsyncLeafDiscovery : ConfigurableModelDiscovery<LeafInfo>() {
|
|||||||
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.leafBlocks
|
override val matchClasses: ConfigurableBlockMatcher get() = BlockConfig.leafBlocks
|
||||||
override val modelTextures: List<ModelTextureList> get() = BlockConfig.leafModels.modelList
|
override val modelTextures: List<ModelTextureList> get() = BlockConfig.leafModels.modelList
|
||||||
|
|
||||||
override fun processModel(state: BlockState, textures: List<String>, atlas: AtlasFuture) = defaultRegisterLeaf(Identifier(textures[0]), atlas)
|
override fun processModel(state: BlockState, textures: List<Identifier>, atlas: AtlasFuture) = defaultRegisterLeaf(textures[0], atlas)
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
LeafRegistry.registries.add(this)
|
LeafRegistry.registries.add(this)
|
||||||
@@ -47,10 +52,11 @@ fun HasLogger.defaultRegisterLeaf(sprite: Identifier, atlas: AtlasFuture): Compl
|
|||||||
val leafType = LeafParticleRegistry.typeMappings.getType(sprite) ?: "default"
|
val leafType = LeafParticleRegistry.typeMappings.getType(sprite) ?: "default"
|
||||||
val generated = GeneratedLeaf(sprite, leafType).register(BetterFoliage.asyncPack)
|
val generated = GeneratedLeaf(sprite, leafType).register(BetterFoliage.asyncPack)
|
||||||
val roundLeaf = atlas.sprite(generated)
|
val roundLeaf = atlas.sprite(generated)
|
||||||
|
val leafTex = atlas.sprite(sprite)
|
||||||
|
|
||||||
log(" leaf texture $sprite")
|
log(" leaf texture $sprite")
|
||||||
log(" particle $leafType")
|
log(" particle $leafType")
|
||||||
return atlas.mapAfter {
|
return atlas.mapAfter {
|
||||||
LeafInfo(roundLeaf.get(), leafType)
|
LeafInfo(roundLeaf.get(), leafType, leafTex.get().averageColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
@file:JvmName("Utils")
|
@file:JvmName("Utils")
|
||||||
package mods.betterfoliage.client.texture
|
package mods.betterfoliage.texture
|
||||||
|
|
||||||
import mods.betterfoliage.client.resource.Identifier
|
import mods.betterfoliage.resource.Identifier
|
||||||
import mods.octarinecore.client.resource.Atlas
|
import mods.betterfoliage.util.get
|
||||||
import mods.octarinecore.client.resource.get
|
import mods.betterfoliage.util.loadImage
|
||||||
import mods.octarinecore.client.resource.loadImage
|
|
||||||
import net.minecraft.resources.IResourceManager
|
import net.minecraft.resources.IResourceManager
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
60
src/main/kotlin/mods/betterfoliage/util/Caching.kt
Normal file
60
src/main/kotlin/mods/betterfoliage/util/Caching.kt
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
interface Invalidator {
|
||||||
|
fun invalidate() {
|
||||||
|
val iterator = callbacks.iterator()
|
||||||
|
while(iterator.hasNext()) iterator.next().let { callback ->
|
||||||
|
callback.get()?.invoke() ?: iterator.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val callbacks: MutableList<WeakReference<()->Unit>>
|
||||||
|
fun onInvalidate(callback: ()->Unit) {
|
||||||
|
callbacks.add(WeakReference(callback))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LazyInvalidatable<V>(invalidator: Invalidator, val valueFactory: ()->V): ReadOnlyProperty<Any, V> {
|
||||||
|
init { invalidator.onInvalidate { value = null } }
|
||||||
|
|
||||||
|
var value: V? = null
|
||||||
|
|
||||||
|
override fun getValue(thisRef: Any, property: KProperty<*>): V {
|
||||||
|
value?.let { return it }
|
||||||
|
return synchronized(this) {
|
||||||
|
value?.let { return it }
|
||||||
|
valueFactory().apply { value = this }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LazyMap<K, V>(val invalidator: Invalidator, val valueFactory: (K)->V) {
|
||||||
|
init { invalidator.onInvalidate { values.clear() } }
|
||||||
|
|
||||||
|
val values = mutableMapOf<K, V>()
|
||||||
|
|
||||||
|
operator fun get(key: K): V {
|
||||||
|
values[key]?.let { return it }
|
||||||
|
return synchronized(values) {
|
||||||
|
values[key]?.let { return it }
|
||||||
|
valueFactory(key).apply { values[key] = this }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
operator fun set(key: K, value: V) { values[key] = value }
|
||||||
|
|
||||||
|
fun delegate(key: K) = Delegate(key)
|
||||||
|
|
||||||
|
inner class Delegate(val key: K) : ReadOnlyProperty<Any, V> {
|
||||||
|
init { invalidator.onInvalidate { cached = null } }
|
||||||
|
|
||||||
|
private var cached: V? = null
|
||||||
|
|
||||||
|
override fun getValue(thisRef: Any, property: KProperty<*>): V {
|
||||||
|
cached?.let { return it }
|
||||||
|
get(key).let { cached = it; return it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/main/kotlin/mods/betterfoliage/util/Collections.kt
Normal file
63
src/main/kotlin/mods/betterfoliage/util/Collections.kt
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starting with the second element of this [Iterable] until the last, call the supplied lambda with
|
||||||
|
* the parameters (index, element, previous element).
|
||||||
|
*/
|
||||||
|
inline fun <reified T> Iterable<T>.forEachPairIndexed(func: (Int, T, T)->Unit) {
|
||||||
|
var previous: T? = null
|
||||||
|
forEachIndexed { idx, current ->
|
||||||
|
if (previous != null) func(idx, current, previous!!)
|
||||||
|
previous = current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T, C: Comparable<C>> Pair<T, T>.minBy(func: (T)->C) =
|
||||||
|
if (func(first) < func(second)) first else second
|
||||||
|
|
||||||
|
inline fun <T, C: Comparable<C>> Pair<T, T>.maxBy(func: (T)->C) =
|
||||||
|
if (func(first) > func(second)) first else second
|
||||||
|
|
||||||
|
inline fun <T, C: Comparable<C>> Triple<T, T, T>.maxValueBy(func: (T)->C): C {
|
||||||
|
var result = func(first)
|
||||||
|
func(second).let { if (it > result) result = it }
|
||||||
|
func(third).let { if (it > result) result = it }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <K, V> Map<K, V?>.filterValuesNotNull() = filterValues { it != null } as Map<K, V>
|
||||||
|
|
||||||
|
inline fun <reified T, R> Iterable<T>.findFirst(func: (T)->R?): R? {
|
||||||
|
forEach { func(it)?.let { return it } }
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <A1, reified A2, B> List<Pair<A1, B>>.filterIsInstanceFirst(cls: Class<A2>) = filter { it.first is A2 } as List<Pair<A2, B>>
|
||||||
|
|
||||||
|
/** Cross product of this [Iterable] with the parameter. */
|
||||||
|
fun <A, B> Iterable<A>.cross(other: Iterable<B>) = flatMap { a -> other.map { b -> a to b } }
|
||||||
|
|
||||||
|
inline fun <C, R, T> Iterable<T>.mapAs(transform: (C) -> R) = map { transform(it as C) }
|
||||||
|
|
||||||
|
inline fun <T1, T2> forEachNested(list1: Iterable<T1>, list2: Iterable<T2>, func: (T1, T2)-> Unit) =
|
||||||
|
list1.forEach { e1 ->
|
||||||
|
list2.forEach { e2 ->
|
||||||
|
func(e1, e2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mutating version of _map_. Replace each element of the list with the result of the given transformation. */
|
||||||
|
inline fun <reified T> MutableList<T>.replace(transform: (T) -> T) = forEachIndexed { idx, value -> this[idx] = transform(value) }
|
||||||
|
|
||||||
|
/** Exchange the two elements of the list with the given indices */
|
||||||
|
inline fun <T> MutableList<T>.exchange(idx1: Int, idx2: Int) {
|
||||||
|
val e = this[idx1]
|
||||||
|
this[idx1] = this[idx2]
|
||||||
|
this[idx2] = e
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return a random element from the array using the provided random generator */
|
||||||
|
inline operator fun <T> Array<T>.get(random: Random) = get(random.nextInt(Int.MAX_VALUE) % size)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package mods.octarinecore.common
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package mods.octarinecore.common
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
import mods.octarinecore.cross
|
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.*
|
import net.minecraft.util.Direction.*
|
||||||
import net.minecraft.util.Direction.Axis.*
|
import net.minecraft.util.Direction.Axis.*
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
@file:JvmName("Utils")
|
@file:JvmName("Utils")
|
||||||
package mods.octarinecore.client.gui
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
import net.minecraft.util.text.StringTextComponent
|
import net.minecraft.util.text.StringTextComponent
|
||||||
import net.minecraft.util.text.Style
|
import net.minecraft.util.text.Style
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
@file:JvmName("Utils")
|
|
||||||
@file:Suppress("NOTHING_TO_INLINE")
|
@file:Suppress("NOTHING_TO_INLINE")
|
||||||
package mods.octarinecore
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity
|
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.*
|
import net.minecraft.world.World
|
||||||
import org.apache.logging.log4j.Level
|
import org.apache.logging.log4j.Level
|
||||||
import org.apache.logging.log4j.Logger
|
import org.apache.logging.log4j.Logger
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
import java.lang.Math.*
|
import java.lang.Math.*
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
const val PI2 = 2.0 * PI
|
const val PI2 = 2.0 * PI
|
||||||
|
|
||||||
@@ -21,36 +19,6 @@ inline fun String.stripEnd(str: String, ignoreCase: Boolean = true) = if (endsWi
|
|||||||
inline fun ResourceLocation.stripStart(str: String) = ResourceLocation(namespace, path.stripStart(str))
|
inline fun ResourceLocation.stripStart(str: String) = ResourceLocation(namespace, path.stripStart(str))
|
||||||
inline fun ResourceLocation.stripEnd(str: String) = ResourceLocation(namespace, path.stripEnd(str))
|
inline fun ResourceLocation.stripEnd(str: String) = ResourceLocation(namespace, path.stripEnd(str))
|
||||||
|
|
||||||
/** Mutating version of _map_. Replace each element of the list with the result of the given transformation. */
|
|
||||||
inline fun <reified T> MutableList<T>.replace(transform: (T) -> T) = forEachIndexed { idx, value -> this[idx] = transform(value) }
|
|
||||||
|
|
||||||
/** Exchange the two elements of the list with the given indices */
|
|
||||||
inline fun <T> MutableList<T>.exchange(idx1: Int, idx2: Int) {
|
|
||||||
val e = this[idx1]
|
|
||||||
this[idx1] = this[idx2]
|
|
||||||
this[idx2] = e
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cross product of this [Iterable] with the parameter. */
|
|
||||||
fun <A, B> Iterable<A>.cross(other: Iterable<B>) = flatMap { a -> other.map { b -> a to b } }
|
|
||||||
|
|
||||||
inline fun <C, R, T> Iterable<T>.mapAs(transform: (C) -> R) = map { transform(it as C) }
|
|
||||||
|
|
||||||
inline fun <T1, T2> forEachNested(list1: Iterable<T1>, list2: Iterable<T2>, func: (T1, T2)-> Unit) =
|
|
||||||
list1.forEach { e1 ->
|
|
||||||
list2.forEach { e2 ->
|
|
||||||
func(e1, e2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
inline fun <K, V> Map<K, V?>.filterValuesNotNull() = filterValues { it != null } as Map<K, V>
|
|
||||||
|
|
||||||
inline fun <reified T, R> Iterable<T>.findFirst(func: (T)->R?): R? {
|
|
||||||
forEach { func(it)?.let { return it } }
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Property-level delegate backed by a [ThreadLocal].
|
* Property-level delegate backed by a [ThreadLocal].
|
||||||
*
|
*
|
||||||
@@ -62,29 +30,9 @@ class ThreadLocalDelegate<T>(init: () -> T) {
|
|||||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { tlVal.set(value) }
|
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { tlVal.set(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Starting with the second element of this [Iterable] until the last, call the supplied lambda with
|
|
||||||
* the parameters (index, element, previous element).
|
|
||||||
*/
|
|
||||||
inline fun <reified T> Iterable<T>.forEachPairIndexed(func: (Int, T, T)->Unit) {
|
|
||||||
var previous: T? = null
|
|
||||||
forEachIndexed { idx, current ->
|
|
||||||
if (previous != null) func(idx, current, previous!!)
|
|
||||||
previous = current
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Call the supplied lambda and return its result, or the given default value if an exception is thrown. */
|
/** Call the supplied lambda and return its result, or the given default value if an exception is thrown. */
|
||||||
fun <T> tryDefault(default: T, work: ()->T) = try { work() } catch (e: Throwable) { default }
|
fun <T> tryDefault(default: T, work: ()->T) = try { work() } catch (e: Throwable) { default }
|
||||||
|
|
||||||
/** Return a random [Double] value between the given two limits (inclusive min, exclusive max). */
|
|
||||||
fun random(min: Double, max: Double) = Math.random().let { min + (max - min) * it }
|
|
||||||
|
|
||||||
fun semiRandom(x: Int, y: Int, z: Int, seed: Int): Int {
|
|
||||||
var value = (x * x + y * y + z * z + x * y + y * z + z * x + (seed * seed)) and 63
|
|
||||||
value = (3 * x * value + 5 * y * value + 7 * z * value + (11 * seed)) and 63
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Return this [Double] value if it lies between the two limits. If outside, return the
|
* Return this [Double] value if it lies between the two limits. If outside, return the
|
||||||
* minimum/maximum value correspondingly.
|
* minimum/maximum value correspondingly.
|
||||||
@@ -112,18 +60,16 @@ fun nextPowerOf2(x: Int): Int {
|
|||||||
// else -> false
|
// else -> false
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the [TileEntity] at the given position, suppressing exceptions.
|
|
||||||
* Also returns null if the chunk is unloaded, which can happen because of multithreaded rendering.
|
|
||||||
*/
|
|
||||||
fun IWorldReader.getTileEntitySafe(pos: BlockPos): TileEntity? = tryDefault(null as TileEntity?) {
|
|
||||||
if (isBlockLoaded(pos)) getTileEntity(pos) else null
|
|
||||||
}
|
|
||||||
|
|
||||||
interface HasLogger {
|
interface HasLogger {
|
||||||
val logger: Logger
|
val logger: Logger
|
||||||
val logName: String get() = this::class.simpleName!!
|
val logName: String get() = this::class.simpleName!!
|
||||||
fun log(msg: String) = log(Level.DEBUG, msg)
|
fun log(msg: String) = log(Level.INFO, msg)
|
||||||
fun log(level: Level, msg: String) = logger.log(level, "[$logName] $msg")
|
fun log(level: Level, msg: String) = logger.log(level, "[$logName] $msg")
|
||||||
|
fun log(msg: String, e: Throwable) = log(Level.WARN, msg, e)
|
||||||
|
fun log(level: Level, msg: String, e: Throwable) = logger.log(level, "[$logName] $msg", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fun textComponent(msg: String, color: Formatting = Formatting.GRAY): LiteralText {
|
||||||
|
// val style = Style().apply { this.color = color }
|
||||||
|
// return LiteralText(msg).apply { this.style = style }
|
||||||
|
//}
|
||||||
18
src/main/kotlin/mods/betterfoliage/util/Random.kt
Normal file
18
src/main/kotlin/mods/betterfoliage/util/Random.kt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
val random = Random(System.nanoTime())
|
||||||
|
|
||||||
|
fun randomB() = random.nextBoolean()
|
||||||
|
fun randomI(min: Int = 0, max: Int = Int.MAX_VALUE) = min + random.nextInt(max - min)
|
||||||
|
fun randomD(min: Double = 0.0, max: Double = 1.0) = random.nextDouble() * (max - min) + min
|
||||||
|
|
||||||
|
fun semiRandom(x: Int, y: Int, z: Int, seed: Int): Int {
|
||||||
|
var value = (x * x + y * y + z * z + x * y + y * z + z * x + (seed * seed))
|
||||||
|
value = (3 * x * value + 5 * y * value + 7 * z * value + (11 * seed))
|
||||||
|
return value shr 4
|
||||||
|
}
|
||||||
|
|
||||||
|
fun BlockPos.semiRandom(seed: Int) = semiRandom(x, y, z, seed)
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
@file:JvmName("Reflection")
|
@file:JvmName("Reflection")
|
||||||
package mods.octarinecore.metaprog
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import mods.octarinecore.metaprog.Namespace.*
|
import mods.betterfoliage.util.Namespace.*
|
||||||
import mods.octarinecore.tryDefault
|
|
||||||
import kotlin.reflect.KCallable
|
|
||||||
import kotlin.reflect.KFunction
|
|
||||||
|
|
||||||
/** Get a Java class with the given name. */
|
/** Get a Java class with the given name. */
|
||||||
fun getJavaClass(name: String) = tryDefault(null) { Class.forName(name) }
|
fun getJavaClass(name: String) = tryDefault(null) { Class.forName(name) }
|
||||||
26
src/main/kotlin/mods/betterfoliage/util/Resources.kt
Normal file
26
src/main/kotlin/mods/betterfoliage/util/Resources.kt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
|
import net.minecraft.resources.IReloadableResourceManager
|
||||||
|
import net.minecraft.resources.IResource
|
||||||
|
import net.minecraft.resources.IResourceManager
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
|
||||||
|
/** Concise getter for the Minecraft resource manager. */
|
||||||
|
val resourceManager: IReloadableResourceManager
|
||||||
|
get() = Minecraft.getInstance().resourceManager as IReloadableResourceManager
|
||||||
|
|
||||||
|
/** Append a string to the [ResourceLocation]'s path. */
|
||||||
|
operator fun ResourceLocation.plus(str: String) = ResourceLocation(namespace, path + str)
|
||||||
|
|
||||||
|
/** Index operator to get a resource. */
|
||||||
|
operator fun IResourceManager.get(domain: String, path: String): IResource? = get(ResourceLocation(domain, path))
|
||||||
|
/** Index operator to get a resource. */
|
||||||
|
operator fun IResourceManager.get(location: ResourceLocation): IResource? = tryDefault(null) { getResource(location) }
|
||||||
|
|
||||||
|
/** Get the lines of a text resource. */
|
||||||
|
fun IResource.getLines(): List<String> {
|
||||||
|
val result = arrayListOf<String>()
|
||||||
|
inputStream.bufferedReader().useLines { it.forEach { result.add(it) } }
|
||||||
|
return result
|
||||||
|
}
|
||||||
86
src/main/kotlin/mods/betterfoliage/util/Sprites.kt
Normal file
86
src/main/kotlin/mods/betterfoliage/util/Sprites.kt
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package mods.betterfoliage.util
|
||||||
|
|
||||||
|
import mods.betterfoliage.render.lighting.HSB
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
|
import net.minecraft.client.renderer.texture.AtlasTexture
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||||
|
import net.minecraft.resources.IResource
|
||||||
|
import net.minecraft.resources.IResourceManager
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import javax.imageio.ImageIO
|
||||||
|
import kotlin.math.atan2
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
enum class Atlas(val basePath: String, val resourceId: ResourceLocation) {
|
||||||
|
BLOCKS("textures", AtlasTexture.LOCATION_BLOCKS_TEXTURE),
|
||||||
|
PARTICLES("textures", AtlasTexture.LOCATION_PARTICLES_TEXTURE);
|
||||||
|
|
||||||
|
/** Get the fully-qualified resource name for sprites belonging to this atlas*/
|
||||||
|
fun wrap(resource: ResourceLocation) = ResourceLocation(resource.namespace, "$basePath/${resource.path}.png")
|
||||||
|
|
||||||
|
/** Get the short resource name for sprites belonging to this atlas*/
|
||||||
|
fun unwrap(resource: ResourceLocation) = resource.stripStart("$basePath/").stripEnd(".png")
|
||||||
|
|
||||||
|
/** Reference to the atlas itself */
|
||||||
|
val atlas: AtlasTexture get() = Minecraft.getInstance().textureManager.getTexture(resourceId) as AtlasTexture
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator fun AtlasTexture.get(res: ResourceLocation): TextureAtlasSprite? = this.getSprite(res)
|
||||||
|
inline operator fun AtlasTexture.get(name: String): TextureAtlasSprite? = get(ResourceLocation(name))
|
||||||
|
|
||||||
|
fun IResourceManager.loadSprite(id: ResourceLocation) = this.get(id)?.loadImage() ?: throw IOException("Cannot load resource $id")
|
||||||
|
|
||||||
|
fun IResource.loadImage(): BufferedImage? = ImageIO.read(this.inputStream)
|
||||||
|
|
||||||
|
/** Index operator to get the RGB value of a pixel. */
|
||||||
|
operator fun BufferedImage.get(x: Int, y: Int) = this.getRGB(x, y)
|
||||||
|
/** Index operator to set the RGB value of a pixel. */
|
||||||
|
operator fun BufferedImage.set(x: Int, y: Int, value: Int) = this.setRGB(x, y, value)
|
||||||
|
|
||||||
|
val BufferedImage.bytes: ByteArray get() =
|
||||||
|
ByteArrayOutputStream().let { ImageIO.write(this, "PNG", it); it.toByteArray() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the average color of a texture.
|
||||||
|
*
|
||||||
|
* Only non-transparent pixels are considered. Averages are taken in the HSB color space (note: Hue is a circular average),
|
||||||
|
* and the result transformed back to the RGB color space.
|
||||||
|
*/
|
||||||
|
val TextureAtlasSprite.averageColor: Int get() {
|
||||||
|
var numOpaque = 0
|
||||||
|
var sumHueX = 0.0
|
||||||
|
var sumHueY = 0.0
|
||||||
|
var sumSaturation = 0.0f
|
||||||
|
var sumBrightness = 0.0f
|
||||||
|
for (x in 0 until width)
|
||||||
|
for (y in 0 until height) {
|
||||||
|
val pixel = getPixelRGBA(0, x, y)
|
||||||
|
val alpha = (pixel shr 24) and 255
|
||||||
|
val hsb = HSB.fromColor(pixel)
|
||||||
|
if (alpha == 255) {
|
||||||
|
numOpaque++
|
||||||
|
sumHueX += cos((hsb.hue.toDouble() - 0.5) * PI2)
|
||||||
|
sumHueY += sin((hsb.hue.toDouble() - 0.5) * PI2)
|
||||||
|
sumSaturation += hsb.saturation
|
||||||
|
sumBrightness += hsb.brightness
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// circular average - transform sum vector to polar angle
|
||||||
|
val avgHue = (atan2(sumHueY, sumHueX) / PI2 + 0.5).toFloat()
|
||||||
|
return HSB(avgHue, sumSaturation / numOpaque.toFloat(), sumBrightness / numOpaque.toFloat()).asColor
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Weighted blend of 2 packed RGB colors */
|
||||||
|
fun blendRGB(rgb1: Int, rgb2: Int, weight1: Int, weight2: Int): Int {
|
||||||
|
val r = (((rgb1 shr 16) and 255) * weight1 + ((rgb2 shr 16) and 255) * weight2) / (weight1 + weight2)
|
||||||
|
val g = (((rgb1 shr 8) and 255) * weight1 + ((rgb2 shr 8) and 255) * weight2) / (weight1 + weight2)
|
||||||
|
val b = ((rgb1 and 255) * weight1 + (rgb2 and 255) * weight2) / (weight1 + weight2)
|
||||||
|
val a = (rgb1 shr 24) and 255
|
||||||
|
val result = ((a shl 24) or (r shl 16) or (g shl 8) or b)
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package mods.octarinecore.client
|
|
||||||
|
|
||||||
import net.minecraft.client.settings.KeyBinding
|
|
||||||
import net.minecraftforge.client.event.InputEvent
|
|
||||||
import net.minecraftforge.common.MinecraftForge
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
|
||||||
import net.minecraftforge.fml.client.registry.ClientRegistry
|
|
||||||
|
|
||||||
class KeyHandler(val modId: String, val defaultKey: Int, val lang: String, val action: (InputEvent.KeyInputEvent)->Unit) {
|
|
||||||
|
|
||||||
val keyBinding = KeyBinding(lang, defaultKey, modId)
|
|
||||||
|
|
||||||
init {
|
|
||||||
ClientRegistry.registerKeyBinding(keyBinding)
|
|
||||||
MinecraftForge.EVENT_BUS.register(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
fun handleKeyPress(event: InputEvent.KeyInputEvent) {
|
|
||||||
if (keyBinding.isPressed) action(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
package mods.octarinecore.client.render
|
|
||||||
|
|
||||||
import mods.octarinecore.PI2
|
|
||||||
import mods.octarinecore.common.Double3
|
|
||||||
import net.minecraft.client.Minecraft
|
|
||||||
import net.minecraft.client.particle.IParticleRenderType
|
|
||||||
import net.minecraft.client.particle.Particle
|
|
||||||
import net.minecraft.client.particle.SpriteTexturedParticle
|
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder
|
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
|
||||||
import net.minecraft.entity.Entity
|
|
||||||
import net.minecraft.world.World
|
|
||||||
|
|
||||||
abstract class AbstractEntityFX(world: World, x: Double, y: Double, z: Double) : SpriteTexturedParticle(world, x, y, z) {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmStatic val sin = Array(64) { idx -> Math.sin(PI2 / 64.0 * idx) }
|
|
||||||
@JvmStatic val cos = Array(64) { idx -> Math.cos(PI2 / 64.0 * idx) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val billboardRot = Pair(Double3.zero, Double3.zero)
|
|
||||||
val currentPos = Double3.zero
|
|
||||||
val prevPos = Double3.zero
|
|
||||||
val velocity = Double3.zero
|
|
||||||
|
|
||||||
override fun tick() {
|
|
||||||
super.tick()
|
|
||||||
currentPos.setTo(posX, posY, posZ)
|
|
||||||
prevPos.setTo(prevPosX, prevPosY, prevPosZ)
|
|
||||||
velocity.setTo(motionX, motionY, motionZ)
|
|
||||||
update()
|
|
||||||
posX = currentPos.x; posY = currentPos.y; posZ = currentPos.z;
|
|
||||||
motionX = velocity.x; motionY = velocity.y; motionZ = velocity.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Render the particle. */
|
|
||||||
abstract fun render(worldRenderer: BufferBuilder, partialTickTime: Float)
|
|
||||||
|
|
||||||
/** Update particle on world tick. */
|
|
||||||
abstract fun update()
|
|
||||||
|
|
||||||
/** True if the particle is renderable. */
|
|
||||||
abstract val isValid: Boolean
|
|
||||||
|
|
||||||
/** Add the particle to the effect renderer if it is valid. */
|
|
||||||
fun addIfValid() { if (isValid) Minecraft.getInstance().particles.addEffect(this) }
|
|
||||||
|
|
||||||
override fun renderParticle(buffer: BufferBuilder, entity: ActiveRenderInfo, partialTicks: Float, rotX: Float, rotZ: Float, rotYZ: Float, rotXY: Float, rotXZ: Float) {
|
|
||||||
billboardRot.first.setTo(rotX + rotXY, rotZ, rotYZ + rotXZ)
|
|
||||||
billboardRot.second.setTo(rotX - rotXY, -rotZ, rotYZ - rotXZ)
|
|
||||||
render(buffer, partialTicks)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Render a particle quad.
|
|
||||||
*
|
|
||||||
* @param[tessellator] the [Tessellator] instance to use
|
|
||||||
* @param[partialTickTime] partial tick time
|
|
||||||
* @param[currentPos] render position
|
|
||||||
* @param[prevPos] previous tick position for interpolation
|
|
||||||
* @param[size] particle size
|
|
||||||
* @param[rotation] viewpoint-dependent particle rotation (64 steps)
|
|
||||||
* @param[icon] particle texture
|
|
||||||
* @param[isMirrored] mirror particle texture along V-axis
|
|
||||||
* @param[alpha] aplha blending
|
|
||||||
*/
|
|
||||||
fun renderParticleQuad(worldRenderer: BufferBuilder,
|
|
||||||
partialTickTime: Float,
|
|
||||||
currentPos: Double3 = this.currentPos,
|
|
||||||
prevPos: Double3 = this.prevPos,
|
|
||||||
size: Double = particleScale.toDouble(),
|
|
||||||
rotation: Int = 0,
|
|
||||||
icon: TextureAtlasSprite = sprite,
|
|
||||||
isMirrored: Boolean = false,
|
|
||||||
alpha: Float = this.particleAlpha) {
|
|
||||||
|
|
||||||
val minU = (if (isMirrored) icon.minU else icon.maxU).toDouble()
|
|
||||||
val maxU = (if (isMirrored) icon.maxU else icon.minU).toDouble()
|
|
||||||
val minV = icon.minV.toDouble()
|
|
||||||
val maxV = icon.maxV.toDouble()
|
|
||||||
|
|
||||||
val center = currentPos.copy().sub(prevPos).mul(partialTickTime.toDouble()).add(prevPos).sub(interpPosX, interpPosY, interpPosZ)
|
|
||||||
val v1 = if (rotation == 0) billboardRot.first * size else
|
|
||||||
Double3.weight(billboardRot.first, cos[rotation and 63] * size, billboardRot.second, sin[rotation and 63] * size)
|
|
||||||
val v2 = if (rotation == 0) billboardRot.second * size else
|
|
||||||
Double3.weight(billboardRot.first, -sin[rotation and 63] * size, billboardRot.second, cos[rotation and 63] * size)
|
|
||||||
|
|
||||||
val renderBrightness = this.getBrightnessForRender(partialTickTime)
|
|
||||||
val brLow = renderBrightness shr 16 and 65535
|
|
||||||
val brHigh = renderBrightness and 65535
|
|
||||||
|
|
||||||
worldRenderer
|
|
||||||
.pos(center.x - v1.x, center.y - v1.y, center.z - v1.z)
|
|
||||||
.tex(maxU, maxV)
|
|
||||||
.color(particleRed, particleGreen, particleBlue, alpha)
|
|
||||||
.lightmap(brLow, brHigh)
|
|
||||||
.endVertex()
|
|
||||||
|
|
||||||
worldRenderer
|
|
||||||
.pos(center.x - v2.x, center.y - v2.y, center.z - v2.z)
|
|
||||||
.tex(maxU, minV)
|
|
||||||
.color(particleRed, particleGreen, particleBlue, alpha)
|
|
||||||
.lightmap(brLow, brHigh)
|
|
||||||
.endVertex()
|
|
||||||
|
|
||||||
worldRenderer
|
|
||||||
.pos(center.x + v1.x, center.y + v1.y, center.z + v1.z)
|
|
||||||
.tex(minU, minV)
|
|
||||||
.color(particleRed, particleGreen, particleBlue, alpha)
|
|
||||||
.lightmap(brLow, brHigh)
|
|
||||||
.endVertex()
|
|
||||||
|
|
||||||
worldRenderer
|
|
||||||
.pos(center.x + v2.x, center.y + v2.y, center.z + v2.z)
|
|
||||||
.tex(minU, maxV)
|
|
||||||
.color(particleRed, particleGreen, particleBlue, alpha)
|
|
||||||
.lightmap(brLow, brHigh)
|
|
||||||
.endVertex()
|
|
||||||
}
|
|
||||||
|
|
||||||
// override fun getFXLayer() = 1
|
|
||||||
override fun getRenderType(): IParticleRenderType = IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT
|
|
||||||
|
|
||||||
fun setColor(color: Int) {
|
|
||||||
particleBlue = (color and 255) / 256.0f
|
|
||||||
particleGreen = ((color shr 8) and 255) / 256.0f
|
|
||||||
particleRed = ((color shr 16) and 255) / 256.0f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
@file:JvmName("RendererHolder")
|
|
||||||
package mods.octarinecore.client.render
|
|
||||||
|
|
||||||
import mods.betterfoliage.client.render.canRenderInCutout
|
|
||||||
import mods.betterfoliage.client.render.isCutout
|
|
||||||
import mods.octarinecore.ThreadLocalDelegate
|
|
||||||
import mods.octarinecore.client.resource.ResourceHandler
|
|
||||||
import mods.octarinecore.common.Double3
|
|
||||||
import mods.octarinecore.common.Int3
|
|
||||||
import mods.octarinecore.common.allDirOffsets
|
|
||||||
import mods.octarinecore.common.plus
|
|
||||||
import mods.octarinecore.semiRandom
|
|
||||||
import net.minecraft.block.Block
|
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.client.Minecraft
|
|
||||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder
|
|
||||||
import net.minecraft.client.renderer.color.BlockColors
|
|
||||||
import net.minecraft.util.BlockRenderLayer
|
|
||||||
import net.minecraft.util.Direction
|
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.util.math.MathHelper
|
|
||||||
import net.minecraft.world.IEnviromentBlockReader
|
|
||||||
import net.minecraft.world.biome.Biome
|
|
||||||
import net.minecraftforge.client.model.data.IModelData
|
|
||||||
import net.minecraftforge.eventbus.api.IEventBus
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.math.abs
|
|
||||||
|
|
||||||
abstract class RenderDecorator(modId: String, modBus: IEventBus) : ResourceHandler(modId, modBus) {
|
|
||||||
|
|
||||||
open val renderOnCutout: Boolean get() = true
|
|
||||||
open val onlyOnCutout: Boolean get() = false
|
|
||||||
|
|
||||||
// ============================
|
|
||||||
// Custom rendering
|
|
||||||
// ============================
|
|
||||||
abstract fun isEligible(ctx: CombinedContext): Boolean
|
|
||||||
abstract fun render(ctx: CombinedContext)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
data class BlockData(val state: BlockState, val color: Int, val brightness: Int)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
@file:JvmName("PixelFormat")
|
|
||||||
package mods.octarinecore.client.render.lighting
|
|
||||||
|
|
||||||
import java.awt.Color
|
|
||||||
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
@file:JvmName("Utils")
|
|
||||||
package mods.octarinecore.client.resource
|
|
||||||
|
|
||||||
import mods.octarinecore.PI2
|
|
||||||
import mods.octarinecore.client.render.lighting.HSB
|
|
||||||
import mods.octarinecore.stripStart
|
|
||||||
import mods.octarinecore.tryDefault
|
|
||||||
import net.minecraft.client.Minecraft
|
|
||||||
import net.minecraft.client.renderer.model.BlockModel
|
|
||||||
import net.minecraft.client.renderer.texture.AtlasTexture
|
|
||||||
import net.minecraft.client.renderer.texture.MissingTextureSprite
|
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
|
||||||
import net.minecraft.resources.IResource
|
|
||||||
import net.minecraft.resources.IResourceManager
|
|
||||||
import net.minecraft.resources.SimpleReloadableResourceManager
|
|
||||||
import net.minecraft.util.ResourceLocation
|
|
||||||
import java.awt.image.BufferedImage
|
|
||||||
import java.io.ByteArrayInputStream
|
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.lang.Math.*
|
|
||||||
import javax.imageio.ImageIO
|
|
||||||
import kotlin.math.atan2
|
|
||||||
|
|
||||||
/** Concise getter for the Minecraft resource manager. */
|
|
||||||
val resourceManager: SimpleReloadableResourceManager
|
|
||||||
get() =
|
|
||||||
Minecraft.getInstance().resourceManager as SimpleReloadableResourceManager
|
|
||||||
|
|
||||||
/** Append a string to the [ResourceLocation]'s path. */
|
|
||||||
operator fun ResourceLocation.plus(str: String) = ResourceLocation(namespace, path + str)
|
|
||||||
|
|
||||||
/** Index operator to get a resource. */
|
|
||||||
operator fun IResourceManager.get(domain: String, path: String): IResource? = get(ResourceLocation(domain, path))
|
|
||||||
/** Index operator to get a resource. */
|
|
||||||
operator fun IResourceManager.get(location: ResourceLocation): IResource? = tryDefault(null) { getResource(location) }
|
|
||||||
|
|
||||||
/** Index operator to get a texture sprite. */
|
|
||||||
operator fun AtlasTexture.get(res: ResourceLocation): TextureAtlasSprite? = getSprite(res)
|
|
||||||
operator fun AtlasTexture.get(name: String): TextureAtlasSprite? = getSprite(ResourceLocation(name))
|
|
||||||
|
|
||||||
val missingSprite: TextureAtlasSprite get() = MissingTextureSprite.func_217790_a()
|
|
||||||
|
|
||||||
/** Load an image resource. */
|
|
||||||
fun IResource.loadImage(): BufferedImage? = ImageIO.read(this.inputStream)
|
|
||||||
|
|
||||||
/** Get the lines of a text resource. */
|
|
||||||
fun IResource.getLines(): List<String> {
|
|
||||||
val result = arrayListOf<String>()
|
|
||||||
inputStream.bufferedReader().useLines { it.forEach { result.add(it) } }
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Index operator to get the RGB value of a pixel. */
|
|
||||||
operator fun BufferedImage.get(x: Int, y: Int) = this.getRGB(x, y)
|
|
||||||
/** Index operator to set the RGB value of a pixel. */
|
|
||||||
operator fun BufferedImage.set(x: Int, y: Int, value: Int) = this.setRGB(x, y, value)
|
|
||||||
|
|
||||||
/** Get an [InputStream] to an image object in PNG format. */
|
|
||||||
val BufferedImage.asStream: InputStream get() =
|
|
||||||
ByteArrayInputStream(ByteArrayOutputStream().let { ImageIO.write(this, "PNG", it); it.toByteArray() })
|
|
||||||
val BufferedImage.bytes: ByteArray get() =
|
|
||||||
ByteArrayOutputStream().let { ImageIO.write(this, "PNG", it); it.toByteArray() }
|
|
||||||
/**
|
|
||||||
* Calculate the average color of a texture.
|
|
||||||
*
|
|
||||||
* Only non-transparent pixels are considered. Averages are taken in the HSB color space (note: Hue is a circular average),
|
|
||||||
* and the result transformed back to the RGB color space.
|
|
||||||
*/
|
|
||||||
val TextureAtlasSprite.averageColor: Int get() {
|
|
||||||
var numOpaque = 0
|
|
||||||
var sumHueX = 0.0
|
|
||||||
var sumHueY = 0.0
|
|
||||||
var sumSaturation = 0.0f
|
|
||||||
var sumBrightness = 0.0f
|
|
||||||
for (x in 0 until width)
|
|
||||||
for (y in 0 until height) {
|
|
||||||
val pixel = getPixelRGBA(0, x, y)
|
|
||||||
val alpha = (pixel shr 24) and 255
|
|
||||||
val hsb = HSB.fromColor(pixel)
|
|
||||||
if (alpha == 255) {
|
|
||||||
numOpaque++
|
|
||||||
sumHueX += cos((hsb.hue.toDouble() - 0.5) * PI2)
|
|
||||||
sumHueY += sin((hsb.hue.toDouble() - 0.5) * PI2)
|
|
||||||
sumSaturation += hsb.saturation
|
|
||||||
sumBrightness += hsb.brightness
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// circular average - transform sum vector to polar angle
|
|
||||||
val avgHue = (atan2(sumHueY, sumHueX) / PI2 + 0.5).toFloat()
|
|
||||||
return HSB(avgHue, sumSaturation / numOpaque.toFloat(), sumBrightness / numOpaque.toFloat()).asColor
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the actual location of a texture from the name of its [TextureAtlasSprite].
|
|
||||||
*/
|
|
||||||
fun textureLocation(iconName: String) = ResourceLocation(iconName).let {
|
|
||||||
if (it.path.startsWith("mcpatcher")) it
|
|
||||||
else ResourceLocation(it.namespace, "textures/${it.path}")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Pair<BlockModel, ResourceLocation>.derivesFrom(targetLocation: ResourceLocation): Boolean {
|
|
||||||
if (second.stripStart("models/") == targetLocation) return true
|
|
||||||
if (first.parent != null && first.parentLocation != null)
|
|
||||||
return Pair(first.parent!!, first.parentLocation!!).derivesFrom(targetLocation)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user