smooth belts

This commit is contained in:
JozsefA 2021-01-05 01:59:32 -08:00
parent 7deb72baa1
commit 566a370e3b
8 changed files with 120 additions and 78 deletions

View file

@ -55,9 +55,9 @@ public class AllSpriteShifts {
CREATIVE_FLUID_TANK = getCT(CTType.CROSS, "creative_fluid_tank");
public static final SpriteShiftEntry
BELT = SpriteShifter.get("block/belt", "block/belt_animated"),
BELT_OFFSET = SpriteShifter.get("block/belt_offset", "block/belt_animated"),
BELT_DIAGONAL = SpriteShifter.get("block/belt_diagonal", "block/belt_diagonal_animated"),
BELT = SpriteShifter.get("block/belt", "block/belt_scroll"),
BELT_OFFSET = SpriteShifter.get("block/belt_offset", "block/belt_offset_scroll"),
BELT_DIAGONAL = SpriteShifter.get("block/belt_diagonal", "block/belt_diagonal_scroll"),
ANDESIDE_BELT_CASING = SpriteShifter.get("block/brass_casing_belt", "block/andesite_casing_belt"),
CRAFTER_THINGIES = SpriteShifter.get("block/crafter_thingies", "block/crafter_thingies");

View file

@ -66,17 +66,6 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
boolean sideways = beltSlope == BeltSlope.SIDEWAYS;
boolean alongX = facing.getAxis() == Axis.X;
MatrixStacker msr = MatrixStacker.of(ms);
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
float renderTick = AnimationTickHolder.getRenderTick();
ms.push();
msr.centre();
msr.rotateY(AngleHelper.horizontalAngle(facing) + (upward ? 180 : 0) + (sideways ? 270 : 0));
msr.rotateZ(sideways ? 90 : 0);
msr.rotateX(!diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0);
msr.unCentre();
if (downward || beltSlope == BeltSlope.VERTICAL && axisDirection == AxisDirection.POSITIVE) {
boolean b = start;
start = end;
@ -98,34 +87,29 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
SpriteShiftEntry spriteShift =
diagonal ? AllSpriteShifts.BELT_DIAGONAL : bottom ? AllSpriteShifts.BELT_OFFSET : AllSpriteShifts.BELT;
int cycleLength = diagonal ? 12 : 16;
int cycleOffset = bottom ? 8 : 0;
// UV shift
beltBuffer.setupInstance(data -> {
float speed = te.getSpeed();
if (diagonal && (downward ^ alongX) || !sideways && !diagonal && alongX
|| sideways && axisDirection == AxisDirection.NEGATIVE)
speed = -speed;
Matrix4f m = new Matrix4f();
m.loadIdentity();
m.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(AngleHelper.horizontalAngle(facing) + (upward ? 180 : 0) + (sideways ? 270 : 0)));
m.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(sideways ? 90 : 0));
m.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(!diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0));
float horizontalAngle = facing.getHorizontalAngle();
data.setPosition(te.getPos())
.setModel(m)
.setRotation(
!diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0,
horizontalAngle + (upward ? 180 : 0) + (sideways ? 270 : 0),
sideways ? 90 : 0
)
.setPackedLight(light)
.setRotationalSpeed(speed);
.setRotationalSpeed(speed)
.setScrollTexture(spriteShift)
.setScrollMult(diagonal ? 3f / 8f : 0.5f);
});
// Diagonal belt do not have a separate bottom model
if (diagonal)
break;
}
ms.pop();
if (te.hasPulley()) {
// TODO 1.15 find a way to cache this model matrix computation
@ -134,7 +118,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
.rotateY();
if (sideways)
dir = Direction.UP;
msr = MatrixStacker.of(modelTransform);
MatrixStacker msr = MatrixStacker.of(modelTransform);
msr.centre();
if (dir.getAxis() == Axis.X)
msr.rotateY(90);
@ -143,9 +127,9 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
msr.rotateX(90);
msr.unCentre();
RotatingBuffer superBuffer = CreateClient.kineticRenderer
RotatingBuffer rotatingBuffer = CreateClient.kineticRenderer
.renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform);
KineticTileEntityRenderer.renderRotatingBuffer(te, superBuffer, light);
KineticTileEntityRenderer.renderRotatingBuffer(te, rotatingBuffer, light);
}
renderItems(te, partialTicks, ms, buffer, light, overlay);

View file

@ -1,10 +1,11 @@
package com.simibubi.create.foundation.utility.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.GL11;
@ -34,7 +35,7 @@ public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
protected void finishBufferingInternal() {
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
int intSize = VertexFormatElement.Type.INT.getSize();
int stride = floatSize * 22;
int stride = floatSize * 16;
int instanceSize = instanceCount * stride;
@ -51,16 +52,21 @@ public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
// render position
GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, stride, 0);
// model matrix
for (int i = 0; i < 4; i++) {
GL20.glVertexAttribPointer(4 + i, 4, GL11.GL_FLOAT, false, stride, floatSize * (4 * i + 3));
}
// render rotation
GL20.glVertexAttribPointer(4, 3, GL11.GL_FLOAT, false, stride, floatSize * 3L);
// light map
GL20.glVertexAttribPointer(8, 2, GL11.GL_FLOAT, false, stride, floatSize * 16L);
GL20.glVertexAttribPointer(5, 2, GL11.GL_FLOAT, false, stride, floatSize * 6L);
// rotational speed and offset
GL20.glVertexAttribPointer(9, 1, GL11.GL_FLOAT, false, stride, floatSize * 18L);
// speed
GL20.glVertexAttribPointer(6, 1, GL11.GL_FLOAT, false, stride, floatSize * 8L);
// uv data
GL20.glVertexAttribPointer(7, 2, GL11.GL_FLOAT, false, stride, floatSize * 9L);
GL20.glVertexAttribPointer(8, 4, GL11.GL_FLOAT, false, stride, floatSize * 11L);
GL20.glVertexAttribPointer(9, 1, GL11.GL_FLOAT, false, stride, floatSize * 15L);
for (int i = 3; i <= numAttributes(); i++) {
GL40.glVertexAttribDivisor(i, 1);
@ -74,9 +80,18 @@ public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
private float x;
private float y;
private float z;
private Matrix4f model;
private float rotX;
private float rotY;
private float rotZ;
private int packedLight;
private float rotationalSpeed;
private float sourceU;
private float sourceV;
private float minU;
private float minV;
private float maxU;
private float maxV;
private float scrollMult;
public BeltData setPosition(BlockPos pos) {
this.x = pos.getX();
@ -85,8 +100,10 @@ public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
return this;
}
public BeltData setModel(Matrix4f model) {
this.model = model;
public BeltData setRotation(float rotX, float rotY, float rotZ) {
this.rotX = rotX;
this.rotY = rotY;
this.rotZ = rotZ;
return this;
}
@ -100,6 +117,25 @@ public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
return this;
}
public BeltData setScrollTexture(SpriteShiftEntry spriteShift) {
TextureAtlasSprite source = spriteShift.getOriginal();
TextureAtlasSprite target = spriteShift.getTarget();
this.sourceU = source.getMinU();
this.sourceV = source.getMinV();
this.minU = target.getMinU();
this.minV = target.getMinV();
this.maxU = target.getMaxU();
this.maxV = target.getMaxV();
return this;
}
public BeltData setScrollMult(float scrollMult) {
this.scrollMult = scrollMult;
return this;
}
void buffer(ByteBuffer buf) {
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF;
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF;
@ -108,14 +144,22 @@ public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
buf.putFloat(y);
buf.putFloat(z);
InstancedBuffer.MATRIX_BUF.rewind();
model.write(InstancedBuffer.MATRIX_BUF.asFloatBuffer());
InstancedBuffer.MATRIX_BUF.rewind();
buf.putFloat(rotX);
buf.putFloat(rotY);
buf.putFloat(rotZ);
buf.put(InstancedBuffer.MATRIX_BUF);
buf.putFloat(blockLightCoordinates);
buf.putFloat(skyLightCoordinates);
buf.putFloat(rotationalSpeed);
buf.putFloat(sourceU);
buf.putFloat(sourceV);
buf.putFloat(minU);
buf.putFloat(minV);
buf.putFloat(maxU);
buf.putFloat(maxV);
buf.putFloat(scrollMult);
}
}
}

View file

@ -50,17 +50,17 @@ public class FastKineticRenderer {
}
public void tick() {
for (Cache<Object, RotatingBuffer> cache : rotating.values()) {
for (RotatingBuffer renderer : cache.asMap().values()) {
renderer.clearInstanceData();
}
}
for (Cache<Object, BeltBuffer> cache : belts.values()) {
for (BeltBuffer renderer : cache.asMap().values()) {
renderer.clearInstanceData();
}
}
// for (Cache<Object, RotatingBuffer> cache : rotating.values()) {
// for (RotatingBuffer renderer : cache.asMap().values()) {
// renderer.clearInstanceData();
// }
// }
//
// for (Cache<Object, BeltBuffer> cache : belts.values()) {
// for (BeltBuffer renderer : cache.asMap().values()) {
// renderer.clearInstanceData();
// }
// }
}
public void enqueue(Runnable run) {
@ -219,5 +219,10 @@ public class FastKineticRenderer {
cache.asMap().values().forEach(InstancedBuffer::invalidate);
cache.invalidateAll();
});
belts.values().forEach(cache -> {
cache.asMap().values().forEach(InstancedBuffer::invalidate);
cache.invalidateAll();
});
}
}

View file

@ -15,8 +15,6 @@ import java.util.function.Consumer;
public abstract class InstancedBuffer<T> extends TemplateBuffer {
protected static ByteBuffer MATRIX_BUF = GLAllocation.createDirectByteBuffer(16 << 2);
protected int vao, ebo, invariantVBO, instanceVBO, instanceCount;
protected final ArrayList<T> data = new ArrayList<>();
@ -112,11 +110,6 @@ public abstract class InstancedBuffer<T> extends TemplateBuffer {
});
}
protected void addData(T instance) {
data.add(instance);
instanceCount++;
}
protected abstract T newInstance();
protected abstract int numAttributes();
@ -127,7 +120,8 @@ public abstract class InstancedBuffer<T> extends TemplateBuffer {
T instanceData = newInstance();
setup.accept(instanceData);
addData(instanceData);
data.add(instanceData);
instanceCount++;
}
public void render() {

View file

@ -6,9 +6,12 @@ layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec3 instancePos;
layout (location = 4) in mat4 model;
layout (location = 8) in vec2 light;
layout (location = 9) in float speed;
layout (location = 4) in vec3 rotationDegrees;
layout (location = 5) in vec2 light;
layout (location = 6) in float speed;
layout (location = 7) in vec2 sourceUV;
layout (location = 8) in vec4 scrollTexture;
layout (location = 9) in float scrollMult;
out vec2 TexCoords;
out vec2 Light;
@ -18,18 +21,30 @@ uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
mat4 rotate(vec3 axis, float angle)
{
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
void main() {
// float textureIndex = fract((speed * time / 36 + cycle[1]) / cycle[0]) * cycle[0];
// if (textureIndex < 0) {
// textureIndex += cycle[0];
// }
//
// vec2 scrollPos = vec2(fract(textureIndex / 4), floor(textureIndex / 16));
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.,
0., 0., 0., 1.);
}
vec4 renderPos = model * vec4(aPos - vec3(0.5), 1f);
void main()
{
vec3 rot = fract(rotationDegrees / 360.) * PI * 2.;
vec4 renderPos = rotate(vec3(1, 0, 0), rot.x) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(0, 1, 0), rot.y) * vec4(aPos - vec3(0.5), 1f);
renderPos += vec4(instancePos + vec3(0.5), 0);
TexCoords = aTexCoords;
float scrollSize = scrollTexture.w - scrollTexture.y;
float scroll = fract(speed * time / (36. * 16.)) * scrollSize * scrollMult;
Light = light;
TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll);
gl_Position = projection * view * renderPos;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B