mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-23 11:28:10 +01:00
Buffing the Buffers
- Refactored the smart bytebuffers to use one centralized system. - Unified caches to a single instance - SuperByteBuffers collect transformations in a matrix rather than performing individual vertex manipulations in subclasses
This commit is contained in:
parent
e537474c8b
commit
786789c312
40 changed files with 737 additions and 810 deletions
|
@ -47,7 +47,7 @@ public class ClientEvents {
|
|||
|
||||
if (!KineticDebugger.isActive() && KineticTileEntityRenderer.rainbowMode) {
|
||||
KineticTileEntityRenderer.rainbowMode = false;
|
||||
KineticTileEntityRenderer.invalidateCache();
|
||||
CreateClient.bufferCache.invalidate();
|
||||
}
|
||||
|
||||
ScreenOpener.tick();
|
||||
|
|
|
@ -6,9 +6,11 @@ import java.util.function.Function;
|
|||
import com.simibubi.create.foundation.block.CTModel;
|
||||
import com.simibubi.create.foundation.block.IHaveConnectedTextures;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.modules.contraptions.CachedBufferReloader;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBufferCache;
|
||||
import com.simibubi.create.modules.contraptions.WrenchModel;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.EncasedFanParticleHandler;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.ContraptionRenderer;
|
||||
import com.simibubi.create.modules.curiosities.deforester.DeforesterModel;
|
||||
import com.simibubi.create.modules.curiosities.partialWindows.WindowInABlockModel;
|
||||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel;
|
||||
|
@ -44,6 +46,7 @@ public class CreateClient {
|
|||
public static SchematicHologram schematicHologram;
|
||||
public static SchematicAndQuillHandler schematicAndQuillHandler;
|
||||
public static EncasedFanParticleHandler fanParticles;
|
||||
public static SuperByteBufferCache bufferCache;
|
||||
public static int renderTicks;
|
||||
|
||||
public static ModConfig config;
|
||||
|
@ -65,6 +68,10 @@ public class CreateClient {
|
|||
schematicAndQuillHandler = new SchematicAndQuillHandler();
|
||||
fanParticles = new EncasedFanParticleHandler();
|
||||
|
||||
bufferCache = new SuperByteBufferCache();
|
||||
bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
|
||||
bufferCache.registerCompartment(ContraptionRenderer.CONTRAPTION, 20);
|
||||
|
||||
AllKeys.register();
|
||||
AllContainers.registerScreenFactories();
|
||||
AllTileEntities.registerRenderers();
|
||||
|
@ -74,7 +81,7 @@ public class CreateClient {
|
|||
|
||||
IResourceManager resourceManager = Minecraft.getInstance().getResourceManager();
|
||||
if (resourceManager instanceof IReloadableResourceManager)
|
||||
((IReloadableResourceManager) resourceManager).addReloadListener(new CachedBufferReloader());
|
||||
((IReloadableResourceManager) resourceManager).addReloadListener(new ResourceReloadHandler());
|
||||
}
|
||||
|
||||
public static void createConfigs(ModConfig.ModConfigEvent event) {
|
||||
|
|
24
src/main/java/com/simibubi/create/ResourceReloadHandler.java
Normal file
24
src/main/java/com/simibubi/create/ResourceReloadHandler.java
Normal file
|
@ -0,0 +1,24 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.foundation.block.SpriteShifter;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntityRenderer;
|
||||
|
||||
import net.minecraft.client.resources.ReloadListener;
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
|
||||
public class ResourceReloadHandler extends ReloadListener<String> {
|
||||
|
||||
@Override
|
||||
protected String prepare(IResourceManager resourceManagerIn, IProfiler profilerIn) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(String splashList, IResourceManager resourceManagerIn, IProfiler profilerIn) {
|
||||
MechanicalBearingTileEntityRenderer.invalidateCache();
|
||||
SpriteShifter.reloadUVs();
|
||||
CreateClient.bufferCache.invalidate();
|
||||
}
|
||||
|
||||
}
|
|
@ -5,7 +5,7 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.foundation.block.CTModelTextureHandler.TextureEntry;
|
||||
import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -24,7 +24,7 @@ import net.minecraftforge.client.model.data.ModelProperty;
|
|||
public class CTModel extends BakedModelWrapper<IBakedModel> {
|
||||
|
||||
private static ModelProperty<CTData> CT_PROPERTY = new ModelProperty<>();
|
||||
private TextureEntry texture;
|
||||
private SpriteShiftEntry texture;
|
||||
|
||||
private class CTData {
|
||||
int[] textures;
|
||||
|
@ -45,7 +45,7 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
|
|||
|
||||
public CTModel(IBakedModel originalModel, String blockId) {
|
||||
super(originalModel);
|
||||
texture = CTModelTextureHandler.get(blockId);
|
||||
texture = SpriteShifter.getCT(blockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,8 +82,8 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
|
|||
float uShift = (index % 8) * textureSize;
|
||||
float vShift = (index / 8) * textureSize * 2;
|
||||
|
||||
uShift = texture.connectedTextures.getInterpolatedU((index % 8) * 2) - texture.originalTexture.getMinU();
|
||||
vShift = texture.connectedTextures.getInterpolatedV((index / 8) * 2) - texture.originalTexture.getMinV();
|
||||
uShift = texture.target.getInterpolatedU((index % 8) * 2) - texture.original.getMinU();
|
||||
vShift = texture.target.getInterpolatedV((index / 8) * 2) - texture.original.getMinV();
|
||||
|
||||
BakedQuad newQuad = new BakedQuad(Arrays.copyOf(quad.getVertexData(), quad.getVertexData().length),
|
||||
quad.getTintIndex(), quad.getFace(), quad.getSprite(), quad.shouldApplyDiffuseLighting(),
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
package com.simibubi.create.foundation.block;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class CTModelTextureHandler {
|
||||
|
||||
static class TextureEntry {
|
||||
ResourceLocation originalTextureLocation;
|
||||
ResourceLocation connectedTextureLocation;
|
||||
TextureAtlasSprite originalTexture;
|
||||
TextureAtlasSprite connectedTextures;
|
||||
|
||||
void loadTextures() {
|
||||
AtlasTexture textureMap = Minecraft.getInstance().getTextureMap();
|
||||
originalTexture = textureMap.getSprite(originalTextureLocation);
|
||||
connectedTextures = textureMap.getSprite(connectedTextureLocation);
|
||||
}
|
||||
}
|
||||
|
||||
static Map<String, TextureEntry> textures = new HashMap<>();
|
||||
|
||||
public static TextureEntry get(String blockId) {
|
||||
if (textures.containsKey(blockId))
|
||||
return textures.get(blockId);
|
||||
|
||||
TextureEntry entry = new TextureEntry();
|
||||
entry.originalTextureLocation = new ResourceLocation(Create.ID, "block/" + blockId);
|
||||
entry.connectedTextureLocation = new ResourceLocation(Create.ID, "block/connected/" + blockId);
|
||||
entry.loadTextures();
|
||||
textures.put(blockId, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public static void reloadUVs() {
|
||||
textures.values().forEach(TextureEntry::loadTextures);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.simibubi.create.foundation.block;
|
||||
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.animation.TileEntityRendererFast;
|
||||
|
||||
public abstract class ColoredOverlayTileEntityRenderer<T extends TileEntity> extends TileEntityRendererFast<T> {
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(T te, double x, double y, double z, float partialTicks, int destroyStage,
|
||||
BufferBuilder buffer) {
|
||||
SuperByteBuffer render = render(getWorld(), te.getPos(), getOverlayState(te), getColor(te, partialTicks));
|
||||
buffer.putBulkData(render.translate(x, y, z).build());
|
||||
}
|
||||
|
||||
protected abstract int getColor(T te, float partialTicks);
|
||||
|
||||
protected abstract BlockState getOverlayState(T te);
|
||||
|
||||
public static SuperByteBuffer render(World world, BlockPos pos, BlockState state, int color) {
|
||||
int packedLightmapCoords = state.getPackedLightmapCoords(world, pos);
|
||||
SuperByteBuffer buffer = CreateClient.bufferCache.renderGenericBlockModel(state);
|
||||
return buffer.color(color).light(packedLightmapCoords);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.simibubi.create.foundation.block;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class SpriteShifter {
|
||||
|
||||
public static class SpriteShiftEntry {
|
||||
ResourceLocation originalTextureLocation;
|
||||
ResourceLocation targetTextureLocation;
|
||||
TextureAtlasSprite original;
|
||||
TextureAtlasSprite target;
|
||||
|
||||
void loadTextures() {
|
||||
AtlasTexture textureMap = Minecraft.getInstance().getTextureMap();
|
||||
original = textureMap.getSprite(originalTextureLocation);
|
||||
target = textureMap.getSprite(targetTextureLocation);
|
||||
}
|
||||
|
||||
public TextureAtlasSprite getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public TextureAtlasSprite getOriginal() {
|
||||
return original;
|
||||
}
|
||||
}
|
||||
|
||||
static Map<String, SpriteShiftEntry> textures = new HashMap<>();
|
||||
|
||||
public static SpriteShiftEntry getCT(String blockId) {
|
||||
return get("block/" + blockId, "block/connected/" + blockId);
|
||||
}
|
||||
|
||||
public static SpriteShiftEntry get(String originalLocation, String targetLocation) {
|
||||
String key = originalLocation + "->" + targetLocation;
|
||||
if (textures.containsKey(key))
|
||||
return textures.get(key);
|
||||
|
||||
SpriteShiftEntry entry = new SpriteShiftEntry();
|
||||
entry.originalTextureLocation = new ResourceLocation(Create.ID, originalLocation);
|
||||
entry.targetTextureLocation = new ResourceLocation(Create.ID, targetLocation);
|
||||
entry.loadTextures();
|
||||
textures.put(key, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public static void reloadUVs() {
|
||||
textures.values().forEach(SpriteShiftEntry::loadTextures);
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
@Deprecated
|
||||
public abstract class BufferManipulator {
|
||||
|
||||
public static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
public class ColoredIndicatorRenderer extends BufferManipulator {
|
||||
|
||||
protected static Map<BlockState, ColoredIndicatorRenderer> cachedBuffers = new HashMap<>();
|
||||
|
||||
public ColoredIndicatorRenderer(ByteBuffer original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(float xIn, float yIn, float zIn, int color, int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
byte r = (byte) (color >> 16);
|
||||
byte g = (byte) ((color >> 8) & 0xFF);
|
||||
byte b = (byte) (color & 0xFF);
|
||||
byte a = (byte) 255;
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
putColor(mutable, vertex, r, g, b, a);
|
||||
putPos(mutable, vertex, getX(original, vertex) + xIn, getY(original, vertex) + yIn,
|
||||
getZ(original, vertex) + zIn);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public static <R extends ColoredIndicatorRenderer> void cacheIfMissing(BlockState renderedState,
|
||||
Function<ByteBuffer, R> factory) {
|
||||
if (!cachedBuffers.containsKey(renderedState)) {
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
IBakedModel originalModel = dispatcher.getModelForState(renderedState);
|
||||
BufferBuilder builder = new BufferBuilder(0);
|
||||
Random random = new Random();
|
||||
|
||||
builder.setTranslation(0, 1, 0);
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
blockRenderer.renderModelFlat(Minecraft.getInstance().world, originalModel, renderedState,
|
||||
BlockPos.ZERO.down(), builder, true, random, 42, EmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
|
||||
cachedBuffers.put(renderedState, factory.apply(builder.getByteBuffer()));
|
||||
}
|
||||
}
|
||||
|
||||
public static ColoredIndicatorRenderer get(BlockState state) {
|
||||
cacheIfMissing(state, ColoredIndicatorRenderer::new);
|
||||
return cachedBuffers.get(state);
|
||||
}
|
||||
|
||||
|
||||
public static void invalidateCache() {
|
||||
cachedBuffers.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.vecmath.Matrix4f;
|
||||
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
|
||||
public class SuperByteBuffer {
|
||||
|
||||
public interface IVertexLighter {
|
||||
public int getPackedLight(float x, float y, float z);
|
||||
}
|
||||
|
||||
public static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
|
||||
protected ByteBuffer original;
|
||||
protected ByteBuffer mutable;
|
||||
|
||||
// Vertex Position
|
||||
private Matrix4f transforms;
|
||||
private Matrix4f t;
|
||||
|
||||
// Vertex Texture Coords
|
||||
private boolean shouldShiftUV;
|
||||
private float uShift, vShift;
|
||||
|
||||
// Vertex Lighting
|
||||
private boolean shouldLight;
|
||||
private IVertexLighter vertexLighter;
|
||||
private int packedLightCoords;
|
||||
|
||||
// Vertex Coloring
|
||||
private boolean shouldColor;
|
||||
private int r, g, b, a;
|
||||
|
||||
public SuperByteBuffer(ByteBuffer original) {
|
||||
original.rewind();
|
||||
this.original = original;
|
||||
|
||||
this.mutable = GLAllocation.createDirectByteBuffer(original.capacity());
|
||||
this.mutable.order(original.order());
|
||||
this.mutable.limit(original.limit());
|
||||
mutable.put(this.original);
|
||||
mutable.rewind();
|
||||
|
||||
t = new Matrix4f();
|
||||
transforms = new Matrix4f();
|
||||
transforms.setIdentity();
|
||||
}
|
||||
|
||||
public ByteBuffer build() {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
float x, y, z = 0;
|
||||
float x2, y2, z2 = 0;
|
||||
|
||||
Matrix4f t = transforms;
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
x = getX(original, vertex);
|
||||
y = getY(original, vertex);
|
||||
z = getZ(original, vertex);
|
||||
|
||||
x2 = t.m00 * x + t.m01 * y + t.m02 * z + t.m03;
|
||||
y2 = t.m10 * x + t.m11 * y + t.m12 * z + t.m13;
|
||||
z2 = t.m20 * x + t.m21 * y + t.m22 * z + t.m23;
|
||||
|
||||
putPos(mutable, vertex, x2, y2, z2);
|
||||
|
||||
if (shouldColor) {
|
||||
byte lumByte = getR(original, vertex);
|
||||
float lum = (lumByte < 0 ? 255 + lumByte : lumByte) / 256f;
|
||||
int r2 = (int) (r * lum);
|
||||
int g2 = (int) (g * lum);
|
||||
int b2 = (int) (b * lum);
|
||||
putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) a);
|
||||
}
|
||||
|
||||
if (shouldShiftUV)
|
||||
putUV(mutable, vertex, getU(original, vertex) + uShift, getV(original, vertex) + vShift);
|
||||
|
||||
if (shouldLight) {
|
||||
if (vertexLighter != null)
|
||||
putLight(mutable, vertex, vertexLighter.getPackedLight(x2, y2, z2));
|
||||
else
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
}
|
||||
|
||||
t.setIdentity();
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public void renderInto(BufferBuilder buffer) {
|
||||
buffer.putBulkData(build());
|
||||
}
|
||||
|
||||
public SuperByteBuffer translate(double x, double y, double z) {
|
||||
return translate((float) x, (float) y, (float) z);
|
||||
}
|
||||
|
||||
public SuperByteBuffer translate(float x, float y, float z) {
|
||||
transforms.m03 += x;
|
||||
transforms.m13 += y;
|
||||
transforms.m23 += z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer rotate(Axis axis, float angle) {
|
||||
if (angle == 0)
|
||||
return this;
|
||||
t.setIdentity();
|
||||
if (axis == Axis.X)
|
||||
t.rotX(angle);
|
||||
else if (axis == Axis.Y)
|
||||
t.rotY(angle);
|
||||
else
|
||||
t.rotZ(angle);
|
||||
transforms.mul(t, transforms);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer rotateCentered(Axis axis, float angle) {
|
||||
return translate(-.5f, -.5f, -.5f).rotate(axis, angle).translate(.5f, .5f, .5f);
|
||||
}
|
||||
|
||||
public SuperByteBuffer shiftUV(TextureAtlasSprite from, TextureAtlasSprite to) {
|
||||
shouldShiftUV = true;
|
||||
uShift = to.getMinU() - from.getMinU();
|
||||
vShift = to.getMinV() - from.getMinV();
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer shiftUVtoSheet(TextureAtlasSprite from, TextureAtlasSprite to, int sheetX, int sheetY) {
|
||||
shouldShiftUV = true;
|
||||
uShift = to.getInterpolatedU(sheetX * 16f / to.getWidth()) - from.getMinU();
|
||||
vShift = to.getInterpolatedV(sheetY * 16f / to.getHeight()) - from.getMinV();
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer light(int packedLightCoords) {
|
||||
shouldLight = true;
|
||||
this.packedLightCoords = packedLightCoords;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer light(IVertexLighter lighter) {
|
||||
shouldLight = true;
|
||||
vertexLighter = lighter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer color(int color) {
|
||||
shouldColor = true;
|
||||
r = ((color >> 16) & 0xFF);
|
||||
g = ((color >> 8) & 0xFF);
|
||||
b = (color & 0xFF);
|
||||
a = 255;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected int vertexCount(ByteBuffer buffer) {
|
||||
return buffer.limit() / FORMAT_LENGTH;
|
||||
}
|
||||
|
||||
protected int getBufferPosition(int vertexIndex) {
|
||||
return vertexIndex * FORMAT_LENGTH;
|
||||
}
|
||||
|
||||
protected float getX(ByteBuffer buffer, int index) {
|
||||
return buffer.getFloat(getBufferPosition(index));
|
||||
}
|
||||
|
||||
protected float getY(ByteBuffer buffer, int index) {
|
||||
return buffer.getFloat(getBufferPosition(index) + 4);
|
||||
}
|
||||
|
||||
protected float getZ(ByteBuffer buffer, int index) {
|
||||
return buffer.getFloat(getBufferPosition(index) + 8);
|
||||
}
|
||||
|
||||
protected byte getR(ByteBuffer buffer, int index) {
|
||||
return buffer.get(getBufferPosition(index) + 12);
|
||||
}
|
||||
|
||||
protected byte getG(ByteBuffer buffer, int index) {
|
||||
return buffer.get(getBufferPosition(index) + 13);
|
||||
}
|
||||
|
||||
protected byte getB(ByteBuffer buffer, int index) {
|
||||
return buffer.get(getBufferPosition(index) + 14);
|
||||
}
|
||||
|
||||
protected byte getA(ByteBuffer buffer, int index) {
|
||||
return buffer.get(getBufferPosition(index) + 15);
|
||||
}
|
||||
|
||||
protected float getU(ByteBuffer buffer, int index) {
|
||||
return buffer.getFloat(getBufferPosition(index) + 16);
|
||||
}
|
||||
|
||||
protected float getV(ByteBuffer buffer, int index) {
|
||||
return buffer.getFloat(getBufferPosition(index) + 20);
|
||||
}
|
||||
|
||||
protected void putPos(ByteBuffer buffer, int index, float x, float y, float z) {
|
||||
int pos = getBufferPosition(index);
|
||||
buffer.putFloat(pos, x);
|
||||
buffer.putFloat(pos + 4, y);
|
||||
buffer.putFloat(pos + 8, z);
|
||||
}
|
||||
|
||||
protected void putUV(ByteBuffer buffer, int index, float u, float v) {
|
||||
int pos = getBufferPosition(index);
|
||||
buffer.putFloat(pos + 16, u);
|
||||
buffer.putFloat(pos + 20, v);
|
||||
}
|
||||
|
||||
protected void putLight(ByteBuffer buffer, int index, int packedLight) {
|
||||
buffer.putInt(getBufferPosition(index) + 24, packedLight);
|
||||
}
|
||||
|
||||
protected void putColor(ByteBuffer buffer, int index, byte r, byte g, byte b, byte a) {
|
||||
int bufferPosition = getBufferPosition(index);
|
||||
buffer.put(bufferPosition + 12, r);
|
||||
buffer.put(bufferPosition + 13, g);
|
||||
buffer.put(bufferPosition + 14, b);
|
||||
buffer.put(bufferPosition + 15, a);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
public class SuperByteBufferCache {
|
||||
|
||||
public static class Compartment<T> {
|
||||
}
|
||||
|
||||
public static final Compartment<BlockState> GENERIC_TILE = new Compartment<>();
|
||||
Map<Compartment<?>, Cache<Object, SuperByteBuffer>> cache;
|
||||
|
||||
public SuperByteBufferCache() {
|
||||
cache = new HashMap<>();
|
||||
registerCompartment(GENERIC_TILE);
|
||||
}
|
||||
|
||||
public SuperByteBuffer renderGenericBlockModel(BlockState toRender) {
|
||||
return getGeneric(toRender, () -> standardBlockRender(toRender));
|
||||
}
|
||||
|
||||
public SuperByteBuffer renderBlockState(Compartment<BlockState> compartment, BlockState toRender) {
|
||||
return get(compartment, toRender, () -> standardBlockRender(toRender));
|
||||
}
|
||||
|
||||
public SuperByteBuffer getGeneric(BlockState key, Supplier<SuperByteBuffer> supplier) {
|
||||
return get(GENERIC_TILE, key, supplier);
|
||||
}
|
||||
|
||||
public <T> SuperByteBuffer get(Compartment<T> compartment, T key, Supplier<SuperByteBuffer> supplier) {
|
||||
Cache<Object, SuperByteBuffer> compartmentCache = this.cache.get(compartment);
|
||||
try {
|
||||
return compartmentCache.get(key, supplier::get);
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void registerCompartment(Compartment<?> instance) {
|
||||
cache.put(instance, CacheBuilder.newBuilder().build());
|
||||
}
|
||||
|
||||
public void registerCompartment(Compartment<?> instance, long ticksTillExpired) {
|
||||
cache.put(instance,
|
||||
CacheBuilder.newBuilder().expireAfterAccess(ticksTillExpired * 50, TimeUnit.MILLISECONDS).build());
|
||||
}
|
||||
|
||||
private SuperByteBuffer standardBlockRender(BlockState renderedState) {
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
IBakedModel originalModel = dispatcher.getModelForState(renderedState);
|
||||
BufferBuilder builder = new BufferBuilder(0);
|
||||
Random random = new Random();
|
||||
|
||||
builder.setTranslation(0, 1, 0);
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
blockRenderer.renderModelFlat(Minecraft.getInstance().world, originalModel, renderedState, BlockPos.ZERO.down(),
|
||||
builder, true, random, 42, EmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
|
||||
return new SuperByteBuffer(builder.getByteBuffer());
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
cache.forEach((comp, cache) -> {
|
||||
cache.invalidateAll();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package com.simibubi.create.modules.contraptions;
|
||||
|
||||
import com.simibubi.create.foundation.block.CTModelTextureHandler;
|
||||
import com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.ContraptionRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltModelAnimator;
|
||||
|
||||
import net.minecraft.client.resources.ReloadListener;
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
|
||||
public class CachedBufferReloader extends ReloadListener<String> {
|
||||
|
||||
@Override
|
||||
protected String prepare(IResourceManager resourceManagerIn, IProfiler profilerIn) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(String splashList, IResourceManager resourceManagerIn, IProfiler profilerIn) {
|
||||
KineticTileEntityRenderer.invalidateCache();
|
||||
ContraptionRenderer.invalidateCache();
|
||||
MechanicalBearingTileEntityRenderer.invalidateCache();
|
||||
ColoredIndicatorRenderer.invalidateCache();
|
||||
CTModelTextureHandler.reloadUVs();
|
||||
BeltModelAnimator.invalidateCache();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,86 +1,38 @@
|
|||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment;
|
||||
import com.simibubi.create.modules.contraptions.KineticDebugger;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.model.animation.TileEntityRendererFast;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTileEntity> {
|
||||
|
||||
public static Map<BlockState, BufferManipulator> cachedBuffers;
|
||||
public static final Compartment<BlockState> KINETIC_TILE = new Compartment<>();
|
||||
public static boolean rainbowMode = false;
|
||||
|
||||
public static class BlockModelSpinner extends BufferManipulator {
|
||||
|
||||
public BlockModelSpinner(ByteBuffer original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(float xIn, float yIn, float zIn, float angle, Axis axis,
|
||||
int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
float cos = MathHelper.cos(angle);
|
||||
float sin = MathHelper.sin(angle);
|
||||
float x, y, z = 0;
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
x = getX(original, vertex) - .5f;
|
||||
y = getY(original, vertex) - .5f;
|
||||
z = getZ(original, vertex) - .5f;
|
||||
|
||||
putPos(mutable, vertex, rotateX(x, y, z, sin, cos, axis) + .5f + xIn,
|
||||
rotateY(x, y, z, sin, cos, axis) + .5f + yIn, rotateZ(x, y, z, sin, cos, axis) + .5f + zIn);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
}
|
||||
|
||||
public KineticTileEntityRenderer() {
|
||||
cachedBuffers = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
renderRotatingKineticBlock(te, getWorld(), getRenderedBlockState(te), x, y, z, buffer);
|
||||
}
|
||||
|
||||
final BlockState state = getRenderedBlockState(te);
|
||||
cacheIfMissing(state, getWorld(), BlockModelSpinner::new);
|
||||
|
||||
final BlockPos pos = te.getPos();
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
float angle = getAngleForTe(te, pos, axis);
|
||||
|
||||
renderFromCache(buffer, state, getWorld(), (float) x, (float) y, (float) z, pos, axis, angle);
|
||||
public static void renderRotatingKineticBlock(KineticTileEntity te, World world, BlockState renderedState, double x,
|
||||
double y, double z, BufferBuilder buffer) {
|
||||
SuperByteBuffer superByteBuffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, renderedState);
|
||||
buffer.putBulkData(standardKineticRotationTransform(superByteBuffer, te, world).translate(x, y, z).build());
|
||||
}
|
||||
|
||||
public static float getAngleForTe(KineticTileEntity te, final BlockPos pos, Axis axis) {
|
||||
|
@ -90,45 +42,26 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
|||
return angle;
|
||||
}
|
||||
|
||||
public static void renderFromCache(BufferBuilder buffer, BlockState state, World world, float x, float y,
|
||||
float z, BlockPos pos, Axis axis, float angle) {
|
||||
int packedLightmapCoords = state.getPackedLightmapCoords(world, pos);
|
||||
ByteBuffer transformed = ((BlockModelSpinner) getBuffer(state)).getTransformed(x, y, z, angle, axis,
|
||||
packedLightmapCoords);
|
||||
public static SuperByteBuffer standardKineticRotationTransform(SuperByteBuffer buffer, KineticTileEntity te,
|
||||
World world) {
|
||||
final BlockPos pos = te.getPos();
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
return kineticRotationTransform(buffer, te, axis, getAngleForTe(te, pos, axis), world);
|
||||
}
|
||||
|
||||
public static SuperByteBuffer kineticRotationTransform(SuperByteBuffer buffer, KineticTileEntity te, Axis axis,
|
||||
float angle, World world) {
|
||||
int packedLightmapCoords = te.getBlockState().getPackedLightmapCoords(world, te.getPos());
|
||||
buffer.light(packedLightmapCoords);
|
||||
buffer.rotateCentered(axis, angle);
|
||||
|
||||
if (KineticDebugger.isActive()) {
|
||||
rainbowMode = true;
|
||||
TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (tileEntity instanceof KineticTileEntity && ((KineticTileEntity) tileEntity).hasNetwork()) {
|
||||
int color = LogisticalActorTileEntity.colorFromUUID(((KineticTileEntity) tileEntity).getNetworkID());
|
||||
BufferManipulator.recolorBuffer(transformed, color);
|
||||
}
|
||||
if (te.hasNetwork())
|
||||
buffer.color(LogisticalActorTileEntity.colorFromUUID(te.getNetworkID()));
|
||||
}
|
||||
|
||||
buffer.putBulkData(transformed);
|
||||
}
|
||||
|
||||
public static BufferManipulator getBuffer(BlockState state) {
|
||||
return cachedBuffers.get(state);
|
||||
}
|
||||
|
||||
public static void cacheIfMissing(final BlockState state, World world,
|
||||
Function<ByteBuffer, BufferManipulator> factory) {
|
||||
if (!cachedBuffers.containsKey(state)) {
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
IBakedModel originalModel = dispatcher.getModelForState(state);
|
||||
BufferBuilder builder = new BufferBuilder(0);
|
||||
Random random = new Random();
|
||||
|
||||
builder.setTranslation(0, 1, 0);
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
blockRenderer.renderModelFlat(world, originalModel, state, BlockPos.ZERO.down(), builder, true, random, 42,
|
||||
EmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
|
||||
cachedBuffers.put(state, factory.apply(builder.getByteBuffer()));
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
protected static float getRotationOffsetForPosition(KineticTileEntity te, final BlockPos pos, final Axis axis) {
|
||||
|
@ -145,9 +78,4 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
|||
return te.getBlockState();
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
if (cachedBuffers != null)
|
||||
cachedBuffers.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.foundation.block.IRenderUtilityBlock;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.VoxelShapers;
|
||||
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
|
||||
|
@ -80,8 +80,8 @@ public class DrillBlock extends DirectionalKineticBlock
|
|||
|
||||
@Override
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
public ByteBuffer renderInConstruct(MovementContext context) {
|
||||
return DrillTileEntityRenderer.renderInConstruct(context);
|
||||
public SuperByteBuffer renderInContraption(MovementContext context) {
|
||||
return DrillTileEntityRenderer.renderInContraption(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,20 +2,17 @@ package com.simibubi.create.modules.contraptions.receivers;
|
|||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MovementContext;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.animation.Animation;
|
||||
|
||||
public class DrillTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
|
||||
|
@ -28,21 +25,16 @@ public class DrillTileEntityRenderer extends KineticTileEntityRenderer {
|
|||
return AllBlocks.DRILL_HEAD.get().getDefaultState().with(FACING, state.get(FACING));
|
||||
}
|
||||
|
||||
public static ByteBuffer renderInConstruct(MovementContext context) {
|
||||
World world = context.world;
|
||||
public static SuperByteBuffer renderInContraption(MovementContext context) {
|
||||
BlockState state = context.state;
|
||||
BlockPos pos = context.currentGridPos;
|
||||
|
||||
final BlockState renderedState = getRenderedBlockState(state);
|
||||
cacheIfMissing(renderedState, world, BlockModelSpinner::new);
|
||||
SuperByteBuffer buffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, getRenderedBlockState(state));
|
||||
|
||||
float speed = (float) (context.getMovementDirection() == state.get(FACING) ? context.getAnimationSpeed() : 0);
|
||||
Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state);
|
||||
float time = Animation.getWorldTime(Minecraft.getInstance().world,
|
||||
Minecraft.getInstance().getRenderPartialTicks());
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI);
|
||||
return ((BlockModelSpinner) getBuffer(renderedState)).getTransformed(0, 0, 0, angle, axis,
|
||||
world.getCombinedLight(pos, 0));
|
||||
|
||||
return buffer.rotateCentered(axis, angle);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.IRenderUtilityBlock;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
|
||||
|
||||
|
@ -74,8 +74,8 @@ public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBeha
|
|||
|
||||
@Override
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
public ByteBuffer renderInConstruct(MovementContext context) {
|
||||
return HarvesterTileEntityRenderer.renderInConstruct(context);
|
||||
public SuperByteBuffer renderInContraption(MovementContext context) {
|
||||
return HarvesterTileEntityRenderer.renderInContraption(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,99 +1,64 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import static com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer.KINETIC_TILE;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MovementContext;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.animation.Animation;
|
||||
|
||||
public class HarvesterTileEntityRenderer extends TileEntityRenderer<HarvesterTileEntity> {
|
||||
|
||||
protected static class HarvesterRenderer extends BufferManipulator {
|
||||
|
||||
public HarvesterRenderer(ByteBuffer original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(float xIn, float yIn, float zIn, float angle, Direction facing,
|
||||
int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
float cos = MathHelper.cos(angle);
|
||||
float sin = MathHelper.sin(angle);
|
||||
float x, y, z = 0;
|
||||
Axis axis = facing.rotateYCCW().getAxis();
|
||||
int axisDirection = -facing.getAxisDirection().getOffset();
|
||||
|
||||
float originOffset = 1 / 16f;
|
||||
float xOffset = axis == Axis.X ? 0 : originOffset * axisDirection;
|
||||
float zOffset = axis == Axis.Z ? 0 : originOffset * axisDirection;
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
x = getX(original, vertex) - .5f + xOffset;
|
||||
y = getY(original, vertex) - .5f + 2 * originOffset;
|
||||
z = getZ(original, vertex) - .5f + zOffset;
|
||||
|
||||
putPos(mutable, vertex, rotateX(x, y, z, sin, cos, axis) + .5f - xOffset + xIn,
|
||||
rotateY(x, y, z, sin, cos, axis) + .5f - 2 * originOffset + yIn,
|
||||
rotateZ(x, y, z, sin, cos, axis) + .5f - zOffset + zIn);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(HarvesterTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
SuperByteBuffer superBuffer = renderHead(getWorld(), te.getPos(), te.getBlockState(), 0);
|
||||
superBuffer.translate(x, y, z).renderInto(buffer);
|
||||
}
|
||||
|
||||
public static ByteBuffer renderInConstruct(MovementContext context) {
|
||||
World world = context.world;
|
||||
public static SuperByteBuffer renderInContraption(MovementContext context) {
|
||||
BlockState state = context.state;
|
||||
BlockPos pos = context.currentGridPos;
|
||||
Direction facing = context.getMovementDirection();
|
||||
|
||||
float speed = (float) (facing == state.get(HORIZONTAL_FACING)
|
||||
? context.getAnimationSpeed() * facing.getAxisDirection().getOffset()
|
||||
: 0);
|
||||
if (facing.getAxis() == Axis.X)
|
||||
speed = -speed;
|
||||
|
||||
float time = Animation.getWorldTime(Minecraft.getInstance().world,
|
||||
Minecraft.getInstance().getRenderPartialTicks());
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI);
|
||||
return getVertexData(world, state, pos, 0, 0, 0, angle);
|
||||
|
||||
return renderHead(context.world, BlockPos.ZERO, state, angle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(HarvesterTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
buffer.putBulkData(getVertexData(te.getWorld(), te.getBlockState(), te.getPos(), x, y, z, 0));
|
||||
}
|
||||
|
||||
public static ByteBuffer getVertexData(World world, BlockState state, BlockPos pos, double x, double y, double z,
|
||||
float angle) {
|
||||
if (!AllBlocks.HARVESTER.typeOf(state))
|
||||
return ByteBuffer.wrap(new byte[] {});
|
||||
public static SuperByteBuffer renderHead(World world, BlockPos pos, BlockState state, float angle) {
|
||||
BlockState renderedState = AllBlocks.HARVESTER_BLADE.get().getDefaultState().with(HORIZONTAL_FACING,
|
||||
state.get(HORIZONTAL_FACING));
|
||||
SuperByteBuffer buffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, renderedState);
|
||||
|
||||
KineticTileEntityRenderer.cacheIfMissing(renderedState, world, HarvesterRenderer::new);
|
||||
HarvesterRenderer renderer = (HarvesterRenderer) KineticTileEntityRenderer.getBuffer(renderedState);
|
||||
ByteBuffer byteBuffer = renderer.getTransformed((float) x, (float) y, (float) z, angle,
|
||||
state.get(HORIZONTAL_FACING), state.getPackedLightmapCoords(world, pos));
|
||||
return byteBuffer;
|
||||
int lightMapCoords = state.getPackedLightmapCoords(world, pos);
|
||||
Direction facing = state.get(HORIZONTAL_FACING);
|
||||
Axis axis = facing.rotateYCCW().getAxis();
|
||||
int axisDirection = -facing.getAxisDirection().getOffset();
|
||||
float originOffset = 1 / 16f;
|
||||
float xOffset = axis == Axis.X ? 0 : originOffset * axisDirection;
|
||||
float zOffset = axis == Axis.Z ? 0 : originOffset * axisDirection;
|
||||
|
||||
buffer.translate(xOffset, 2 * originOffset, zOffset);
|
||||
buffer.rotateCentered(axis, angle);
|
||||
buffer.translate(-xOffset, -2 * originOffset, -zOffset);
|
||||
|
||||
buffer.light(lightMapCoords);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,24 +66,23 @@ public class MechanicalMixerTileEntity extends KineticTileEntity {
|
|||
|
||||
public float getRenderedHeadOffset(float partialTicks) {
|
||||
int localTick = 0;
|
||||
float offset = 0;
|
||||
if (running) {
|
||||
if (runningTicks < 20) {
|
||||
localTick = runningTicks;
|
||||
float num = (localTick + partialTicks) / 20f;
|
||||
num = ((2 - MathHelper.cos((float) (num * Math.PI))) / 2);
|
||||
return num - .5f;
|
||||
}
|
||||
if (runningTicks <= 20) {
|
||||
return 1;
|
||||
}
|
||||
if (runningTicks > 20) {
|
||||
offset = num - .5f;
|
||||
} else if (runningTicks <= 20) {
|
||||
offset = 1;
|
||||
} else if (runningTicks > 20) {
|
||||
localTick = 40 - runningTicks;
|
||||
float num = (localTick - partialTicks) / 20f;
|
||||
num = ((2 - MathHelper.cos((float) (num * Math.PI))) / 2);
|
||||
return num - .5f;
|
||||
offset = num - .5f;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return offset + 7 / 16f;
|
||||
}
|
||||
|
||||
public float getRenderedHeadRotationSpeed(float partialTicks) {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.MechanicalPressTileEntityRenderer.HeadTranslator;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
|
@ -19,22 +20,23 @@ public class MechanicalMixerTileEntityRenderer extends KineticTileEntityRenderer
|
|||
int destroyStage, BufferBuilder buffer) {
|
||||
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
|
||||
final BlockState poleState = AllBlocks.MECHANICAL_MIXER_POLE.get().getDefaultState();
|
||||
final BlockState headState = AllBlocks.MECHANICAL_MIXER_HEAD.get().getDefaultState();
|
||||
cacheIfMissing(poleState, getWorld(), HeadTranslator::new);
|
||||
cacheIfMissing(headState, getWorld(), HeadTranslator::new);
|
||||
final BlockPos pos = te.getPos();
|
||||
MechanicalMixerTileEntity mixer = (MechanicalMixerTileEntity) te;
|
||||
BlockState poleState = AllBlocks.MECHANICAL_MIXER_POLE.get().getDefaultState();
|
||||
BlockState headState = AllBlocks.MECHANICAL_MIXER_HEAD.get().getDefaultState();
|
||||
BlockPos pos = te.getPos();
|
||||
|
||||
int packedLightmapCoords = poleState.getPackedLightmapCoords(getWorld(), pos);
|
||||
float speed = ((MechanicalMixerTileEntity) te).getRenderedHeadRotationSpeed(partialTicks);
|
||||
float renderedHeadOffset = ((MechanicalMixerTileEntity) te).getRenderedHeadOffset(partialTicks) + 7 / 16f;
|
||||
float renderedHeadOffset = mixer.getRenderedHeadOffset(partialTicks);
|
||||
float speed = mixer.getRenderedHeadRotationSpeed(partialTicks);
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
float angle = (float) (((time * speed * 2) % 360) / 180 * (float) Math.PI);
|
||||
|
||||
buffer.putBulkData(((HeadTranslator) cachedBuffers.get(poleState)).getTransformed((float) x, (float) y,
|
||||
(float) z, renderedHeadOffset, packedLightmapCoords));
|
||||
buffer.putBulkData(((HeadTranslator) cachedBuffers.get(headState)).getTransformedRotated((float) x, (float) y,
|
||||
(float) z, renderedHeadOffset, angle, packedLightmapCoords));
|
||||
SuperByteBuffer poleRender = CreateClient.bufferCache.renderGenericBlockModel(poleState);
|
||||
poleRender.translate(x, y - renderedHeadOffset, z).light(packedLightmapCoords).renderInto(buffer);
|
||||
|
||||
SuperByteBuffer headRender = CreateClient.bufferCache.renderGenericBlockModel(headState);
|
||||
headRender.rotateCentered(Axis.Y, angle).translate(x, y - renderedHeadOffset, z).light(packedLightmapCoords)
|
||||
.renderInto(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,89 +1,43 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class MechanicalPressTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
|
||||
public static class HeadTranslator extends BufferManipulator {
|
||||
|
||||
public HeadTranslator(ByteBuffer original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(float xIn, float yIn, float zIn, float pushDistance, int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
putPos(mutable, vertex, getX(original, vertex) + xIn, getY(original, vertex) + yIn - pushDistance,
|
||||
getZ(original, vertex) + zIn);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformedRotated(float xIn, float yIn, float zIn, float pushDistance, float angle,
|
||||
int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
float cos = MathHelper.cos(angle);
|
||||
float sin = MathHelper.sin(angle);
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
float x = getX(original, vertex) - .5f;
|
||||
float y = getY(original, vertex) + yIn - pushDistance;
|
||||
float z = getZ(original, vertex) - .5f;
|
||||
float x2 = x;
|
||||
|
||||
x = rotateX(x, y, z, sin, cos, Axis.Y) + .5f + xIn;
|
||||
z = rotateZ(x2, y, z, sin, cos, Axis.Y) + .5f + zIn;
|
||||
|
||||
putPos(mutable, vertex, x, y, z);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
|
||||
final BlockState state = getRenderedHeadBlockState(te);
|
||||
cacheIfMissing(state, getWorld(), HeadTranslator::new);
|
||||
|
||||
final BlockPos pos = te.getPos();
|
||||
|
||||
BlockState state = getRenderedHeadBlockState(te);
|
||||
BlockPos pos = te.getPos();
|
||||
int packedLightmapCoords = state.getPackedLightmapCoords(getWorld(), pos);
|
||||
buffer.putBulkData(((HeadTranslator) cachedBuffers.get(state)).getTransformed((float) x, (float) y, (float) z,
|
||||
((MechanicalPressTileEntity) te).getRenderedHeadOffset(partialTicks), packedLightmapCoords));
|
||||
float renderedHeadOffset = ((MechanicalPressTileEntity) te).getRenderedHeadOffset(partialTicks);
|
||||
|
||||
SuperByteBuffer headRender = CreateClient.bufferCache.renderGenericBlockModel(state);
|
||||
headRender.translate(x, y - renderedHeadOffset, z).light(packedLightmapCoords).renderInto(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||
return AllBlocks.SHAFT.get().getDefaultState().with(BlockStateProperties.AXIS,
|
||||
te.getBlockState().get(BlockStateProperties.HORIZONTAL_FACING).getAxis());
|
||||
te.getBlockState().get(HORIZONTAL_FACING).getAxis());
|
||||
}
|
||||
|
||||
protected BlockState getRenderedHeadBlockState(KineticTileEntity te) {
|
||||
return AllBlocks.MECHANICAL_PRESS_HEAD.get().getDefaultState().with(BlockStateProperties.HORIZONTAL_FACING,
|
||||
te.getBlockState().get(BlockStateProperties.HORIZONTAL_FACING));
|
||||
return AllBlocks.MECHANICAL_PRESS_HEAD.get().getDefaultState().with(HORIZONTAL_FACING,
|
||||
te.getBlockState().get(HORIZONTAL_FACING));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import com.simibubi.create.foundation.utility.TessellatorHelper;
|
|||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer.BlockModelSpinner;
|
||||
import com.simibubi.create.modules.logistics.block.FilteredTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -22,23 +21,27 @@ import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
|||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SawTileEntityRenderer extends TileEntityRenderer<SawTileEntity> {
|
||||
|
||||
FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
public SawTileEntityRenderer() {
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(SawTileEntity te, double x, double y, double z, float partialTicks, int destroyStage) {
|
||||
super.render(te, x, y, z, partialTicks, destroyStage);
|
||||
renderItems(te, x, y, z, partialTicks);
|
||||
FilteredTileEntityRenderer.render(te, x, y, z, partialTicks, destroyStage);
|
||||
renderShaft(te, x, y, z);
|
||||
}
|
||||
|
||||
protected void renderShaft(SawTileEntity te, double x, double y, double z) {
|
||||
TessellatorHelper.prepareFastRender();
|
||||
TessellatorHelper.begin(DefaultVertexFormats.BLOCK);
|
||||
KineticTileEntityRenderer.renderRotatingKineticBlock(te, getWorld(), getRenderedBlockState(te), x, y, z,
|
||||
Tessellator.getInstance().getBuffer());
|
||||
TessellatorHelper.draw();
|
||||
}
|
||||
|
||||
protected void renderItems(SawTileEntity te, double x, double y, double z, float partialTicks) {
|
||||
boolean processingMode = te.getBlockState().get(SawBlock.FACING) == Direction.UP;
|
||||
if (processingMode && !te.inventory.isEmpty()) {
|
||||
boolean alongZ = !te.getBlockState().get(SawBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||
|
@ -69,22 +72,6 @@ public class SawTileEntityRenderer extends TileEntityRenderer<SawTileEntity> {
|
|||
itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
// Filter
|
||||
filterRenderer.render(te, x, y, z, partialTicks, destroyStage);
|
||||
|
||||
// Kinetic renders
|
||||
final BlockState state = getRenderedBlockState(te);
|
||||
KineticTileEntityRenderer.cacheIfMissing(state, getWorld(), BlockModelSpinner::new);
|
||||
final BlockPos pos = te.getPos();
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
float angle = KineticTileEntityRenderer.getAngleForTe(te, pos, axis);
|
||||
|
||||
TessellatorHelper.prepareFastRender();
|
||||
TessellatorHelper.begin(DefaultVertexFormats.BLOCK);
|
||||
KineticTileEntityRenderer.renderFromCache(Tessellator.getInstance().getBuffer(), state, getWorld(), (float) x,
|
||||
(float) y, (float) z, pos, axis, angle);
|
||||
TessellatorHelper.draw();
|
||||
}
|
||||
|
||||
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers.constructs;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.PlacementSimulationWorld;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MovementContext;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -19,20 +18,24 @@ import net.minecraft.client.renderer.BlockRendererDispatcher;
|
|||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
public class ContraptionRenderer {
|
||||
|
||||
protected static Cache<Contraption, ContraptionVertexBuffer> cachedConstructs;
|
||||
public static final Compartment<Contraption> CONTRAPTION = new Compartment<>();
|
||||
protected static PlacementSimulationWorld renderWorld;
|
||||
|
||||
public static <T extends BufferManipulator> void cacheContraptionIfMissing(Contraption c) {
|
||||
if (cachedConstructs == null)
|
||||
cachedConstructs = CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.SECONDS).build();
|
||||
if (cachedConstructs.getIfPresent(c) != null)
|
||||
return;
|
||||
public static void render(World world, Contraption c, Consumer<SuperByteBuffer> transform, BufferBuilder buffer) {
|
||||
SuperByteBuffer contraptionBuffer = CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c));
|
||||
transform.accept(contraptionBuffer);
|
||||
buffer.putBulkData(contraptionBuffer.build());
|
||||
renderActors(world, c, transform, buffer);
|
||||
}
|
||||
|
||||
private static SuperByteBuffer renderContraption(Contraption c) {
|
||||
if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world)
|
||||
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world);
|
||||
|
||||
|
@ -43,10 +46,8 @@ public class ContraptionRenderer {
|
|||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
builder.setTranslation(0, 0, 0);
|
||||
|
||||
for (BlockInfo info : c.blocks.values()) {
|
||||
for (BlockInfo info : c.blocks.values())
|
||||
renderWorld.setBlockState(info.pos, info.state);
|
||||
}
|
||||
|
||||
for (BlockInfo info : c.blocks.values()) {
|
||||
IBakedModel originalModel = dispatcher.getModelForState(info.state);
|
||||
blockRenderer.renderModel(renderWorld, originalModel, info.state, info.pos, builder, true, random, 42,
|
||||
|
@ -55,14 +56,10 @@ public class ContraptionRenderer {
|
|||
|
||||
builder.finishDrawing();
|
||||
renderWorld.clear();
|
||||
cachedConstructs.put(c, new ContraptionVertexBuffer(builder.getByteBuffer()));
|
||||
return new SuperByteBuffer(builder.getByteBuffer());
|
||||
}
|
||||
|
||||
public static ContraptionVertexBuffer get(Contraption c) {
|
||||
return cachedConstructs.getIfPresent(c);
|
||||
}
|
||||
|
||||
public static void renderActors(World world, Contraption c, float xIn, float yIn, float zIn, float yaw, float pitch,
|
||||
private static void renderActors(World world, Contraption c, Consumer<SuperByteBuffer> transform,
|
||||
BufferBuilder buffer) {
|
||||
for (Pair<BlockInfo, MovementContext> actor : c.getActors()) {
|
||||
MovementContext context = actor.getRight();
|
||||
|
@ -73,30 +70,18 @@ public class ContraptionRenderer {
|
|||
|
||||
BlockInfo blockInfo = actor.getLeft();
|
||||
IHaveMovementBehavior block = (IHaveMovementBehavior) blockInfo.state.getBlock();
|
||||
ByteBuffer renderInConstruct = block.renderInConstruct(context);
|
||||
if (renderInConstruct == null)
|
||||
SuperByteBuffer render = block.renderInContraption(context);
|
||||
if (render == null)
|
||||
continue;
|
||||
|
||||
int posX = blockInfo.pos.getX();
|
||||
int posY = blockInfo.pos.getY();
|
||||
int posZ = blockInfo.pos.getZ();
|
||||
|
||||
float x = xIn + posX;
|
||||
float y = yIn + posY;
|
||||
float z = zIn + posZ;
|
||||
|
||||
float xOrigin = -posX + c.anchor.getX() + .5f;
|
||||
float yOrigin = -posY + c.anchor.getY() + .5f;
|
||||
float zOrigin = -posZ + c.anchor.getZ() + .5f;
|
||||
|
||||
buffer.putBulkData(BufferManipulator.remanipulateBuffer(renderInConstruct, x, y, z, xOrigin, yOrigin,
|
||||
zOrigin, yaw, pitch));
|
||||
render.translate(posX, posY, posZ);
|
||||
transform.accept(render);
|
||||
render.light((lx, ly, lz) -> world.getCombinedLight(new BlockPos(lx, ly, lz), 0)).renderInto(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
if (cachedConstructs != null)
|
||||
cachedConstructs.invalidateAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers.constructs;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ContraptionVertexBuffer extends BufferManipulator {
|
||||
|
||||
public ContraptionVertexBuffer(ByteBuffer original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
public ByteBuffer getTranslated(World world, float x, float y, float z, Vec3d offset) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
float xL = getX(original, vertex);
|
||||
float yL = getY(original, vertex);
|
||||
float zL = getZ(original, vertex);
|
||||
putPos(mutable, vertex, xL + x + (float) offset.x, yL + y + (float) offset.y, zL + z + (float) offset.z);
|
||||
BlockPos pos = new BlockPos(offset.x + xL, offset.y + yL, offset.z + zL);
|
||||
putLight(mutable, vertex, world.getCombinedLight(pos, 0));
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public ByteBuffer getTranslatedAndRotated(World world, float x, float y, float z, float yaw, float pitch,
|
||||
Vec3d offset, Vec3d rotationOffset) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
float cosYaw = MathHelper.cos(yaw);
|
||||
float sinYaw = MathHelper.sin(yaw);
|
||||
float cosPitch = MathHelper.cos(pitch);
|
||||
float sinPitch = MathHelper.sin(pitch);
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
float xL = getX(original, vertex) - (float) rotationOffset.x;
|
||||
float yL = getY(original, vertex) - (float) rotationOffset.y;
|
||||
float zL = getZ(original, vertex) - (float) rotationOffset.z;
|
||||
|
||||
float xL2 = rotateX(xL, yL, zL, sinPitch, cosPitch, Axis.X);
|
||||
float yL2 = rotateY(xL, yL, zL, sinPitch, cosPitch, Axis.X);
|
||||
float zL2 = rotateZ(xL, yL, zL, sinPitch, cosPitch, Axis.X);
|
||||
//
|
||||
xL = rotateX(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
|
||||
yL = rotateY(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
|
||||
zL = rotateZ(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y);
|
||||
|
||||
float xPos = xL + x + (float) (offset.x + rotationOffset.x);
|
||||
float yPos = yL + y + (float) (offset.y + rotationOffset.y);
|
||||
float zPos = zL + z + (float) (offset.z + rotationOffset.z);
|
||||
putPos(mutable, vertex, xPos, yPos, zPos);
|
||||
BlockPos pos = new BlockPos(xL + rotationOffset.x - .5f, yL + rotationOffset.y - .5f,
|
||||
zL + rotationOffset.z - .5f);
|
||||
putLight(mutable, vertex, world.getCombinedLight(pos, 15));
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers.constructs;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -49,7 +48,7 @@ public interface IHaveMovementBehavior {
|
|||
public Direction getMovementDirection() {
|
||||
return Direction.getFacingFromVector(motion.x, motion.y, motion.z);
|
||||
}
|
||||
|
||||
|
||||
public float getAnimationSpeed() {
|
||||
int modifier = moverType == MoverType.MINECART ? 1000 : 200;
|
||||
return ((int) (motion.length() * modifier)) / 100 * 100;
|
||||
|
@ -76,7 +75,7 @@ public interface IHaveMovementBehavior {
|
|||
}
|
||||
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
default ByteBuffer renderInConstruct(MovementContext context) {
|
||||
default SuperByteBuffer renderInContraption(MovementContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -42,5 +43,10 @@ public class MechanicalBearingBlock extends DirectionalKineticBlock
|
|||
protected boolean hasStaticPart() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Axis getRotationAxis(BlockState state) {
|
||||
return state.get(FACING).getAxis();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import org.lwjgl.opengl.GL11;
|
|||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.PlacementSimulationWorld;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
|
@ -23,7 +23,6 @@ import net.minecraft.client.renderer.model.IBakedModel;
|
|||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
@ -36,28 +35,17 @@ public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRender
|
|||
@Override
|
||||
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
|
||||
MechanicalBearingTileEntity bearingTe = (MechanicalBearingTileEntity) te;
|
||||
final Direction facing = te.getBlockState().get(BlockStateProperties.FACING);
|
||||
final BlockPos pos = te.getPos();
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
BlockState shaftState = AllBlocks.SHAFT_HALF.get().getDefaultState().with(BlockStateProperties.FACING,
|
||||
facing.getOpposite());
|
||||
BlockState capState = AllBlocks.MECHANICAL_BEARING_TOP.get().getDefaultState().with(BlockStateProperties.FACING,
|
||||
facing);
|
||||
|
||||
cacheIfMissing(shaftState, getWorld(), BlockModelSpinner::new);
|
||||
cacheIfMissing(capState, getWorld(), BlockModelSpinner::new);
|
||||
|
||||
float offset = getRotationOffsetForPosition(te, pos, facing.getAxis());
|
||||
float angle = (time * te.getSpeed()) % 360;
|
||||
|
||||
angle += offset;
|
||||
angle = angle / 180f * (float) Math.PI;
|
||||
SuperByteBuffer superBuffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, capState);
|
||||
float interpolatedAngle = bearingTe.getInterpolatedAngle(partialTicks);
|
||||
|
||||
renderFromCache(buffer, shaftState, getWorld(), (float) x, (float) y, (float) z, pos, facing.getAxis(), angle);
|
||||
renderFromCache(buffer, capState, getWorld(), (float) x, (float) y, (float) z, pos, facing.getAxis(),
|
||||
interpolatedAngle);
|
||||
kineticRotationTransform(superBuffer, bearingTe, facing.getAxis(), interpolatedAngle, getWorld());
|
||||
superBuffer.translate(x, y, z).renderInto(buffer);
|
||||
|
||||
if (!bearingTe.running)
|
||||
return;
|
||||
|
@ -108,8 +96,8 @@ public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRender
|
|||
|
||||
@Override
|
||||
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||
return AllBlocks.SHAFT.block.getDefaultState().with(BlockStateProperties.AXIS,
|
||||
((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState()));
|
||||
return AllBlocks.SHAFT_HALF.get().getDefaultState().with(BlockStateProperties.FACING,
|
||||
te.getBlockState().get(BlockStateProperties.FACING).getOpposite());
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
|
|
|
@ -17,27 +17,13 @@ public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRendere
|
|||
int destroyStage, BufferBuilder buffer) {
|
||||
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
|
||||
// SPECIAL RENDER
|
||||
MechanicalPistonTileEntity pistonTe = (MechanicalPistonTileEntity) te;
|
||||
|
||||
if (!pistonTe.running)
|
||||
return;
|
||||
|
||||
ContraptionRenderer.cacheContraptionIfMissing(pistonTe.movedContraption);
|
||||
renderConstructFromCache(pistonTe.movedContraption, pistonTe, x, y, z, partialTicks, buffer);
|
||||
|
||||
Vec3d offset = pistonTe.getConstructOffset(partialTicks).subtract(new Vec3d(pistonTe.getPos()));
|
||||
ContraptionRenderer.renderActors(pistonTe.getWorld(), pistonTe.movedContraption, (float) (x + offset.x),
|
||||
(float) (y + offset.y), (float) (z + offset.z), 0, 0, buffer);
|
||||
}
|
||||
|
||||
protected void renderConstructFromCache(Contraption c, MechanicalPistonTileEntity te, double x, double y, double z,
|
||||
float partialTicks, BufferBuilder buffer) {
|
||||
final Vec3d offset = te.getConstructOffset(partialTicks);
|
||||
float xPos = (float) (x - te.getPos().getX());
|
||||
float yPos = (float) (y - te.getPos().getY());
|
||||
float zPos = (float) (z - te.getPos().getZ());
|
||||
buffer.putBulkData(ContraptionRenderer.get(c).getTranslated(te.getWorld(), xPos, yPos, zPos, offset));
|
||||
ContraptionRenderer.render(getWorld(), pistonTe.movedContraption, (superBuffer) -> {
|
||||
superBuffer.translate(x + offset.x, y + offset.y, z + offset.z);
|
||||
}, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.mojang.blaze3d.platform.GlStateManager;
|
|||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.ContraptionRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.ContraptionVertexBuffer;
|
||||
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
|
@ -12,6 +11,7 @@ import net.minecraft.client.renderer.entity.EntityRendererManager;
|
|||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
@ -74,20 +74,19 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
|
|||
}
|
||||
}
|
||||
|
||||
ContraptionRenderer.cacheContraptionIfMissing(entity.contraption);
|
||||
BlockPos anchor = entity.contraption.getAnchor();
|
||||
Vec3d rotationOffset = VecHelper.getCenterOf(anchor);
|
||||
// Vec3d offset = VecHelper.getCenterOf(anchor).scale(-1);
|
||||
|
||||
TessellatorHelper.prepareFastRender();
|
||||
TessellatorHelper.begin(DefaultVertexFormats.BLOCK);
|
||||
ContraptionVertexBuffer buffer = ContraptionRenderer.get(entity.contraption);
|
||||
if (buffer != null) {
|
||||
BlockPos anchor = entity.contraption.getAnchor();
|
||||
Vec3d rotationOffset = VecHelper.getCenterOf(anchor);
|
||||
Vec3d offset = VecHelper.getCenterOf(anchor).scale(-1);
|
||||
Tessellator.getInstance().getBuffer().putBulkData(buffer.getTranslatedAndRotated(entity.world, (float) x,
|
||||
(float) y, (float) z, angleYaw, -anglePitch, offset, rotationOffset));
|
||||
ContraptionRenderer.renderActors(entity.world, entity.contraption, (float) (x + offset.x),
|
||||
(float) (y + offset.y), (float) (z + offset.z), angleYaw, -anglePitch,
|
||||
Tessellator.getInstance().getBuffer());
|
||||
}
|
||||
ContraptionRenderer.render(entity.world, entity.contraption, superByteBuffer -> {
|
||||
superByteBuffer.translate(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z);
|
||||
superByteBuffer.rotate(Axis.Y, angleYaw);
|
||||
superByteBuffer.rotate(Axis.Z, anglePitch);
|
||||
superByteBuffer.translate(x, y, z);
|
||||
|
||||
}, Tessellator.getInstance().getBuffer());
|
||||
TessellatorHelper.draw();
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
|
@ -28,8 +30,6 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
|
|||
continue;
|
||||
|
||||
BlockState state = defaultState.with(BlockStateProperties.FACING, direction);
|
||||
cacheIfMissing(state, getWorld(), BlockModelSpinner::new);
|
||||
|
||||
float offset = getRotationOffsetForPosition(te, pos, axis);
|
||||
float angle = (time * te.getSpeed()) % 360;
|
||||
|
||||
|
@ -45,7 +45,9 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
|
|||
angle += offset;
|
||||
angle = angle / 180f * (float) Math.PI;
|
||||
|
||||
renderFromCache(buffer, state, getWorld(), (float) x, (float) y, (float) z, pos, axis, angle);
|
||||
SuperByteBuffer superByteBuffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, state);
|
||||
kineticRotationTransform(superByteBuffer, te, axis, angle, getWorld());
|
||||
superByteBuffer.translate(x, y, z).renderInto(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
|
@ -18,22 +20,19 @@ public class SplitShaftTileEntityRenderer extends KineticTileEntityRenderer {
|
|||
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
|
||||
final BlockState defaultState = AllBlocks.SHAFT_HALF.get().getDefaultState();
|
||||
final BlockPos pos = te.getPos();
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
final BlockState defaultState = AllBlocks.SHAFT_HALF.get().getDefaultState();
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
final Axis axis = direction.getAxis();
|
||||
Axis axis = direction.getAxis();
|
||||
if (boxAxis != axis)
|
||||
continue;
|
||||
|
||||
BlockState state = defaultState.with(BlockStateProperties.FACING, direction);
|
||||
cacheIfMissing(state, getWorld(), BlockModelSpinner::new);
|
||||
|
||||
float offset = getRotationOffsetForPosition(te, pos, axis);
|
||||
float angle = (time * te.getSpeed()) % 360;
|
||||
float modifier = 1;
|
||||
|
||||
|
||||
if (te instanceof SplitShaftTileEntity)
|
||||
modifier = ((SplitShaftTileEntity) te).getRotationSpeedModifier(direction);
|
||||
|
||||
|
@ -41,7 +40,11 @@ public class SplitShaftTileEntityRenderer extends KineticTileEntityRenderer {
|
|||
angle += offset;
|
||||
angle = angle / 180f * (float) Math.PI;
|
||||
|
||||
renderFromCache(buffer, state, getWorld(), (float) x, (float) y, (float) z, pos, axis, angle);
|
||||
BlockState state = defaultState.with(BlockStateProperties.FACING, direction);
|
||||
SuperByteBuffer superByteBuffer = CreateClient.bufferCache.renderBlockState(KINETIC_TILE, state);
|
||||
kineticRotationTransform(superByteBuffer, te, axis, angle, getWorld());
|
||||
superByteBuffer.translate(x, y, z).renderInto(buffer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class BeltModelAnimator extends BufferManipulator {
|
||||
protected static TextureAtlasSprite beltTextures;
|
||||
protected static TextureAtlasSprite originalTexture;
|
||||
|
||||
public BeltModelAnimator(ByteBuffer template) {
|
||||
super(template);
|
||||
}
|
||||
|
||||
private void initSprites() {
|
||||
AtlasTexture textureMap = Minecraft.getInstance().getTextureMap();
|
||||
originalTexture = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt"));
|
||||
beltTextures = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt_animated"));
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(BeltTileEntity te, float x, float y, float z, int color) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
float textureOffsetX = 0;
|
||||
float textureOffsetY = 0;
|
||||
|
||||
if (te.getSpeed() != 0) {
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
Direction direction = te.getBlockState().get(BlockStateProperties.HORIZONTAL_FACING);
|
||||
if (direction == Direction.EAST || direction == Direction.NORTH)
|
||||
time = -time;
|
||||
int textureIndex = (int) ((te.getSpeed() * time / 8) % 16);
|
||||
if (textureIndex < 0)
|
||||
textureIndex += 16;
|
||||
|
||||
if (beltTextures == null)
|
||||
initSprites();
|
||||
textureOffsetX = beltTextures.getInterpolatedU((textureIndex % 4) * 4) - originalTexture.getMinU();
|
||||
textureOffsetY = beltTextures.getInterpolatedV((textureIndex / 4) * 4) - originalTexture.getMinV();
|
||||
}
|
||||
|
||||
final BlockState blockState = te.getBlockState();
|
||||
int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos());
|
||||
float texOffX = textureOffsetX;
|
||||
float texOffY = textureOffsetY;
|
||||
|
||||
boolean defaultColor = color == -1;
|
||||
int b = defaultColor ? 128 : color & 0xFF;
|
||||
int g = defaultColor ? 128 : (color >> 8) & 0xFF;
|
||||
int r = defaultColor ? 128 : (color >> 16) & 0xFF;
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
putPos(mutable, vertex, getX(original, vertex) + x, getY(original, vertex) + y, getZ(original, vertex) + z);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
|
||||
int bufferPosition = getBufferPosition(vertex);
|
||||
mutable.putFloat(bufferPosition + 16, original.getFloat(bufferPosition + 16) + texOffX);
|
||||
mutable.putFloat(bufferPosition + 20, original.getFloat(bufferPosition + 20) + texOffY);
|
||||
|
||||
byte lumByte = getR(original, vertex);
|
||||
float lum = (lumByte < 0 ? 255 + lumByte : lumByte) / 256f;
|
||||
|
||||
int r2 = (int) (r * lum);
|
||||
int g2 = (int) (g * lum);
|
||||
int b2 = (int) (b * lum);
|
||||
putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) 255);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
beltTextures = null;
|
||||
}
|
||||
}
|
|
@ -1,15 +1,21 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.block.SpriteShifter;
|
||||
import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.IndependentShadowRenderer;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer.BlockModelSpinner;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -23,7 +29,6 @@ import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
|||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
@ -31,6 +36,8 @@ import net.minecraft.util.math.Vec3i;
|
|||
@SuppressWarnings("deprecation")
|
||||
public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
|
||||
|
||||
private static SpriteShiftEntry animatedTexture;
|
||||
|
||||
@Override
|
||||
public void render(BeltTileEntity te, double x, double y, double z, float partialTicks, int destroyStage) {
|
||||
super.render(te, x, y, z, partialTicks, destroyStage);
|
||||
|
@ -40,6 +47,41 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
|
|||
renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, Tessellator.getInstance().getBuffer());
|
||||
TessellatorHelper.draw();
|
||||
|
||||
renderItems(te, x, y, z, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(BeltTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
if (te.hasPulley())
|
||||
KineticTileEntityRenderer.renderRotatingKineticBlock(te, getWorld(), getPulleyState(te), x, y, z, buffer);
|
||||
|
||||
BlockState renderedState = getBeltState(te);
|
||||
SuperByteBuffer beltBuffer = CreateClient.bufferCache.renderBlockState(KineticTileEntityRenderer.KINETIC_TILE,
|
||||
renderedState);
|
||||
|
||||
beltBuffer.color(te.color == -1 ? 0x808080 : te.color);
|
||||
|
||||
// UV shift
|
||||
if (te.getSpeed() != 0) {
|
||||
if (animatedTexture == null)
|
||||
animatedTexture = SpriteShifter.get("block/belt", "block/belt_animated");
|
||||
|
||||
float time = AnimationTickHolder.getRenderTick()
|
||||
* te.getBlockState().get(HORIZONTAL_FACING).getAxisDirection().getOffset();
|
||||
int textureIndex = (int) ((te.getSpeed() * time / 8) % 16);
|
||||
if (textureIndex < 0)
|
||||
textureIndex += 16;
|
||||
|
||||
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(),
|
||||
(textureIndex % 4) * 16, (textureIndex / 4) * 16);
|
||||
}
|
||||
|
||||
int packedLightmapCoords = te.getBlockState().getPackedLightmapCoords(getWorld(), te.getPos());
|
||||
beltBuffer.light(packedLightmapCoords).translate(x, y, z).renderInto(buffer);
|
||||
}
|
||||
|
||||
protected void renderItems(BeltTileEntity te, double x, double y, double z, float partialTicks) {
|
||||
if (te.isController()) {
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
|
@ -55,7 +97,7 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
|
|||
float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition);
|
||||
float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset);
|
||||
float verticalMovement = verticality;
|
||||
|
||||
|
||||
if (te.getSpeed() == 0) {
|
||||
offset = transported.beltPosition;
|
||||
sideOffset = transported.sideOffset;
|
||||
|
@ -127,33 +169,13 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(BeltTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
|
||||
if (te.hasPulley()) {
|
||||
final BlockState state = getRenderedBlockState(te);
|
||||
KineticTileEntityRenderer.cacheIfMissing(state, getWorld(), BlockModelSpinner::new);
|
||||
final BlockPos pos = te.getPos();
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
float angle = KineticTileEntityRenderer.getAngleForTe(te, pos, axis);
|
||||
KineticTileEntityRenderer.renderFromCache(buffer, state, getWorld(), (float) x, (float) y, (float) z, pos,
|
||||
axis, angle);
|
||||
}
|
||||
|
||||
KineticTileEntityRenderer.cacheIfMissing(te.getBlockState().with(BeltBlock.CASING, false), getWorld(),
|
||||
BeltModelAnimator::new);
|
||||
renderBeltFromCache(te, (float) x, (float) y, (float) z, buffer);
|
||||
}
|
||||
|
||||
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||
protected BlockState getPulleyState(KineticTileEntity te) {
|
||||
return AllBlocks.BELT_PULLEY.get().getDefaultState().with(BlockStateProperties.AXIS,
|
||||
((IRotate) AllBlocks.BELT.get()).getRotationAxis(te.getBlockState()));
|
||||
}
|
||||
|
||||
public void renderBeltFromCache(BeltTileEntity te, float x, float y, float z, BufferBuilder buffer) {
|
||||
buffer.putBulkData(((BeltModelAnimator) KineticTileEntityRenderer.cachedBuffers
|
||||
.get(te.getBlockState().with(BeltBlock.CASING, false))).getTransformed(te, x, y, z, te.color));
|
||||
protected BlockState getBeltState(KineticTileEntity te) {
|
||||
return te.getBlockState().with(BeltBlock.CASING, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
@SuppressWarnings("deprecation")
|
||||
public class FilteredTileEntityRenderer {
|
||||
|
||||
public <T extends TileEntity & IHaveFilter> void render(T tileEntityIn, double x, double y, double z,
|
||||
public static <T extends TileEntity & IHaveFilter> void render(T tileEntityIn, double x, double y, double z,
|
||||
float partialTicks, int destroyStage) {
|
||||
BlockState state = tileEntityIn.getBlockState();
|
||||
IBlockWithFilter block = (IBlockWithFilter) state.getBlock();
|
||||
|
@ -41,7 +41,8 @@ public class FilteredTileEntityRenderer {
|
|||
|
||||
}
|
||||
|
||||
private void renderFilterItem(ItemStack stack, Vec3d position, Direction facing, float scaleDiff, float angle) {
|
||||
private static void renderFilterItem(ItemStack stack, Vec3d position, Direction facing, float scaleDiff,
|
||||
float angle) {
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||
boolean vertical = facing.getAxis().isVertical();
|
||||
|
||||
|
|
|
@ -6,17 +6,11 @@ import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
|||
|
||||
public class BeltFunnelTileEntityRenderer extends TileEntityRenderer<BeltFunnelTileEntity> {
|
||||
|
||||
FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
public BeltFunnelTileEntityRenderer() {
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BeltFunnelTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
||||
int destroyStage) {
|
||||
super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
FilteredTileEntityRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,12 +8,6 @@ import net.minecraft.state.properties.BlockStateProperties;
|
|||
|
||||
public class EntityDetectorTileEntityRenderer extends TileEntityRenderer<EntityDetectorTileEntity> {
|
||||
|
||||
private FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
public EntityDetectorTileEntityRenderer() {
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(EntityDetectorTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
||||
int destroyStage) {
|
||||
|
@ -25,7 +19,7 @@ public class EntityDetectorTileEntityRenderer extends TileEntityRenderer<EntityD
|
|||
int k = i / 65536;
|
||||
GLX.glMultiTexCoord2f(GLX.GL_TEXTURE1, (float) j, (float) k);
|
||||
|
||||
filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
FilteredTileEntityRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,17 +6,11 @@ import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
|||
|
||||
public class ExtractorTileEntityRenderer extends TileEntityRenderer<ExtractorTileEntity> {
|
||||
|
||||
FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
public ExtractorTileEntityRenderer() {
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ExtractorTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
||||
int destroyStage) {
|
||||
super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
FilteredTileEntityRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -8,11 +8,9 @@ import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
|||
public class LinkedExtractorTileEntityRenderer extends TileEntityRenderer<LinkedExtractorTileEntity> {
|
||||
|
||||
LinkedTileEntityRenderer linkRenderer;
|
||||
FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
public LinkedExtractorTileEntityRenderer() {
|
||||
linkRenderer = new LinkedTileEntityRenderer();
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,7 +18,7 @@ public class LinkedExtractorTileEntityRenderer extends TileEntityRenderer<Linked
|
|||
int destroyStage) {
|
||||
super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
linkRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
FilteredTileEntityRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,28 +1,21 @@
|
|||
package com.simibubi.create.modules.logistics.block.diodes;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.ColoredOverlayTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.client.model.animation.TileEntityRendererFast;
|
||||
|
||||
public class FlexpeaterTileEntityRenderer extends TileEntityRendererFast<FlexpeaterTileEntity> {
|
||||
public class FlexpeaterTileEntityRenderer extends ColoredOverlayTileEntityRenderer<FlexpeaterTileEntity> {
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(FlexpeaterTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
BlockPos pos = te.getPos();
|
||||
protected int getColor(FlexpeaterTileEntity te, float partialTicks) {
|
||||
return ColorHelper.mixColors(0x2C0300, 0xCD0000, te.state / (float) te.maxState);
|
||||
}
|
||||
|
||||
BlockState renderedState = AllBlocks.FLEXPEATER_INDICATOR.get().getDefaultState();
|
||||
BlockState blockState = te.getBlockState();
|
||||
int color = ColorHelper.mixColors(0x2C0300, 0xCD0000, te.state / (float) te.maxState);
|
||||
int packedLightmapCoords = blockState.getPackedLightmapCoords(getWorld(), pos);
|
||||
|
||||
buffer.putBulkData(ColoredIndicatorRenderer.get(renderedState).getTransformed((float) x, (float) y, (float) z,
|
||||
color, packedLightmapCoords));
|
||||
@Override
|
||||
protected BlockState getOverlayState(FlexpeaterTileEntity te) {
|
||||
return AllBlocks.FLEXPEATER_INDICATOR.get().getDefaultState();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,25 +4,23 @@ import static com.simibubi.create.modules.logistics.management.base.LogisticalCo
|
|||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
||||
import com.simibubi.create.foundation.block.ColoredOverlayTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.client.model.animation.TileEntityRendererFast;
|
||||
|
||||
public class LogisticalControllerTileEntityRenderer extends TileEntityRendererFast<LogisticalActorTileEntity> {
|
||||
public class LogisticalControllerTileEntityRenderer
|
||||
extends ColoredOverlayTileEntityRenderer<LogisticalActorTileEntity> {
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(LogisticalActorTileEntity te, double x, double y, double z,
|
||||
float partialTicks, int destroyStage, BufferBuilder buffer) {
|
||||
BlockPos pos = te.getPos();
|
||||
BlockState blockState = te.getBlockState();
|
||||
BlockState renderedState = AllBlocks.LOGISTICAL_CONTROLLER_INDICATOR.get().getDefaultState()
|
||||
.with(FACING, blockState.get(FACING)).with(TYPE, blockState.get(TYPE));
|
||||
int packedLightmapCoords = blockState.getPackedLightmapCoords(getWorld(), pos);
|
||||
buffer.putBulkData(ColoredIndicatorRenderer.get(renderedState).getTransformed((float) x, (float) y, (float) z,
|
||||
te.getColor(), packedLightmapCoords));
|
||||
protected int getColor(LogisticalActorTileEntity te, float partialTicks) {
|
||||
return te.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState getOverlayState(LogisticalActorTileEntity te) {
|
||||
BlockState state = te.getBlockState();
|
||||
return AllBlocks.LOGISTICAL_CONTROLLER_INDICATOR.get().getDefaultState().with(FACING, state.get(FACING))
|
||||
.with(TYPE, state.get(TYPE));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
||||
import com.simibubi.create.foundation.block.ColoredOverlayTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -15,29 +14,32 @@ import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
|||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class LogisticiansTableTileEntityRenderer extends TileEntityRenderer<LogisticiansTableTileEntity> {
|
||||
|
||||
public void render(LogisticiansTableTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage) {
|
||||
renderColoredIndicator(te, x, y, z);
|
||||
renderBook(te, x, y, z);
|
||||
}
|
||||
|
||||
protected void renderColoredIndicator(LogisticiansTableTileEntity te, double x, double y, double z) {
|
||||
TessellatorHelper.prepareFastRender();
|
||||
BlockState renderedState = AllBlocks.LOGISTICIANS_TABLE_INDICATOR.get().getDefaultState();
|
||||
TessellatorHelper.begin(DefaultVertexFormats.BLOCK);
|
||||
SuperByteBuffer render = ColoredOverlayTileEntityRenderer.render(getWorld(), te.getPos(), renderedState,
|
||||
te.getColor());
|
||||
Tessellator.getInstance().getBuffer().putBulkData(render.translate(x, y, z).build());
|
||||
TessellatorHelper.draw();
|
||||
}
|
||||
|
||||
private static final ResourceLocation bookLocation = new ResourceLocation(
|
||||
"textures/entity/enchanting_table_book.png");
|
||||
private final BookModel bookModel = new BookModel();
|
||||
|
||||
public void render(LogisticiansTableTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
||||
int destroyStage) {
|
||||
TessellatorHelper.prepareFastRender();
|
||||
|
||||
BlockPos pos = tileEntityIn.getPos();
|
||||
BlockState blockState = tileEntityIn.getBlockState();
|
||||
BlockState renderedState = AllBlocks.LOGISTICIANS_TABLE_INDICATOR.get().getDefaultState();
|
||||
int packedLightmapCoords = blockState.getPackedLightmapCoords(getWorld(), pos);
|
||||
Tessellator.getInstance().getBuffer().begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
int color = tileEntityIn.getColor();
|
||||
Tessellator.getInstance().getBuffer().putBulkData(ColoredIndicatorRenderer.get(renderedState)
|
||||
.getTransformed((float) x, (float) y, (float) z, color, packedLightmapCoords));
|
||||
Tessellator.getInstance().draw();
|
||||
protected void renderBook(LogisticiansTableTileEntity te, double x, double y, double z) {
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
|
||||
BlockState blockstate = tileEntityIn.getBlockState();
|
||||
BlockState blockstate = te.getBlockState();
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translatef((float) x + 0.5F, (float) y + 1.0F + 0.0625F, (float) z + 0.5F);
|
||||
float f = blockstate.get(BlockStateProperties.HORIZONTAL_FACING).rotateY().getHorizontalAngle();
|
||||
|
@ -49,6 +51,5 @@ public class LogisticiansTableTileEntityRenderer extends TileEntityRenderer<Logi
|
|||
this.bookModel.render(0.0F, 0.1F, 0.9F, 1.2F, 0.0F, 0.0625F);
|
||||
GlStateManager.disableCull();
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue