mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 16:06:28 +01:00
Merge branch 'dev' into shader-pipeline
# Conflicts: # src/main/java/com/jozufozu/flywheel/core/WorldContext.java
This commit is contained in:
commit
a2b740f0d8
47 changed files with 1565 additions and 174 deletions
|
@ -99,6 +99,8 @@ repositories {
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||||
|
|
||||||
|
//implementation "org.joml:joml:1.10.1"
|
||||||
|
|
||||||
annotationProcessor 'org.spongepowered:mixin:0.8.2:processor'
|
annotationProcessor 'org.spongepowered:mixin:0.8.2:processor'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
0.1.0:
|
||||||
|
Fixes
|
||||||
|
- Render layer events are always dispatched, even when the backend is disabled
|
||||||
|
- Fix a crash when light updates occur close to the world height
|
||||||
|
- Fix issue with optifine shaders
|
||||||
|
- Fix PartialModels not being initialized
|
||||||
|
|
||||||
0.0.3:
|
0.0.3:
|
||||||
New
|
New
|
||||||
- Include the logo in the mod
|
- Include the logo in the mod
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
org.gradle.jvmargs=-Xmx3G
|
org.gradle.jvmargs=-Xmx3G
|
||||||
org.gradle.daemon=false
|
org.gradle.daemon=false
|
||||||
# mod version info
|
# mod version info
|
||||||
mod_version=0.0.3
|
mod_version=0.1.0
|
||||||
mc_update_version=1.16
|
mc_update_version=1.16
|
||||||
minecraft_version=1.16.5
|
minecraft_version=1.16.5
|
||||||
forge_version=36.0.42
|
forge_version=36.0.42
|
||||||
|
|
|
@ -4,6 +4,8 @@ import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.core.AtlasStitcher;
|
import com.jozufozu.flywheel.core.AtlasStitcher;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
|
import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
||||||
|
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
@ -20,5 +22,9 @@ public class FlywheelClient {
|
||||||
|
|
||||||
modEventBus.addListener(Contexts::flwInit);
|
modEventBus.addListener(Contexts::flwInit);
|
||||||
modEventBus.addListener(Materials::flwInit);
|
modEventBus.addListener(Materials::flwInit);
|
||||||
|
modEventBus.addListener(PartialModel::onModelRegistry);
|
||||||
|
modEventBus.addListener(PartialModel::onModelBake);
|
||||||
|
|
||||||
|
VanillaInstances.init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
|
@ -18,7 +19,6 @@ import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
@ -52,7 +52,6 @@ import net.minecraftforge.resource.IResourceType;
|
||||||
import net.minecraftforge.resource.ISelectiveResourceReloadListener;
|
import net.minecraftforge.resource.ISelectiveResourceReloadListener;
|
||||||
import net.minecraftforge.resource.VanillaResourceType;
|
import net.minecraftforge.resource.VanillaResourceType;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public class ShaderSources implements ISelectiveResourceReloadListener {
|
public class ShaderSources implements ISelectiveResourceReloadListener {
|
||||||
public static final String SHADER_DIR = "flywheel/shaders/";
|
public static final String SHADER_DIR = "flywheel/shaders/";
|
||||||
public static final String PROGRAM_DIR = "flywheel/programs/";
|
public static final String PROGRAM_DIR = "flywheel/programs/";
|
||||||
|
@ -205,7 +204,7 @@ public class ShaderSources implements ISelectiveResourceReloadListener {
|
||||||
try {
|
try {
|
||||||
bytebuffer = readToBuffer(is);
|
bytebuffer = readToBuffer(is);
|
||||||
int i = bytebuffer.position();
|
int i = bytebuffer.position();
|
||||||
bytebuffer.rewind();
|
((Buffer) bytebuffer).rewind();
|
||||||
return MemoryUtil.memASCII(bytebuffer, i);
|
return MemoryUtil.memASCII(bytebuffer, i);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.gl.buffer;
|
package com.jozufozu.flywheel.backend.gl.buffer;
|
||||||
|
|
||||||
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ public class VecBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public VecBuffer rewind() {
|
public VecBuffer rewind() {
|
||||||
internal.rewind();
|
((Buffer) internal).rewind();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||||
|
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||||
|
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||||
|
import static org.lwjgl.opengl.GL13.GL_TEXTURE4;
|
||||||
|
import static org.lwjgl.opengl.GL13.glActiveTexture;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
|
import com.jozufozu.flywheel.core.crumbling.CrumblingInstanceManager;
|
||||||
|
import com.jozufozu.flywheel.core.crumbling.CrumblingMaterialManager;
|
||||||
|
import com.jozufozu.flywheel.core.crumbling.CrumblingProgram;
|
||||||
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
|
import net.minecraft.client.renderer.DestroyBlockProgress;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.model.ModelBakery;
|
||||||
|
import net.minecraft.client.renderer.texture.Texture;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureManager;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.LazyValue;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responsible for rendering the block breaking overlay for instanced tiles.
|
||||||
|
*/
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@Mod.EventBusSubscriber(Dist.CLIENT)
|
||||||
|
public class CrumblingRenderer {
|
||||||
|
|
||||||
|
private static final LazyValue<MaterialManager<CrumblingProgram>> materialManager = new LazyValue<>(() -> new CrumblingMaterialManager(Contexts.CRUMBLING));
|
||||||
|
private static final LazyValue<InstanceManager<TileEntity>> manager = new LazyValue<>(() -> new CrumblingInstanceManager(materialManager.getValue()));
|
||||||
|
|
||||||
|
private static final RenderType crumblingLayer = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
|
||||||
|
|
||||||
|
public static void renderBreaking(ClientWorld world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||||
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing(world)) return;
|
||||||
|
|
||||||
|
Int2ObjectMap<List<TileEntity>> activeStages = getActiveStageTiles(world);
|
||||||
|
|
||||||
|
if (activeStages.isEmpty()) return;
|
||||||
|
|
||||||
|
InstanceManager<TileEntity> renderer = manager.getValue();
|
||||||
|
|
||||||
|
TextureManager textureManager = Minecraft.getInstance().textureManager;
|
||||||
|
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
||||||
|
|
||||||
|
MaterialManager<CrumblingProgram> materials = materialManager.getValue();
|
||||||
|
crumblingLayer.startDrawing();
|
||||||
|
|
||||||
|
for (Int2ObjectMap.Entry<List<TileEntity>> stage : activeStages.int2ObjectEntrySet()) {
|
||||||
|
int i = stage.getIntKey();
|
||||||
|
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
|
||||||
|
|
||||||
|
// something about when we call this means that the textures are not ready for use on the first frame they should appear
|
||||||
|
if (breaking != null) {
|
||||||
|
stage.getValue().forEach(renderer::add);
|
||||||
|
|
||||||
|
renderer.beginFrame(info);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE4);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||||
|
materials.render(RenderType.getCutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
||||||
|
|
||||||
|
renderer.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
crumblingLayer.endDrawing();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));
|
||||||
|
if (breaking != null) glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associate each breaking stage with a list of all tile entities at that stage.
|
||||||
|
*/
|
||||||
|
private static Int2ObjectMap<List<TileEntity>> getActiveStageTiles(ClientWorld world) {
|
||||||
|
Long2ObjectMap<SortedSet<DestroyBlockProgress>> breakingProgressions = Minecraft.getInstance().worldRenderer.blockBreakingProgressions;
|
||||||
|
|
||||||
|
Int2ObjectMap<List<TileEntity>> breakingEntities = new Int2ObjectArrayMap<>();
|
||||||
|
|
||||||
|
for (Long2ObjectMap.Entry<SortedSet<DestroyBlockProgress>> entry : breakingProgressions.long2ObjectEntrySet()) {
|
||||||
|
BlockPos breakingPos = BlockPos.fromLong(entry.getLongKey());
|
||||||
|
|
||||||
|
SortedSet<DestroyBlockProgress> progresses = entry.getValue();
|
||||||
|
if (progresses != null && !progresses.isEmpty()) {
|
||||||
|
int blockDamage = progresses.last()
|
||||||
|
.getPartialBlockDamage();
|
||||||
|
|
||||||
|
TileEntity tileEntity = world.getTileEntity(breakingPos);
|
||||||
|
|
||||||
|
if (tileEntity != null) {
|
||||||
|
List<TileEntity> tileEntities = breakingEntities.computeIfAbsent(blockDamage, $ -> new ArrayList<>());
|
||||||
|
tileEntities.add(tileEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return breakingEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||||
|
ClientWorld world = event.getWorld();
|
||||||
|
if (Backend.getInstance()
|
||||||
|
.canUseInstancing() && world != null) {
|
||||||
|
materialManager.getValue().delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,12 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
materialManager.addListener(this);
|
materialManager.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract boolean canInstance(T obj);
|
||||||
|
|
||||||
|
protected abstract IInstance createRaw(T obj);
|
||||||
|
|
||||||
|
protected abstract boolean canCreateInstance(T entity);
|
||||||
|
|
||||||
public void tick(double cameraX, double cameraY, double cameraZ) {
|
public void tick(double cameraX, double cameraY, double cameraZ) {
|
||||||
tick++;
|
tick++;
|
||||||
|
|
||||||
|
@ -100,7 +106,7 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
if (!Backend.getInstance()
|
if (!Backend.getInstance()
|
||||||
.canUseInstancing()) return;
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
if (obj instanceof IInstanceRendered) {
|
if (canInstance(obj)) {
|
||||||
addInternal(obj);
|
addInternal(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +122,7 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
if (!Backend.getInstance()
|
if (!Backend.getInstance()
|
||||||
.canUseInstancing()) return;
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
if (obj instanceof IInstanceRendered) {
|
if (canInstance(obj)) {
|
||||||
IInstance instance = getInstance(obj, false);
|
IInstance instance = getInstance(obj, false);
|
||||||
|
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
|
@ -143,7 +149,7 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
if (!Backend.getInstance()
|
if (!Backend.getInstance()
|
||||||
.canUseInstancing()) return;
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
if (obj instanceof IInstanceRendered) {
|
if (canInstance(obj)) {
|
||||||
IInstance instance = getInstance(obj, false);
|
IInstance instance = getInstance(obj, false);
|
||||||
|
|
||||||
if (instance != null) instance.updateLight();
|
if (instance != null) instance.updateLight();
|
||||||
|
@ -154,13 +160,14 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
if (!Backend.getInstance()
|
if (!Backend.getInstance()
|
||||||
.canUseInstancing()) return;
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
if (obj instanceof IInstanceRendered) {
|
if (canInstance(obj)) {
|
||||||
IInstance instance = getInstance(obj, false);
|
IInstance instance = getInstance(obj, false);
|
||||||
if (instance != null) removeInternal(obj, instance);
|
if (instance != null) removeInternal(obj, instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
|
instances.values().forEach(IInstance::remove);
|
||||||
instances.clear();
|
instances.clear();
|
||||||
dynamicInstances.clear();
|
dynamicInstances.clear();
|
||||||
tickableInstances.clear();
|
tickableInstances.clear();
|
||||||
|
@ -241,8 +248,4 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
invalidate();
|
invalidate();
|
||||||
instancedTiles.forEach(this::add);
|
instancedTiles.forEach(this::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IInstance createRaw(T obj);
|
|
||||||
|
|
||||||
protected abstract boolean canCreateInstance(T entity);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -137,7 +138,7 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
vertices.putFloat(reader.getV(i));
|
vertices.putFloat(reader.getV(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
vertices.rewind();
|
((Buffer) vertices).rewind();
|
||||||
|
|
||||||
// return new BufferedModel(GlPrimitive.QUADS, format, vertices, vertexCount);
|
// return new BufferedModel(GlPrimitive.QUADS, format, vertices, vertexCount);
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,22 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
|
||||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
|
||||||
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
|
||||||
import static org.lwjgl.opengl.GL13.GL_TEXTURE4;
|
|
||||||
import static org.lwjgl.opengl.GL13.glActiveTexture;
|
|
||||||
|
|
||||||
import java.util.BitSet;
|
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.core.CrumblingInstanceManager;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.jozufozu.flywheel.util.WorldAttached;
|
import com.jozufozu.flywheel.util.WorldAttached;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
|
||||||
import net.minecraft.client.renderer.DestroyBlockProgress;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
|
||||||
import net.minecraft.client.renderer.model.ModelBakery;
|
|
||||||
import net.minecraft.client.renderer.texture.Texture;
|
|
||||||
import net.minecraft.client.renderer.texture.TextureManager;
|
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.inventory.container.PlayerContainer;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.LazyValue;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
@ -50,16 +28,10 @@ import net.minecraftforge.fml.common.Mod;
|
||||||
@Mod.EventBusSubscriber(Dist.CLIENT)
|
@Mod.EventBusSubscriber(Dist.CLIENT)
|
||||||
public class InstancedRenderDispatcher {
|
public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
private static final WorldAttached<InstanceManager<Entity>> entityInstanceManager = new WorldAttached<>(world -> new EntityInstanceManager(Contexts.WORLD.getMaterialManager(world)));
|
private static final WorldAttached<MaterialManager<WorldProgram>> materialManagers = new WorldAttached<>($ -> new MaterialManager<>(Contexts.WORLD));
|
||||||
private static final WorldAttached<InstanceManager<TileEntity>> tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(Contexts.WORLD.getMaterialManager(world)));
|
|
||||||
|
|
||||||
private static final LazyValue<Vector<CrumblingInstanceManager>> blockBreaking = new LazyValue<>(() -> {
|
private static final WorldAttached<InstanceManager<Entity>> entityInstanceManager = new WorldAttached<>(world -> new EntityInstanceManager(materialManagers.get(world)));
|
||||||
Vector<CrumblingInstanceManager> renderers = new Vector<>(10);
|
private static final WorldAttached<InstanceManager<TileEntity>> tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(materialManagers.get(world)));
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
renderers.add(new CrumblingInstanceManager());
|
|
||||||
}
|
|
||||||
return renderers;
|
|
||||||
});
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static InstanceManager<TileEntity> getTiles(IWorld world) {
|
public static InstanceManager<TileEntity> getTiles(IWorld world) {
|
||||||
|
@ -99,7 +71,7 @@ public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onBeginFrame(BeginFrameEvent event) {
|
public static void onBeginFrame(BeginFrameEvent event) {
|
||||||
Contexts.WORLD.getMaterialManager(event.getWorld())
|
materialManagers.get(event.getWorld())
|
||||||
.checkAndShiftOrigin(event.getInfo());
|
.checkAndShiftOrigin(event.getInfo());
|
||||||
|
|
||||||
getTiles(event.getWorld()).beginFrame(event.getInfo());
|
getTiles(event.getWorld()).beginFrame(event.getInfo());
|
||||||
|
@ -114,7 +86,7 @@ public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
event.type.startDrawing();
|
event.type.startDrawing();
|
||||||
|
|
||||||
Contexts.WORLD.getMaterialManager(world)
|
materialManagers.get(world)
|
||||||
.render(event.type, event.viewProjection, event.camX, event.camY, event.camZ);
|
.render(event.type, event.viewProjection, event.camX, event.camY, event.camZ);
|
||||||
|
|
||||||
event.type.endDrawing();
|
event.type.endDrawing();
|
||||||
|
@ -129,65 +101,8 @@ public class InstancedRenderDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final RenderType crumblingLayer = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
|
|
||||||
|
|
||||||
public static void renderBreaking(ClientWorld world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
|
||||||
if (!Backend.getInstance()
|
|
||||||
.canUseInstancing(world)) return;
|
|
||||||
|
|
||||||
WorldRenderer worldRenderer = Minecraft.getInstance().worldRenderer;
|
|
||||||
Long2ObjectMap<SortedSet<DestroyBlockProgress>> breakingProgressions = worldRenderer.blockBreakingProgressions;
|
|
||||||
|
|
||||||
if (breakingProgressions.isEmpty()) return;
|
|
||||||
Vector<CrumblingInstanceManager> renderers = blockBreaking.getValue();
|
|
||||||
|
|
||||||
BitSet bitSet = new BitSet(10);
|
|
||||||
|
|
||||||
for (Long2ObjectMap.Entry<SortedSet<DestroyBlockProgress>> entry : breakingProgressions.long2ObjectEntrySet()) {
|
|
||||||
BlockPos breakingPos = BlockPos.fromLong(entry.getLongKey());
|
|
||||||
|
|
||||||
SortedSet<DestroyBlockProgress> progresses = entry.getValue();
|
|
||||||
if (progresses != null && !progresses.isEmpty()) {
|
|
||||||
int blockDamage = progresses.last()
|
|
||||||
.getPartialBlockDamage();
|
|
||||||
bitSet.set(blockDamage);
|
|
||||||
renderers.get(blockDamage)
|
|
||||||
.add(world.getTileEntity(breakingPos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureManager textureManager = Minecraft.getInstance().textureManager;
|
|
||||||
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE)
|
|
||||||
.getGlTextureId());
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE4);
|
|
||||||
|
|
||||||
crumblingLayer.startDrawing();
|
|
||||||
bitSet.stream()
|
|
||||||
.forEach(i -> {
|
|
||||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
|
|
||||||
CrumblingInstanceManager renderer = renderers.get(i);
|
|
||||||
renderer.beginFrame(info);
|
|
||||||
|
|
||||||
if (breaking != null) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
|
||||||
renderer.materialManager.render(RenderType.getCutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.invalidate();
|
|
||||||
});
|
|
||||||
crumblingLayer.endDrawing();
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));
|
|
||||||
if (breaking != null) glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void loadAllInWorld(ClientWorld world) {
|
public static void loadAllInWorld(ClientWorld world) {
|
||||||
Contexts.WORLD.getMaterialManager(world)
|
materialManagers.get(world)
|
||||||
.delete();
|
.delete();
|
||||||
|
|
||||||
InstanceManager<TileEntity> tiles = tileInstanceManager.replace(world);
|
InstanceManager<TileEntity> tiles = tileInstanceManager.replace(world);
|
||||||
|
|
|
@ -10,6 +10,8 @@ import com.jozufozu.flywheel.backend.instancing.entity.IEntityInstanceFactory;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.ITileInstanceFactory;
|
import com.jozufozu.flywheel.backend.instancing.tile.ITileInstanceFactory;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
@ -22,15 +24,54 @@ public class InstancedRenderRegistry {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Object2BooleanMap<Object> skipRender = new Object2BooleanLinkedOpenHashMap<>();
|
||||||
private final Map<TileEntityType<?>, ITileInstanceFactory<?>> tiles = Maps.newHashMap();
|
private final Map<TileEntityType<?>, ITileInstanceFactory<?>> tiles = Maps.newHashMap();
|
||||||
private final Map<EntityType<?>, IEntityInstanceFactory<?>> entities = Maps.newHashMap();
|
private final Map<EntityType<?>, IEntityInstanceFactory<?>> entities = Maps.newHashMap();
|
||||||
|
|
||||||
public <T extends TileEntity> void register(TileEntityType<? extends T> type, ITileInstanceFactory<? super T> rendererFactory) {
|
protected InstancedRenderRegistry() {
|
||||||
this.tiles.put(type, rendererFactory);
|
skipRender.defaultReturnValue(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T extends TileEntity> boolean shouldSkipRender(T type) {
|
||||||
|
return _skipRender(type.getType()) || ((type instanceof IInstanceRendered) && !((IInstanceRendered) type).shouldRenderNormally());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Entity> boolean shouldSkipRender(T type) {
|
||||||
|
return _skipRender(type.getType()) || ((type instanceof IInstanceRendered) && !((IInstanceRendered) type).shouldRenderNormally());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends TileEntity> boolean canInstance(TileEntityType<? extends T> type) {
|
||||||
|
return tiles.containsKey(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Entity> boolean canInstance(EntityType<? extends T> type) {
|
||||||
|
return entities.containsKey(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends TileEntity> TileConfig<? extends T> tile(TileEntityType<? extends T> type) {
|
||||||
|
return new TileConfig<>(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Entity> EntityConfig<? extends T> entity(EntityType<? extends T> type) {
|
||||||
|
return new EntityConfig<>(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated will be removed in 0.3.0, use {@link #tile}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public <T extends TileEntity> void register(TileEntityType<? extends T> type, ITileInstanceFactory<? super T> rendererFactory) {
|
||||||
|
this.tile(type)
|
||||||
|
.factory(rendererFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated will be removed in 0.3.0, use {@link #entity}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public <T extends Entity> void register(EntityType<? extends T> type, IEntityInstanceFactory<? super T> rendererFactory) {
|
public <T extends Entity> void register(EntityType<? extends T> type, IEntityInstanceFactory<? super T> rendererFactory) {
|
||||||
this.entities.put(type, rendererFactory);
|
this.entity(type)
|
||||||
|
.factory(rendererFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -54,4 +95,47 @@ public class InstancedRenderRegistry {
|
||||||
else return factory.create(manager, tile);
|
else return factory.create(manager, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean _skipRender(Object o) {
|
||||||
|
return skipRender.getBoolean(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TileConfig<T extends TileEntity> {
|
||||||
|
|
||||||
|
private final TileEntityType<T> type;
|
||||||
|
|
||||||
|
public TileConfig(TileEntityType<T> type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TileConfig<T> factory(ITileInstanceFactory<? super T> rendererFactory) {
|
||||||
|
tiles.put(type, rendererFactory);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TileConfig<T> setSkipRender(boolean skipRender) {
|
||||||
|
InstancedRenderRegistry.this.skipRender.put(type, skipRender);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EntityConfig<T extends Entity> {
|
||||||
|
|
||||||
|
private final EntityType<T> type;
|
||||||
|
|
||||||
|
public EntityConfig(EntityType<T> type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityConfig<T> factory(IEntityInstanceFactory<? super T> rendererFactory) {
|
||||||
|
entities.put(type, rendererFactory);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityConfig<T> setSkipRender(boolean skipRender) {
|
||||||
|
InstancedRenderRegistry.this.skipRender.put(type, skipRender);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
protected final Map<ResourceLocation, ArrayList<MaterialRenderer<P>>> renderers;
|
protected final Map<ResourceLocation, ArrayList<MaterialRenderer<P>>> renderers;
|
||||||
protected final Map<ResourceLocation, Map<MaterialSpec<?>, InstanceMaterial<?>>> materials;
|
protected final Map<ResourceLocation, Map<MaterialSpec<?>, InstanceMaterial<?>>> materials;
|
||||||
|
|
||||||
private BlockPos originCoordinate = BlockPos.ZERO;
|
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||||
|
|
||||||
private final WeakHashSet<OriginShiftListener> listeners;
|
private final WeakHashSet<OriginShiftListener> listeners;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,11 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||||
super(materialManager);
|
super(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canInstance(Entity obj) {
|
||||||
|
return obj != null && InstancedRenderRegistry.getInstance().canInstance(obj.getType());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IInstance createRaw(Entity obj) {
|
protected IInstance createRaw(Entity obj) {
|
||||||
return InstancedRenderRegistry.getInstance()
|
return InstancedRenderRegistry.getInstance()
|
||||||
|
|
|
@ -17,6 +17,11 @@ public class TileInstanceManager extends InstanceManager<TileEntity> {
|
||||||
super(materialManager);
|
super(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canInstance(TileEntity obj) {
|
||||||
|
return obj != null && InstancedRenderRegistry.getInstance().canInstance(obj.getType());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IInstance createRaw(TileEntity obj) {
|
protected IInstance createRaw(TileEntity obj) {
|
||||||
return InstancedRenderRegistry.getInstance()
|
return InstancedRenderRegistry.getInstance()
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.SpecMetaRegistry;
|
import com.jozufozu.flywheel.backend.SpecMetaRegistry;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
|
import com.jozufozu.flywheel.core.crumbling.CrumblingProgram;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldFog;
|
import com.jozufozu.flywheel.core.shader.WorldFog;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.core.shader.gamestate.FogStateProvider;
|
import com.jozufozu.flywheel.core.shader.gamestate.FogStateProvider;
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core;
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL20.glUniform2f;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.loading.Program;
|
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
|
||||||
import com.jozufozu.flywheel.core.shader.extension.IProgramExtension;
|
|
||||||
|
|
||||||
public class CrumblingProgram extends WorldProgram {
|
|
||||||
protected final int uTextureScale;
|
|
||||||
protected int uCrumbling;
|
|
||||||
|
|
||||||
public CrumblingProgram(Program program, List<IProgramExtension> extensions) {
|
|
||||||
super(program, extensions);
|
|
||||||
|
|
||||||
uTextureScale = getUniformLocation("uTextureScale");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void registerSamplers() {
|
|
||||||
super.registerSamplers();
|
|
||||||
uCrumbling = setSamplerBinding("uCrumbling", 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTextureScale(float x, float y) {
|
|
||||||
glUniform2f(uTextureScale, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -12,12 +12,13 @@ import net.minecraftforge.client.model.ModelLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper class for loading and accessing json models.
|
* A helper class for loading and accessing json models.
|
||||||
* <p>
|
* <br>
|
||||||
* Creating a PartialModel will make the associated modelLocation automatically load.
|
* Creating a PartialModel will make the associated modelLocation automatically load.
|
||||||
* As such, PartialModels must be initialized at or before {@link ModelRegistryEvent}.
|
* PartialModels must be initialized during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent FMLClientSetupEvent}.
|
||||||
|
* <br>
|
||||||
* Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations)
|
* Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations)
|
||||||
* will have their bakedModel fields populated.
|
* will have their bakedModel fields populated.
|
||||||
* <p>
|
* <br>
|
||||||
* Attempting to create a PartialModel after ModelRegistryEvent will cause an error.
|
* Attempting to create a PartialModel after ModelRegistryEvent will cause an error.
|
||||||
*/
|
*/
|
||||||
public class PartialModel {
|
public class PartialModel {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.jozufozu.flywheel.core;
|
package com.jozufozu.flywheel.core;
|
||||||
|
|
||||||
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
@ -136,7 +137,7 @@ public class QuadConverter {
|
||||||
type.castAndBuffer(indices, i + 2);
|
type.castAndBuffer(indices, i + 2);
|
||||||
type.castAndBuffer(indices, i + 3);
|
type.castAndBuffer(indices, i + 3);
|
||||||
}
|
}
|
||||||
indices.flip();
|
((Buffer) indices).flip();
|
||||||
}
|
}
|
||||||
|
|
||||||
private GlBuffer getBuffer(GlNumericType type) {
|
private GlBuffer getBuffer(GlNumericType type) {
|
||||||
|
|
|
@ -14,7 +14,6 @@ import com.jozufozu.flywheel.backend.ResourceUtil;
|
||||||
import com.jozufozu.flywheel.backend.ShaderContext;
|
import com.jozufozu.flywheel.backend.ShaderContext;
|
||||||
import com.jozufozu.flywheel.backend.ShaderSources;
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
||||||
import com.jozufozu.flywheel.backend.loading.InstancedArraysTemplate;
|
import com.jozufozu.flywheel.backend.loading.InstancedArraysTemplate;
|
||||||
import com.jozufozu.flywheel.backend.loading.Program;
|
import com.jozufozu.flywheel.backend.loading.Program;
|
||||||
|
@ -30,7 +29,6 @@ import com.jozufozu.flywheel.core.shader.spec.ProgramState;
|
||||||
import com.jozufozu.flywheel.util.WorldAttached;
|
import com.jozufozu.flywheel.util.WorldAttached;
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.IWorld;
|
|
||||||
|
|
||||||
public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
|
|
||||||
|
@ -41,8 +39,6 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
protected Supplier<Stream<ResourceLocation>> specStream;
|
protected Supplier<Stream<ResourceLocation>> specStream;
|
||||||
protected TemplateFactory templateFactory;
|
protected TemplateFactory templateFactory;
|
||||||
|
|
||||||
private final WorldAttached<MaterialManager<P>> worldAttachedMMs = new WorldAttached<>($ -> new MaterialManager<>(this));
|
|
||||||
|
|
||||||
private final Map<ShaderType, ResourceLocation> builtins = new EnumMap<>(ShaderType.class);
|
private final Map<ShaderType, ResourceLocation> builtins = new EnumMap<>(ShaderType.class);
|
||||||
private final Map<ShaderType, String> builtinSources = new EnumMap<>(ShaderType.class);
|
private final Map<ShaderType, String> builtinSources = new EnumMap<>(ShaderType.class);
|
||||||
|
|
||||||
|
@ -73,10 +69,6 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialManager<P> getMaterialManager(IWorld world) {
|
|
||||||
return worldAttachedMMs.get(world);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorldContext<P> withSpecStream(Supplier<Stream<ResourceLocation>> specStream) {
|
public WorldContext<P> withSpecStream(Supplier<Stream<ResourceLocation>> specStream) {
|
||||||
this.specStream = specStream;
|
this.specStream = specStream;
|
||||||
return this;
|
return this;
|
||||||
|
@ -116,13 +108,6 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
.forEach(this::loadSpec);
|
.forEach(this::loadSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete() {
|
|
||||||
super.delete();
|
|
||||||
|
|
||||||
worldAttachedMMs.empty(MaterialManager::delete);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Shader getSource(ShaderType type, ResourceLocation name) {
|
protected Shader getSource(ShaderType type, ResourceLocation name) {
|
||||||
Shader source = super.getSource(type, name);
|
Shader source = super.getSource(type, name);
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.jozufozu.flywheel.core.atlas;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.mixin.atlas.SheetDataAccessor;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
|
import net.minecraft.client.renderer.texture.Texture;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
public class AtlasInfo {
|
||||||
|
|
||||||
|
private static final Map<ResourceLocation, SheetData> sheetData = new HashMap<>();
|
||||||
|
|
||||||
|
public static AtlasTexture getAtlas(ResourceLocation name) {
|
||||||
|
Texture texture = Minecraft.getInstance().textureManager.getTexture(name);
|
||||||
|
|
||||||
|
if (texture instanceof AtlasTexture)
|
||||||
|
return (AtlasTexture) texture;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SheetData getAtlasData(TextureAtlasSprite texture) {
|
||||||
|
return getAtlasData(texture.getAtlas());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SheetData getAtlasData(AtlasTexture atlas) {
|
||||||
|
return getAtlasData(atlas.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SheetData getAtlasData(ResourceLocation loc) {
|
||||||
|
return sheetData.get(loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAtlasData(ResourceLocation atlas, SheetDataAccessor accessor) {
|
||||||
|
sheetData.put(atlas, new SheetData(accessor.getWidth(), accessor.getHeight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.jozufozu.flywheel.core.atlas;
|
||||||
|
|
||||||
|
public class SheetData {
|
||||||
|
public final int width;
|
||||||
|
public final int height;
|
||||||
|
|
||||||
|
public SheetData(int width, int height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.core;
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||||
|
@ -6,8 +6,9 @@ import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class CrumblingInstanceManager extends TileInstanceManager {
|
public class CrumblingInstanceManager extends TileInstanceManager {
|
||||||
public CrumblingInstanceManager() {
|
|
||||||
super(new MaterialManager<>(Contexts.CRUMBLING));
|
public CrumblingInstanceManager(MaterialManager<?> materialManager) {
|
||||||
|
super(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||||
|
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||||
|
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||||
|
import static org.lwjgl.opengl.GL13.glActiveTexture;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.MaterialRenderer;
|
||||||
|
import com.jozufozu.flywheel.core.WorldContext;
|
||||||
|
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
||||||
|
import com.jozufozu.flywheel.core.atlas.SheetData;
|
||||||
|
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureManager;
|
||||||
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
|
||||||
|
public class CrumblingMaterialManager extends MaterialManager<CrumblingProgram> {
|
||||||
|
|
||||||
|
public CrumblingMaterialManager(WorldContext<CrumblingProgram> context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render every model for every material.
|
||||||
|
*
|
||||||
|
* @param layer Which vanilla {@link RenderType} is being drawn?
|
||||||
|
* @param viewProjection How do we get from camera space to clip space?
|
||||||
|
* @param callback Provide additional uniforms or state here.
|
||||||
|
*/
|
||||||
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<CrumblingProgram> callback) {
|
||||||
|
camX -= originCoordinate.getX();
|
||||||
|
camY -= originCoordinate.getY();
|
||||||
|
camZ -= originCoordinate.getZ();
|
||||||
|
|
||||||
|
Matrix4f translate = Matrix4f.translate((float) -camX, (float) -camY, (float) -camZ);
|
||||||
|
|
||||||
|
translate.multiplyBackward(viewProjection);
|
||||||
|
|
||||||
|
TextureManager textureManager = Minecraft.getInstance().textureManager;
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE)
|
||||||
|
.getGlTextureId());
|
||||||
|
|
||||||
|
for (MaterialRenderer<CrumblingProgram> material : atlasRenderers) {
|
||||||
|
material.render(layer, translate, camX, camY, camZ, CrumblingProgram::setDefaultAtlasSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<ResourceLocation, ArrayList<MaterialRenderer<CrumblingProgram>>> entry : renderers.entrySet()) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(entry.getKey())
|
||||||
|
.getGlTextureId());
|
||||||
|
SheetData atlasData = AtlasInfo.getAtlasData(entry.getKey());
|
||||||
|
for (MaterialRenderer<CrumblingProgram> materialRenderer : entry.getValue()) {
|
||||||
|
materialRenderer.render(layer, translate, camX, camY, camZ, p -> p.setAtlasSize(atlasData.width, atlasData.height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL20.glUniform2f;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.loading.Program;
|
||||||
|
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
||||||
|
import com.jozufozu.flywheel.core.atlas.SheetData;
|
||||||
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
|
import com.jozufozu.flywheel.core.shader.extension.IProgramExtension;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.model.ModelBakery;
|
||||||
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
|
|
||||||
|
public class CrumblingProgram extends WorldProgram {
|
||||||
|
protected final int uTextureScale;
|
||||||
|
protected int uCrumbling;
|
||||||
|
|
||||||
|
public CrumblingProgram(Program program, List<IProgramExtension> extensions) {
|
||||||
|
super(program, extensions);
|
||||||
|
|
||||||
|
uTextureScale = getUniformLocation("uTextureScale");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind() {
|
||||||
|
super.bind();
|
||||||
|
setDefaultAtlasSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerSamplers() {
|
||||||
|
super.registerSamplers();
|
||||||
|
uCrumbling = setSamplerBinding("uCrumbling", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextureScale(float x, float y) {
|
||||||
|
glUniform2f(uTextureScale, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultAtlasSize() {
|
||||||
|
SheetData atlasData = AtlasInfo.getAtlasData(PlayerContainer.BLOCK_ATLAS_TEXTURE);
|
||||||
|
if (atlasData == null) return;
|
||||||
|
|
||||||
|
int width = atlasData.width;
|
||||||
|
int height = atlasData.height;
|
||||||
|
|
||||||
|
setAtlasSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAtlasSize(int width, int height) {
|
||||||
|
AtlasTexture blockAtlas = AtlasInfo.getAtlas(PlayerContainer.BLOCK_ATLAS_TEXTURE);
|
||||||
|
if (blockAtlas == null) return;
|
||||||
|
|
||||||
|
TextureAtlasSprite sprite = blockAtlas.getSprite(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));
|
||||||
|
|
||||||
|
setTextureScale(width / (float) sprite.getWidth(), height / (float) sprite.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.core.materials;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||||
|
import com.jozufozu.flywheel.util.vec.Vec3;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.vector.Quaternion;
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
@ -19,7 +20,7 @@ public class OrientedData extends BasicData {
|
||||||
private float qX;
|
private float qX;
|
||||||
private float qY;
|
private float qY;
|
||||||
private float qZ;
|
private float qZ;
|
||||||
private float qW;
|
private float qW = 1;
|
||||||
|
|
||||||
public OrientedData(Instancer<?> owner) {
|
public OrientedData(Instancer<?> owner) {
|
||||||
super(owner);
|
super(owner);
|
||||||
|
@ -41,6 +42,11 @@ public class OrientedData extends BasicData {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public OrientedData nudge(Vec3 pos) {
|
||||||
|
return nudge(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
public OrientedData nudge(float x, float y, float z) {
|
public OrientedData nudge(float x, float y, float z) {
|
||||||
this.posX += x;
|
this.posX += x;
|
||||||
this.posY += y;
|
this.posY += y;
|
||||||
|
@ -57,6 +63,10 @@ public class OrientedData extends BasicData {
|
||||||
return setPosition((float) pos.getX(), (float) pos.getY(), (float) pos.getZ());
|
return setPosition((float) pos.getX(), (float) pos.getY(), (float) pos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OrientedData setPivot(Vec3 pos) {
|
||||||
|
return setPivot(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
public OrientedData setPivot(float x, float y, float z) {
|
public OrientedData setPivot(float x, float y, float z) {
|
||||||
this.pivotX = x;
|
this.pivotX = x;
|
||||||
this.pivotY = y;
|
this.pivotY = y;
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
public class ModelPart {
|
||||||
|
|
||||||
|
public static PartBuilder builder(int sizeU, int sizeV) {
|
||||||
|
return new PartBuilder(sizeU, sizeV);
|
||||||
|
}
|
||||||
|
}
|
194
src/main/java/com/jozufozu/flywheel/core/model/PartBuilder.java
Normal file
194
src/main/java/com/jozufozu/flywheel/core/model/PartBuilder.java
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
import static com.jozufozu.flywheel.util.RenderMath.nb;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
|
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||||
|
import com.jozufozu.flywheel.backend.model.IndexedModel;
|
||||||
|
import com.jozufozu.flywheel.core.Formats;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
|
||||||
|
public class PartBuilder {
|
||||||
|
|
||||||
|
private float sizeU = 64.0F;
|
||||||
|
private float sizeV = 32.0F;
|
||||||
|
|
||||||
|
private TextureAtlasSprite sprite;
|
||||||
|
|
||||||
|
private final List<CuboidBuilder> cuboids = new ArrayList<>();
|
||||||
|
|
||||||
|
public PartBuilder() { }
|
||||||
|
|
||||||
|
public PartBuilder(int sizeU, int sizeV) {
|
||||||
|
this.setTextureSize(sizeU, sizeV);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PartBuilder setTextureSize(int textureWidth, int textureHeight) {
|
||||||
|
this.sizeU = (float)textureWidth;
|
||||||
|
this.sizeV = (float)textureHeight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PartBuilder sprite(TextureAtlasSprite sprite) {
|
||||||
|
this.sprite = sprite;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CuboidBuilder cuboid() {
|
||||||
|
return new CuboidBuilder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedModel build() {
|
||||||
|
int vertices = 0;
|
||||||
|
|
||||||
|
for (CuboidBuilder cuboid : cuboids) {
|
||||||
|
vertices += cuboid.vertices();
|
||||||
|
}
|
||||||
|
|
||||||
|
VecBuffer buffer = VecBuffer.allocate(vertices * Formats.UNLIT_MODEL.getStride());
|
||||||
|
|
||||||
|
for (CuboidBuilder cuboid : cuboids) {
|
||||||
|
cuboid.buffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
return IndexedModel.fromSequentialQuads(Formats.UNLIT_MODEL, buffer.unwrap(), vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PartBuilder addCuboid(CuboidBuilder builder) {
|
||||||
|
cuboids.add(builder);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CuboidBuilder {
|
||||||
|
|
||||||
|
TextureAtlasSprite sprite;
|
||||||
|
|
||||||
|
Set<Direction> visibleFaces = EnumSet.allOf(Direction.class);
|
||||||
|
int textureOffsetU;
|
||||||
|
int textureOffsetV;
|
||||||
|
|
||||||
|
float posX1;
|
||||||
|
float posY1;
|
||||||
|
float posZ1;
|
||||||
|
float posX2;
|
||||||
|
float posY2;
|
||||||
|
float posZ2;
|
||||||
|
|
||||||
|
final PartBuilder partBuilder;
|
||||||
|
|
||||||
|
CuboidBuilder(PartBuilder partBuilder) {
|
||||||
|
this.partBuilder = partBuilder;
|
||||||
|
this.sprite = partBuilder.sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CuboidBuilder textureOffset(int u, int v) {
|
||||||
|
this.textureOffsetU = u;
|
||||||
|
this.textureOffsetV = v;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CuboidBuilder start(float x, float y, float z) {
|
||||||
|
this.posX1 = x;
|
||||||
|
this.posY1 = y;
|
||||||
|
this.posZ1 = z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CuboidBuilder end(float x, float y, float z) {
|
||||||
|
this.posX2 = x;
|
||||||
|
this.posY2 = y;
|
||||||
|
this.posZ2 = z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CuboidBuilder size(float x, float y, float z) {
|
||||||
|
this.posX2 = posX1 + x;
|
||||||
|
this.posY2 = posY1 + y;
|
||||||
|
this.posZ2 = posZ1 + z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CuboidBuilder sprite(TextureAtlasSprite sprite) {
|
||||||
|
this.sprite = sprite;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PartBuilder endCuboid() {
|
||||||
|
return partBuilder.addCuboid(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int vertices() {
|
||||||
|
return visibleFaces.size() * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buffer(VecBuffer buffer) {
|
||||||
|
|
||||||
|
float sizeX = posX2 - posX1;
|
||||||
|
float sizeY = posY2 - posY1;
|
||||||
|
float sizeZ = posZ2 - posZ1;
|
||||||
|
|
||||||
|
Vector3f lll = new Vector3f(posX1 / 16f, posY1 / 16f, posZ1 / 16f);
|
||||||
|
Vector3f hll = new Vector3f(posX2 / 16f, posY1 / 16f, posZ1 / 16f);
|
||||||
|
Vector3f hhl = new Vector3f(posX2 / 16f, posY2 / 16f, posZ1 / 16f);
|
||||||
|
Vector3f lhl = new Vector3f(posX1 / 16f, posY2 / 16f, posZ1 / 16f);
|
||||||
|
Vector3f llh = new Vector3f(posX1 / 16f, posY1 / 16f, posZ2 / 16f);
|
||||||
|
Vector3f hlh = new Vector3f(posX2 / 16f, posY1 / 16f, posZ2 / 16f);
|
||||||
|
Vector3f hhh = new Vector3f(posX2 / 16f, posY2 / 16f, posZ2 / 16f);
|
||||||
|
Vector3f lhh = new Vector3f(posX1 / 16f, posY2 / 16f, posZ2 / 16f);
|
||||||
|
float f4 = getU((float)textureOffsetU);
|
||||||
|
float f5 = getU((float)textureOffsetU + sizeZ);
|
||||||
|
float f6 = getU((float)textureOffsetU + sizeZ + sizeX);
|
||||||
|
float f7 = getU((float)textureOffsetU + sizeZ + sizeX + sizeX);
|
||||||
|
float f8 = getU((float)textureOffsetU + sizeZ + sizeX + sizeZ);
|
||||||
|
float f9 = getU((float)textureOffsetU + sizeZ + sizeX + sizeZ + sizeX);
|
||||||
|
float f10 = getV((float)textureOffsetV);
|
||||||
|
float f11 = getV((float)textureOffsetV + sizeZ);
|
||||||
|
float f12 = getV((float)textureOffsetV + sizeZ + sizeY);
|
||||||
|
|
||||||
|
quad(buffer, new Vector3f[]{hlh, llh, lll, hll}, f5, f10, f6, f11, Direction.DOWN);
|
||||||
|
quad(buffer, new Vector3f[]{hhl, lhl, lhh, hhh}, f6, f11, f7, f10, Direction.UP);
|
||||||
|
quad(buffer, new Vector3f[]{lll, llh, lhh, lhl}, f4, f11, f5, f12, Direction.WEST);
|
||||||
|
quad(buffer, new Vector3f[]{hll, lll, lhl, hhl}, f5, f11, f6, f12, Direction.NORTH);
|
||||||
|
quad(buffer, new Vector3f[]{hlh, hll, hhl, hhh}, f6, f11, f8, f12, Direction.EAST);
|
||||||
|
quad(buffer, new Vector3f[]{llh, hlh, hhh, lhh}, f8, f11, f9, f12, Direction.SOUTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void quad(VecBuffer buffer, Vector3f[] vertices, float minU, float minV, float maxU, float maxV, Direction dir) {
|
||||||
|
|
||||||
|
Vector3f normal = dir.getUnitVector();
|
||||||
|
|
||||||
|
buffer.putVec3(vertices[0].getX(), vertices[0].getY(), vertices[0].getZ()).putVec3(nb(normal.getX()), nb(normal.getY()), nb(normal.getZ())).putVec2(maxU, minV);
|
||||||
|
buffer.putVec3(vertices[1].getX(), vertices[1].getY(), vertices[1].getZ()).putVec3(nb(normal.getX()), nb(normal.getY()), nb(normal.getZ())).putVec2(minU, minV);
|
||||||
|
buffer.putVec3(vertices[2].getX(), vertices[2].getY(), vertices[2].getZ()).putVec3(nb(normal.getX()), nb(normal.getY()), nb(normal.getZ())).putVec2(minU, maxV);
|
||||||
|
buffer.putVec3(vertices[3].getX(), vertices[3].getY(), vertices[3].getZ()).putVec3(nb(normal.getX()), nb(normal.getY()), nb(normal.getZ())).putVec2(maxU, maxV);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getU(float u) {
|
||||||
|
if (sprite != null)
|
||||||
|
return sprite.getInterpolatedU(u * 16 / partBuilder.sizeU);
|
||||||
|
else
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getV(float v) {
|
||||||
|
if (sprite != null)
|
||||||
|
return sprite.getInterpolatedV(v * 16 / partBuilder.sizeV);
|
||||||
|
else
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
118
src/main/java/com/jozufozu/flywheel/core/model/Readable.java
Normal file
118
src/main/java/com/jozufozu/flywheel/core/model/Readable.java
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
|
||||||
|
public class Readable {
|
||||||
|
public static class ModelBox {
|
||||||
|
private final TexturedQuad[] quads;
|
||||||
|
public final float posX1;
|
||||||
|
public final float posY1;
|
||||||
|
public final float posZ1;
|
||||||
|
public final float posX2;
|
||||||
|
public final float posY2;
|
||||||
|
public final float posZ2;
|
||||||
|
|
||||||
|
public ModelBox(int texOffU, int texOffV, float posX1, float posY1, float posZ1, float sizeX, float sizeY, float sizeZ, float growX, float growY, float growZ, boolean mirror, float texWidth, float texHeight) {
|
||||||
|
this.posX1 = posX1;
|
||||||
|
this.posY1 = posY1;
|
||||||
|
this.posZ1 = posZ1;
|
||||||
|
this.posX2 = posX1 + sizeX;
|
||||||
|
this.posY2 = posY1 + sizeY;
|
||||||
|
this.posZ2 = posZ1 + sizeZ;
|
||||||
|
this.quads = new TexturedQuad[6];
|
||||||
|
float posX2 = posX1 + sizeX;
|
||||||
|
float posY2 = posY1 + sizeY;
|
||||||
|
float posZ2 = posZ1 + sizeZ;
|
||||||
|
posX1 = posX1 - growX;
|
||||||
|
posY1 = posY1 - growY;
|
||||||
|
posZ1 = posZ1 - growZ;
|
||||||
|
posX2 = posX2 + growX;
|
||||||
|
posY2 = posY2 + growY;
|
||||||
|
posZ2 = posZ2 + growZ;
|
||||||
|
if (mirror) {
|
||||||
|
float tmp = posX2;
|
||||||
|
posX2 = posX1;
|
||||||
|
posX1 = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
PositionTextureVertex lll = new PositionTextureVertex(posX1, posY1, posZ1, 0.0F, 0.0F);
|
||||||
|
PositionTextureVertex hll = new PositionTextureVertex(posX2, posY1, posZ1, 0.0F, 8.0F);
|
||||||
|
PositionTextureVertex hhl = new PositionTextureVertex(posX2, posY2, posZ1, 8.0F, 8.0F);
|
||||||
|
PositionTextureVertex lhl = new PositionTextureVertex(posX1, posY2, posZ1, 8.0F, 0.0F);
|
||||||
|
PositionTextureVertex llh = new PositionTextureVertex(posX1, posY1, posZ2, 0.0F, 0.0F);
|
||||||
|
PositionTextureVertex hlh = new PositionTextureVertex(posX2, posY1, posZ2, 0.0F, 8.0F);
|
||||||
|
PositionTextureVertex hhh = new PositionTextureVertex(posX2, posY2, posZ2, 8.0F, 8.0F);
|
||||||
|
PositionTextureVertex lhh = new PositionTextureVertex(posX1, posY2, posZ2, 8.0F, 0.0F);
|
||||||
|
float f4 = (float)texOffU;
|
||||||
|
float f5 = (float)texOffU + sizeZ;
|
||||||
|
float f6 = (float)texOffU + sizeZ + sizeX;
|
||||||
|
float f7 = (float)texOffU + sizeZ + sizeX + sizeX;
|
||||||
|
float f8 = (float)texOffU + sizeZ + sizeX + sizeZ;
|
||||||
|
float f9 = (float)texOffU + sizeZ + sizeX + sizeZ + sizeX;
|
||||||
|
float f10 = (float)texOffV;
|
||||||
|
float f11 = (float)texOffV + sizeZ;
|
||||||
|
float f12 = (float)texOffV + sizeZ + sizeY;
|
||||||
|
this.quads[2] = new TexturedQuad(new PositionTextureVertex[]{hlh, llh, lll, hll}, f5, f10, f6, f11, texWidth, texHeight, mirror, Direction.DOWN);
|
||||||
|
this.quads[3] = new TexturedQuad(new PositionTextureVertex[]{hhl, lhl, lhh, hhh}, f6, f11, f7, f10, texWidth, texHeight, mirror, Direction.UP);
|
||||||
|
this.quads[1] = new TexturedQuad(new PositionTextureVertex[]{lll, llh, lhh, lhl}, f4, f11, f5, f12, texWidth, texHeight, mirror, Direction.WEST);
|
||||||
|
this.quads[4] = new TexturedQuad(new PositionTextureVertex[]{hll, lll, lhl, hhl}, f5, f11, f6, f12, texWidth, texHeight, mirror, Direction.NORTH);
|
||||||
|
this.quads[0] = new TexturedQuad(new PositionTextureVertex[]{hlh, hll, hhl, hhh}, f6, f11, f8, f12, texWidth, texHeight, mirror, Direction.EAST);
|
||||||
|
this.quads[5] = new TexturedQuad(new PositionTextureVertex[]{llh, hlh, hhh, lhh}, f8, f11, f9, f12, texWidth, texHeight, mirror, Direction.SOUTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PositionTextureVertex {
|
||||||
|
public final float x;
|
||||||
|
public final float y;
|
||||||
|
public final float z;
|
||||||
|
public final float u;
|
||||||
|
public final float v;
|
||||||
|
|
||||||
|
public PositionTextureVertex(float x, float y, float z) {
|
||||||
|
this(x, y, z, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionTextureVertex(float x, float y, float z, float u, float v) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.u = u;
|
||||||
|
this.v = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionTextureVertex setTexturePosition(float u, float v) {
|
||||||
|
return new PositionTextureVertex(x, y, z, u, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TexturedQuad {
|
||||||
|
public final PositionTextureVertex[] vertices;
|
||||||
|
public final Vector3f normal;
|
||||||
|
|
||||||
|
public TexturedQuad(PositionTextureVertex[] vertices, float minU, float minV, float maxU, float maxV, float texWidth, float texHeight, boolean p_i225951_8_, Direction p_i225951_9_) {
|
||||||
|
this.vertices = vertices;
|
||||||
|
float w = 0.0F / texWidth;
|
||||||
|
float h = 0.0F / texHeight;
|
||||||
|
vertices[0] = vertices[0].setTexturePosition(maxU / texWidth - w, minV / texHeight + h);
|
||||||
|
vertices[1] = vertices[1].setTexturePosition(minU / texWidth + w, minV / texHeight + h);
|
||||||
|
vertices[2] = vertices[2].setTexturePosition(minU / texWidth + w, maxV / texHeight - h);
|
||||||
|
vertices[3] = vertices[3].setTexturePosition(maxU / texWidth - w, maxV / texHeight - h);
|
||||||
|
if (p_i225951_8_) {
|
||||||
|
int i = vertices.length;
|
||||||
|
|
||||||
|
for(int j = 0; j < i / 2; ++j) {
|
||||||
|
PositionTextureVertex modelrenderer$positiontexturevertex = vertices[j];
|
||||||
|
vertices[j] = vertices[i - 1 - j];
|
||||||
|
vertices[i - 1 - j] = modelrenderer$positiontexturevertex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.normal = p_i225951_9_.getUnitVector();
|
||||||
|
if (p_i225951_8_) {
|
||||||
|
this.normal.multiplyComponentwise(-1.0F, 1.0F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||||
|
package com.jozufozu.flywheel.core;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
|
@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
@ -28,7 +28,9 @@ public class CancelEntityRenderMixin {
|
||||||
.canUseInstancing()) {
|
.canUseInstancing()) {
|
||||||
|
|
||||||
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
||||||
filtered.removeIf(entity -> entity instanceof IInstanceRendered && !((IInstanceRendered) entity).shouldRenderNormally());
|
|
||||||
|
InstancedRenderRegistry r = InstancedRenderRegistry.getInstance();
|
||||||
|
filtered.removeIf(r::shouldSkipRender);
|
||||||
|
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +44,9 @@ public class CancelEntityRenderMixin {
|
||||||
.canUseInstancing()) {
|
.canUseInstancing()) {
|
||||||
|
|
||||||
ArrayList<Entity> filtered = Lists.newArrayList(classInheritanceMultiMap);
|
ArrayList<Entity> filtered = Lists.newArrayList(classInheritanceMultiMap);
|
||||||
filtered.removeIf(entity -> entity instanceof IInstanceRendered && !((IInstanceRendered) entity).shouldRenderNormally());
|
|
||||||
|
InstancedRenderRegistry r = InstancedRenderRegistry.getInstance();
|
||||||
|
filtered.removeIf(r::shouldSkipRender);
|
||||||
|
|
||||||
return filtered.iterator();
|
return filtered.iterator();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
|
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
@ -31,7 +31,8 @@ public class CancelTileEntityRenderMixin {
|
||||||
.canUseInstancing()) {
|
.canUseInstancing()) {
|
||||||
List<TileEntity> tiles = cir.getReturnValue();
|
List<TileEntity> tiles = cir.getReturnValue();
|
||||||
|
|
||||||
tiles.removeIf(tile -> tile instanceof IInstanceRendered && !((IInstanceRendered) tile).shouldRenderNormally());
|
InstancedRenderRegistry r = InstancedRenderRegistry.getInstance();
|
||||||
|
tiles.removeIf(r::shouldSkipRender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
import com.jozufozu.flywheel.backend.OptifineHandler;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.CrumblingRenderer;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
@ -81,7 +82,7 @@ public class RenderHooksMixin {
|
||||||
.getProjectionMatrix());
|
.getProjectionMatrix());
|
||||||
|
|
||||||
Vector3d cameraPos = info.getProjectedView();
|
Vector3d cameraPos = info.getProjectedView();
|
||||||
InstancedRenderDispatcher.renderBreaking(world, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
CrumblingRenderer.renderBreaking(world, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
||||||
|
|
||||||
if (!OptifineHandler.usingShaders()) GL20.glUseProgram(0);
|
if (!OptifineHandler.usingShaders()) GL20.glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.jozufozu.flywheel.mixin.atlas;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
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.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
|
import net.minecraft.profiler.IProfiler;
|
||||||
|
import net.minecraft.resources.IResourceManager;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
@Mixin(AtlasTexture.class)
|
||||||
|
public abstract class AtlasDataMixin {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract ResourceLocation getId();
|
||||||
|
|
||||||
|
@Inject(method = "stitch", at = @At("RETURN"))
|
||||||
|
public void stealAtlasData(IResourceManager resourceManager, Stream<ResourceLocation> locationStream, IProfiler profiler, int mipMapLevels, CallbackInfoReturnable<AtlasTexture.SheetData> cir) {
|
||||||
|
AtlasTexture.SheetData value = cir.getReturnValue();
|
||||||
|
|
||||||
|
SheetDataAccessor dataAccessor = (SheetDataAccessor) value;
|
||||||
|
|
||||||
|
AtlasInfo.setAtlasData(getId(), dataAccessor);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.jozufozu.flywheel.mixin.atlas;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
|
|
||||||
|
@Mixin(AtlasTexture.SheetData.class)
|
||||||
|
public interface SheetDataAccessor {
|
||||||
|
|
||||||
|
@Accessor("width")
|
||||||
|
int getWidth();
|
||||||
|
|
||||||
|
@Accessor("height")
|
||||||
|
int getHeight();
|
||||||
|
|
||||||
|
}
|
|
@ -9,8 +9,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.light.LightUpdater;
|
||||||
import com.jozufozu.flywheel.util.ChunkUtil;
|
import com.jozufozu.flywheel.util.ChunkUtil;
|
||||||
|
|
||||||
|
|
8
src/main/java/com/jozufozu/flywheel/util/RenderMath.java
Normal file
8
src/main/java/com/jozufozu/flywheel/util/RenderMath.java
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package com.jozufozu.flywheel.util;
|
||||||
|
|
||||||
|
public class RenderMath {
|
||||||
|
|
||||||
|
public static byte nb(float f) {
|
||||||
|
return (byte) (f * 127);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import net.minecraft.world.IWorld;
|
||||||
|
|
||||||
public class WorldAttached<T> {
|
public class WorldAttached<T> {
|
||||||
|
|
||||||
Map<IWorld, T> attached;
|
private final Map<IWorld, T> attached;
|
||||||
private final Function<IWorld, T> factory;
|
private final Function<IWorld, T> factory;
|
||||||
|
|
||||||
public WorldAttached(Function<IWorld, T> factory) {
|
public WorldAttached(Function<IWorld, T> factory) {
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.jozufozu.flywheel.util.transform;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
|
||||||
|
public class MatrixTransformStack implements TransformStack {
|
||||||
|
|
||||||
|
private final MatrixStack internal = new MatrixStack();
|
||||||
|
|
||||||
|
public MatrixStack unwrap() {
|
||||||
|
return internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformStack translate(double x, double y, double z) {
|
||||||
|
internal.translate(x, y, z);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformStack multiply(Quaternion quaternion) {
|
||||||
|
internal.multiply(quaternion);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformStack push() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformStack pop() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package com.jozufozu.flywheel.util.transform;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
|
||||||
|
public class QuaternionTransformStack implements TransformStack {
|
||||||
|
|
||||||
|
private final Deque<Transform> stack;
|
||||||
|
|
||||||
|
public QuaternionTransformStack() {
|
||||||
|
stack = new ArrayDeque<>();
|
||||||
|
stack.add(new Transform());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformStack translate(double x, double y, double z) {
|
||||||
|
|
||||||
|
Transform peek = stack.peek();
|
||||||
|
|
||||||
|
double qx = peek.qx;
|
||||||
|
double qy = peek.qy;
|
||||||
|
double qz = peek.qz;
|
||||||
|
double qw = peek.qw;
|
||||||
|
peek.x += qw * x + qy * z - qz * y;
|
||||||
|
peek.y += qw * y - qx * z + qz * x;
|
||||||
|
peek.z += qw * z + qx * y - qy * x;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformStack multiply(Quaternion quaternion) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformStack push() {
|
||||||
|
stack.push(stack.peek().copy());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformStack pop() {
|
||||||
|
|
||||||
|
if (stack.size() == 1) {
|
||||||
|
stack.peek().loadIdentity();
|
||||||
|
} else {
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Transform {
|
||||||
|
public double qx;
|
||||||
|
public double qy;
|
||||||
|
public double qz;
|
||||||
|
public double qw;
|
||||||
|
public double x;
|
||||||
|
public double y;
|
||||||
|
public double z;
|
||||||
|
|
||||||
|
public Transform() {
|
||||||
|
qw = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadIdentity() {
|
||||||
|
x = y = z = 0.0;
|
||||||
|
|
||||||
|
qx = qy = qz = 0.0;
|
||||||
|
qw = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transform copy() {
|
||||||
|
Transform transform = new Transform();
|
||||||
|
|
||||||
|
transform.qx = this.qx;
|
||||||
|
transform.qy = this.qy;
|
||||||
|
transform.qz = this.qz;
|
||||||
|
transform.qw = this.qw;
|
||||||
|
transform.x = this.x;
|
||||||
|
transform.y = this.y;
|
||||||
|
transform.z = this.z;
|
||||||
|
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.jozufozu.flywheel.util.transform;
|
||||||
|
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
import net.minecraft.util.math.vector.Vector3i;
|
||||||
|
|
||||||
|
public interface TransformStack {
|
||||||
|
Vector3d CENTER = new Vector3d(0.5, 0.5, 0.5);
|
||||||
|
|
||||||
|
TransformStack translate(double x, double y, double z);
|
||||||
|
|
||||||
|
TransformStack multiply(Quaternion quaternion);
|
||||||
|
|
||||||
|
TransformStack push();
|
||||||
|
|
||||||
|
TransformStack pop();
|
||||||
|
|
||||||
|
default TransformStack rotate(Direction axis, float radians) {
|
||||||
|
if (radians == 0)
|
||||||
|
return this;
|
||||||
|
return multiply(axis.getUnitVector()
|
||||||
|
.getRadialQuaternion(radians));
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack rotate(double angle, Direction.Axis axis) {
|
||||||
|
Vector3f vec =
|
||||||
|
axis == Direction.Axis.X ? Vector3f.POSITIVE_X : axis == Direction.Axis.Y ? Vector3f.POSITIVE_Y : Vector3f.POSITIVE_Z;
|
||||||
|
return multiply(vec, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack rotateX(double angle) {
|
||||||
|
return multiply(Vector3f.POSITIVE_X, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack rotateY(double angle) {
|
||||||
|
return multiply(Vector3f.POSITIVE_Y, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack rotateZ(double angle) {
|
||||||
|
return multiply(Vector3f.POSITIVE_Z, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack centre() {
|
||||||
|
return translate(CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack unCentre() {
|
||||||
|
return translateBack(CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack translate(Vector3i vec) {
|
||||||
|
return translate(vec.getX(), vec.getY(), vec.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack translate(Vector3d vec) {
|
||||||
|
return translate(vec.x, vec.y, vec.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack translateBack(Vector3d vec) {
|
||||||
|
return translate(-vec.x, -vec.y, -vec.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack nudge(int id) {
|
||||||
|
long randomBits = (long) id * 31L * 493286711L;
|
||||||
|
randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L;
|
||||||
|
float xNudge = (((float) (randomBits >> 16 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
|
||||||
|
float yNudge = (((float) (randomBits >> 20 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
|
||||||
|
float zNudge = (((float) (randomBits >> 24 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
|
||||||
|
return translate(xNudge, yNudge, zNudge);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TransformStack multiply(Vector3f axis, double angle) {
|
||||||
|
if (angle == 0)
|
||||||
|
return this;
|
||||||
|
return multiply(axis.getDegreesQuaternion((float) angle));
|
||||||
|
}
|
||||||
|
}
|
80
src/main/java/com/jozufozu/flywheel/util/vec/Vec3.java
Normal file
80
src/main/java/com/jozufozu/flywheel/util/vec/Vec3.java
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package com.jozufozu.flywheel.util.vec;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
|
||||||
|
public class Vec3 {
|
||||||
|
public static final Vec3 NEGATIVE_X = new Vec3(-1.0F, 0.0F, 0.0F);
|
||||||
|
public static final Vec3 POSITIVE_X = new Vec3(1.0F, 0.0F, 0.0F);
|
||||||
|
public static final Vec3 NEGATIVE_Y = new Vec3(0.0F, -1.0F, 0.0F);
|
||||||
|
public static final Vec3 POSITIVE_Y = new Vec3(0.0F, 1.0F, 0.0F);
|
||||||
|
public static final Vec3 NEGATIVE_Z = new Vec3(0.0F, 0.0F, -1.0F);
|
||||||
|
public static final Vec3 POSITIVE_Z = new Vec3(0.0F, 0.0F, 1.0F);
|
||||||
|
|
||||||
|
private float x;
|
||||||
|
private float y;
|
||||||
|
private float z;
|
||||||
|
|
||||||
|
public Vec3(float x, float y, float z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 multiply(Quaternion quat) {
|
||||||
|
Vec4 vec4 = new Vec4(this, 1f);
|
||||||
|
|
||||||
|
vec4.multiply(quat);
|
||||||
|
|
||||||
|
return set(vec4.getX(), vec4.getY(), vec4.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 copy() {
|
||||||
|
return new Vec3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3f convert() {
|
||||||
|
return new Vector3f(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 set(float x, float y, float z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 add(Vec3 v) {
|
||||||
|
return add(v.x, v.y, v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 add(float x, float y, float z) {
|
||||||
|
this.x += x;
|
||||||
|
this.y += y;
|
||||||
|
this.z += z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 sub(Vec3 v) {
|
||||||
|
return sub(v.x, v.y, v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 sub(float x, float y, float z) {
|
||||||
|
this.x -= x;
|
||||||
|
this.y -= y;
|
||||||
|
this.z -= z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
66
src/main/java/com/jozufozu/flywheel/util/vec/Vec4.java
Normal file
66
src/main/java/com/jozufozu/flywheel/util/vec/Vec4.java
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package com.jozufozu.flywheel.util.vec;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
|
||||||
|
public class Vec4 {
|
||||||
|
|
||||||
|
private float x;
|
||||||
|
private float y;
|
||||||
|
private float z;
|
||||||
|
private float w;
|
||||||
|
|
||||||
|
public Vec4(float x, float y, float z, float w) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec4(Vec3 vec3) {
|
||||||
|
this(vec3, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec4(Vec3 vec3, float w) {
|
||||||
|
this.x = vec3.getX();
|
||||||
|
this.y = vec3.getY();
|
||||||
|
this.z = vec3.getZ();
|
||||||
|
this.w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec4 multiply(Quaternion quat) {
|
||||||
|
Quaternion quaternion = new Quaternion(quat);
|
||||||
|
quaternion.multiply(new Quaternion(this.getX(), this.getY(), this.getZ(), 0.0F));
|
||||||
|
Quaternion quaternion1 = new Quaternion(quat);
|
||||||
|
quaternion1.conjugate();
|
||||||
|
quaternion.multiply(quaternion1);
|
||||||
|
return set(quaternion.getX(), quaternion.getY(), quaternion.getZ(), this.getW());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 xyz() {
|
||||||
|
return new Vec3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getW() {
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec4 set(float x, float y, float z, float w) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.w = w;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
||||||
|
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||||
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
|
import com.jozufozu.flywheel.core.materials.OrientedData;
|
||||||
|
import com.jozufozu.flywheel.core.model.ModelPart;
|
||||||
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.tileentity.BellTileEntityRenderer;
|
||||||
|
import net.minecraft.tileentity.BellTileEntity;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
|
||||||
|
public class BellInstance extends TileEntityInstance<BellTileEntity> implements IDynamicInstance {
|
||||||
|
|
||||||
|
private final OrientedData bell;
|
||||||
|
|
||||||
|
private float lastRingTime = Float.NaN;
|
||||||
|
|
||||||
|
public BellInstance(MaterialManager<?> materialManager, BellTileEntity tile) {
|
||||||
|
super(materialManager, tile);
|
||||||
|
|
||||||
|
bell = createBellInstance()
|
||||||
|
.setPivot(0.5f, 0.75f, 0.5f)
|
||||||
|
.setPosition(getInstancePosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginFrame() {
|
||||||
|
float ringTime = (float)tile.ringingTicks + AnimationTickHolder.getPartialTicks();
|
||||||
|
|
||||||
|
if (ringTime == lastRingTime) return;
|
||||||
|
lastRingTime = ringTime;
|
||||||
|
|
||||||
|
if (tile.isRinging) {
|
||||||
|
float angle = MathHelper.sin(ringTime / (float) Math.PI) / (4.0F + ringTime / 3.0F);
|
||||||
|
|
||||||
|
Vector3f ringAxis = tile.ringDirection.rotateYCCW().getUnitVector();
|
||||||
|
|
||||||
|
bell.setRotation(ringAxis.getRadialQuaternion(angle));
|
||||||
|
} else {
|
||||||
|
bell.setRotation(Quaternion.IDENTITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLight() {
|
||||||
|
relight(getWorldPosition(), bell);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
bell.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrientedData createBellInstance() {
|
||||||
|
return materialManager.getMaterial(Materials.ORIENTED)
|
||||||
|
.get(tile.getType(), BellInstance::createBellModel)
|
||||||
|
.createInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BufferedModel createBellModel() {
|
||||||
|
return ModelPart.builder(32, 32)
|
||||||
|
.sprite(BellTileEntityRenderer.field_217653_c.getSprite())
|
||||||
|
.cuboid()
|
||||||
|
.start(5.0F, 6.0F, 5.0F)
|
||||||
|
.size(6.0F, 7.0F, 6.0F)
|
||||||
|
.endCuboid()
|
||||||
|
.cuboid()
|
||||||
|
.textureOffset(0, 13)
|
||||||
|
.start(4.0F, 4.0F, 4.0F)
|
||||||
|
.size(8.0F, 2.0F, 8.0F)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
216
src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
Normal file
216
src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
||||||
|
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||||
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
|
import com.jozufozu.flywheel.core.materials.ModelData;
|
||||||
|
import com.jozufozu.flywheel.core.materials.OrientedData;
|
||||||
|
import com.jozufozu.flywheel.core.model.ModelPart;
|
||||||
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
|
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.floats.Float2FloatFunction;
|
||||||
|
import net.minecraft.block.AbstractChestBlock;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.ChestBlock;
|
||||||
|
import net.minecraft.client.renderer.Atlases;
|
||||||
|
import net.minecraft.client.renderer.model.RenderMaterial;
|
||||||
|
import net.minecraft.state.properties.ChestType;
|
||||||
|
import net.minecraft.tileentity.ChestTileEntity;
|
||||||
|
import net.minecraft.tileentity.IChestLid;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.tileentity.TileEntityMerger;
|
||||||
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
|
||||||
|
public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityInstance<T> implements IDynamicInstance {
|
||||||
|
|
||||||
|
private final OrientedData body;
|
||||||
|
private final ModelData lid;
|
||||||
|
|
||||||
|
private final Float2FloatFunction lidProgress;
|
||||||
|
private final RenderMaterial renderMaterial;
|
||||||
|
@Nonnull
|
||||||
|
private final ChestType chestType;
|
||||||
|
private final Quaternion baseRotation;
|
||||||
|
|
||||||
|
private float lastProgress = Float.NaN;
|
||||||
|
|
||||||
|
public ChestInstance(MaterialManager<?> materialManager, T tile) {
|
||||||
|
super(materialManager, tile);
|
||||||
|
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
|
||||||
|
chestType = blockState.contains(ChestBlock.TYPE) ? blockState.get(ChestBlock.TYPE) : ChestType.SINGLE;
|
||||||
|
renderMaterial = Atlases.getChestTexture(tile, chestType, isChristmas());
|
||||||
|
|
||||||
|
body = baseInstance()
|
||||||
|
.setPosition(getInstancePosition());
|
||||||
|
lid = lidInstance();
|
||||||
|
|
||||||
|
if (block instanceof AbstractChestBlock) {
|
||||||
|
|
||||||
|
// MatrixStack stack = new MatrixStack();
|
||||||
|
//
|
||||||
|
// stack.push();
|
||||||
|
float horizontalAngle = blockState.get(ChestBlock.FACING).getHorizontalAngle();
|
||||||
|
|
||||||
|
baseRotation = Vector3f.POSITIVE_Y.getDegreesQuaternion(-horizontalAngle);
|
||||||
|
|
||||||
|
body.setRotation(baseRotation);
|
||||||
|
|
||||||
|
AbstractChestBlock<?> chestBlock = (AbstractChestBlock<?>) block;
|
||||||
|
|
||||||
|
TileEntityMerger.ICallbackWrapper<? extends ChestTileEntity> wrapper = chestBlock.getBlockEntitySource(blockState, world, getWorldPosition(), true);
|
||||||
|
|
||||||
|
this.lidProgress = wrapper.apply(ChestBlock.getAnimationProgressRetriever(tile));
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
baseRotation = Quaternion.IDENTITY;
|
||||||
|
lidProgress = $ -> 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginFrame() {
|
||||||
|
float progress = lidProgress.get(AnimationTickHolder.getPartialTicks());
|
||||||
|
|
||||||
|
if (lastProgress == progress) return;
|
||||||
|
|
||||||
|
lastProgress = progress;
|
||||||
|
|
||||||
|
progress = 1.0F - progress;
|
||||||
|
progress = 1.0F - progress * progress * progress;
|
||||||
|
|
||||||
|
float angleX = -(progress * ((float) Math.PI / 2F));
|
||||||
|
|
||||||
|
MatrixTransformStack stack = new MatrixTransformStack();
|
||||||
|
|
||||||
|
stack.translate(getInstancePosition())
|
||||||
|
.translate(0, 9f/16f, 0)
|
||||||
|
.centre()
|
||||||
|
.multiply(baseRotation)
|
||||||
|
.unCentre()
|
||||||
|
.translate(0, 0, 1f / 16f)
|
||||||
|
.multiply(Vector3f.POSITIVE_X.getRadialQuaternion(angleX))
|
||||||
|
.translate(0, 0, -1f / 16f);
|
||||||
|
|
||||||
|
lid.setTransform(stack.unwrap());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLight() {
|
||||||
|
relight(getWorldPosition(), body, lid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
body.delete();
|
||||||
|
lid.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrientedData baseInstance() {
|
||||||
|
|
||||||
|
return materialManager.getMaterial(Materials.ORIENTED, renderMaterial.getAtlasId())
|
||||||
|
.get("base_" + renderMaterial.getTextureId(), this::getBaseModel)
|
||||||
|
.createInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModelData lidInstance() {
|
||||||
|
|
||||||
|
return materialManager.getMaterial(Materials.TRANSFORMED, renderMaterial.getAtlasId())
|
||||||
|
.get("lid_" + renderMaterial.getTextureId(), this::getLidModel)
|
||||||
|
.createInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedModel getBaseModel() {
|
||||||
|
|
||||||
|
switch (chestType) {
|
||||||
|
case LEFT:
|
||||||
|
return ModelPart.builder(64, 64)
|
||||||
|
.sprite(renderMaterial.getSprite())
|
||||||
|
.cuboid()
|
||||||
|
.textureOffset(0, 19)
|
||||||
|
.start(0, 0, 1)
|
||||||
|
.size(15, 10, 14)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
case RIGHT:
|
||||||
|
return ModelPart.builder(64, 64)
|
||||||
|
.sprite(renderMaterial.getSprite())
|
||||||
|
.cuboid()
|
||||||
|
.textureOffset(0, 19)
|
||||||
|
.start(1, 0, 1)
|
||||||
|
.size(15, 10, 14)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ModelPart.builder(64, 64)
|
||||||
|
.sprite(renderMaterial.getSprite())
|
||||||
|
.cuboid()
|
||||||
|
.textureOffset(0, 19)
|
||||||
|
.start(1, 0, 1)
|
||||||
|
.end(15, 10, 15)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedModel getLidModel() {
|
||||||
|
|
||||||
|
switch (chestType) {
|
||||||
|
case LEFT:
|
||||||
|
return ModelPart.builder(64, 64)
|
||||||
|
.sprite(renderMaterial.getSprite())
|
||||||
|
.cuboid()
|
||||||
|
.textureOffset(0, 0)
|
||||||
|
.start(0, 0, 1)
|
||||||
|
.size(15, 5, 14)
|
||||||
|
.endCuboid()
|
||||||
|
.cuboid()
|
||||||
|
.start(0, -2, 15)
|
||||||
|
.size(1, 4, 1)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
case RIGHT:
|
||||||
|
return ModelPart.builder(64, 64)
|
||||||
|
.sprite(renderMaterial.getSprite())
|
||||||
|
.cuboid()
|
||||||
|
.textureOffset(0, 0)
|
||||||
|
.start(1, 0, 1)
|
||||||
|
.size(15, 5, 14)
|
||||||
|
.endCuboid()
|
||||||
|
.cuboid()
|
||||||
|
.start(15, -2, 15)
|
||||||
|
.size(1, 4, 1)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ModelPart.builder(64, 64)
|
||||||
|
.sprite(renderMaterial.getSprite())
|
||||||
|
.cuboid()
|
||||||
|
.textureOffset(0, 0)
|
||||||
|
.start(1, 0, 1)
|
||||||
|
.size(14, 5, 14)
|
||||||
|
.endCuboid()
|
||||||
|
.cuboid()
|
||||||
|
.start(7, -2, 15)
|
||||||
|
.size(2, 4, 1)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isChristmas() {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
return calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DATE) >= 24 && calendar.get(Calendar.DATE) <= 26;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO:
|
||||||
|
* <table>
|
||||||
|
* <tr><td>{@link TileEntityType#SIGN}</td><td> {@link net.minecraft.client.renderer.tileentity.SignTileEntityRenderer SignTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#MOB_SPAWNER}</td><td> {@link net.minecraft.client.renderer.tileentity.MobSpawnerTileEntityRenderer MobSpawnerTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#PISTON}</td><td> {@link net.minecraft.client.renderer.tileentity.PistonTileEntityRenderer PistonTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#ENCHANTING_TABLE}</td><td> {@link net.minecraft.client.renderer.tileentity.EnchantmentTableTileEntityRenderer EnchantmentTableTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#LECTERN}</td><td> {@link net.minecraft.client.renderer.tileentity.LecternTileEntityRenderer LecternTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#END_PORTAL}</td><td> {@link net.minecraft.client.renderer.tileentity.EndPortalTileEntityRenderer EndPortalTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#END_GATEWAY}</td><td> {@link net.minecraft.client.renderer.tileentity.EndGatewayTileEntityRenderer EndGatewayTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#BEACON}</td><td> {@link net.minecraft.client.renderer.tileentity.BeaconTileEntityRenderer BeaconTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#SKULL}</td><td> {@link net.minecraft.client.renderer.tileentity.SkullTileEntityRenderer SkullTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#BANNER}</td><td> {@link net.minecraft.client.renderer.tileentity.BannerTileEntityRenderer BannerTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#STRUCTURE_BLOCK}</td><td> {@link net.minecraft.client.renderer.tileentity.StructureTileEntityRenderer StructureTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#SHULKER_BOX}</td><td> {@link net.minecraft.client.renderer.tileentity.ShulkerBoxTileEntityRenderer ShulkerBoxTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#BED}</td><td> {@link net.minecraft.client.renderer.tileentity.BedTileEntityRenderer BedTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#CONDUIT}</td><td> {@link net.minecraft.client.renderer.tileentity.ConduitTileEntityRenderer ConduitTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#BELL}</td><td> {@link net.minecraft.client.renderer.tileentity.BellTileEntityRenderer BellTileEntityRenderer}</td></tr>
|
||||||
|
* <tr><td>{@link TileEntityType#CAMPFIRE}</td><td> {@link net.minecraft.client.renderer.tileentity.CampfireTileEntityRenderer CampfireTileEntityRenderer}</td></tr>
|
||||||
|
* </table>
|
||||||
|
*/
|
||||||
|
public class VanillaInstances {
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
InstancedRenderRegistry r = InstancedRenderRegistry.getInstance();
|
||||||
|
|
||||||
|
r.tile(TileEntityType.CHEST)
|
||||||
|
.setSkipRender(true)
|
||||||
|
.factory(ChestInstance::new);
|
||||||
|
r.tile(TileEntityType.ENDER_CHEST)
|
||||||
|
.setSkipRender(true)
|
||||||
|
.factory(ChestInstance::new);
|
||||||
|
r.tile(TileEntityType.TRAPPED_CHEST)
|
||||||
|
.setSkipRender(true)
|
||||||
|
.factory(ChestInstance::new);
|
||||||
|
|
||||||
|
r.tile(TileEntityType.BELL)
|
||||||
|
.setSkipRender(true)
|
||||||
|
.factory(BellInstance::new);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,8 @@
|
||||||
"StoreProjectionMatrixMixin",
|
"StoreProjectionMatrixMixin",
|
||||||
"TileRemoveMixin",
|
"TileRemoveMixin",
|
||||||
"TileWorldHookMixin",
|
"TileWorldHookMixin",
|
||||||
|
"atlas.AtlasDataMixin",
|
||||||
|
"atlas.SheetDataAccessor",
|
||||||
"light.LightUpdateMixin",
|
"light.LightUpdateMixin",
|
||||||
"light.NetworkLightUpdateMixin"
|
"light.NetworkLightUpdateMixin"
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue