mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 07:56:26 +01:00
Instanced Minecarts
- Rotations in PartBuilder - BlockModels are always UNLIT_MODEL format
This commit is contained in:
parent
68ca281ee8
commit
86dbed66af
5 changed files with 255 additions and 33 deletions
|
@ -4,7 +4,6 @@ import java.util.function.Supplier;
|
|||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.core.PartialModel;
|
||||
import com.jozufozu.flywheel.core.model.BlockModel;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
|
@ -26,7 +25,7 @@ public interface InstanceMaterial<D extends InstanceData> {
|
|||
Instancer<D> model(Object key, Supplier<IModel> modelSupplier);
|
||||
|
||||
default Instancer<D> getModel(PartialModel partial, BlockState referenceState) {
|
||||
return model(partial, () -> new BlockModel(Formats.UNLIT_MODEL, partial.get(), referenceState));
|
||||
return model(partial, () -> new BlockModel(partial.get(), referenceState));
|
||||
}
|
||||
|
||||
default Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir) {
|
||||
|
@ -34,10 +33,10 @@ public interface InstanceMaterial<D extends InstanceData> {
|
|||
}
|
||||
|
||||
default Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
|
||||
return model(Pair.of(dir, partial), () -> new BlockModel(Formats.UNLIT_MODEL, partial.get(), referenceState, modelTransform.get()));
|
||||
return model(Pair.of(dir, partial), () -> new BlockModel(partial.get(), referenceState, modelTransform.get()));
|
||||
}
|
||||
|
||||
default Instancer<D> getModel(BlockState toRender) {
|
||||
return model(toRender, () -> new BlockModel(Formats.UNLIT_MODEL, toRender));
|
||||
return model(toRender, () -> new BlockModel(toRender));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@ import org.lwjgl.opengl.GL11;
|
|||
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.backend.model.ElementBuffer;
|
||||
import com.jozufozu.flywheel.core.QuadConverter;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.util.BufferBuilderReader;
|
||||
import com.jozufozu.flywheel.util.VirtualEmptyModelData;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
@ -31,26 +30,23 @@ public class BlockModel implements IModel {
|
|||
|
||||
private final BufferBuilderReader reader;
|
||||
|
||||
private final VertexFormat modelFormat;
|
||||
|
||||
public BlockModel(VertexFormat modelFormat, BlockState state) {
|
||||
this(modelFormat, Minecraft.getInstance()
|
||||
public BlockModel(BlockState state) {
|
||||
this(Minecraft.getInstance()
|
||||
.getBlockRenderer()
|
||||
.getBlockModel(state), state);
|
||||
}
|
||||
|
||||
public BlockModel(VertexFormat modelFormat, IBakedModel model, BlockState referenceState) {
|
||||
this(modelFormat, model, referenceState, IDENTITY);
|
||||
public BlockModel(IBakedModel model, BlockState referenceState) {
|
||||
this(model, referenceState, IDENTITY);
|
||||
}
|
||||
|
||||
public BlockModel(VertexFormat modelFormat, IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||
this.modelFormat = modelFormat;
|
||||
public BlockModel(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||
reader = new BufferBuilderReader(getBufferBuilder(model, referenceState, ms));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexFormat format() {
|
||||
return modelFormat;
|
||||
return Formats.UNLIT_MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,6 +11,8 @@ import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
|||
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.vector.Matrix3f;
|
||||
import net.minecraft.util.math.vector.Quaternion;
|
||||
import net.minecraft.util.math.vector.Vector3f;
|
||||
|
||||
public class PartBuilder {
|
||||
|
@ -62,6 +64,11 @@ public class PartBuilder {
|
|||
|
||||
boolean invertYZ;
|
||||
|
||||
boolean useRotation;
|
||||
float rotationX;
|
||||
float rotationY;
|
||||
float rotationZ;
|
||||
|
||||
final PartBuilder partBuilder;
|
||||
|
||||
CuboidBuilder(PartBuilder partBuilder) {
|
||||
|
@ -96,6 +103,36 @@ public class PartBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public CuboidBuilder shift(float x, float y, float z) {
|
||||
posX1 = posX1 - x;
|
||||
posY1 = posY1 - y;
|
||||
posZ1 = posZ1 - z;
|
||||
posX2 = posX2 - x;
|
||||
posY2 = posY2 - y;
|
||||
posZ2 = posZ2 - z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CuboidBuilder rotate(float x, float y, float z) {
|
||||
useRotation = true;
|
||||
this.rotationX = x;
|
||||
this.rotationY = y;
|
||||
this.rotationZ = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CuboidBuilder rotateX(float x) {
|
||||
useRotation = true;
|
||||
this.rotationX = x;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CuboidBuilder rotateY(float y) {
|
||||
useRotation = true;
|
||||
this.rotationY = y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CuboidBuilder sprite(TextureAtlasSprite sprite) {
|
||||
this.sprite = sprite;
|
||||
return this;
|
||||
|
@ -130,6 +167,7 @@ public class PartBuilder {
|
|||
float posY2 = this.posY2 / 16f;
|
||||
float posZ2 = this.posZ2 / 16f;
|
||||
|
||||
|
||||
Vector3f lll = new Vector3f(posX1, posY1, posZ1);
|
||||
Vector3f hll = new Vector3f(posX2, posY1, posZ1);
|
||||
Vector3f hhl = new Vector3f(posX2, posY2, posZ1);
|
||||
|
@ -138,6 +176,32 @@ public class PartBuilder {
|
|||
Vector3f hlh = new Vector3f(posX2, posY1, posZ2);
|
||||
Vector3f hhh = new Vector3f(posX2, posY2, posZ2);
|
||||
Vector3f lhh = new Vector3f(posX1, posY2, posZ2);
|
||||
|
||||
Vector3f down = Direction.DOWN.step();
|
||||
Vector3f up = Direction.UP.step();
|
||||
Vector3f west = Direction.WEST.step();
|
||||
Vector3f north = Direction.NORTH.step();
|
||||
Vector3f east = Direction.EAST.step();
|
||||
Vector3f south = Direction.SOUTH.step();
|
||||
|
||||
if (useRotation) {
|
||||
Matrix3f matrix3f = new Matrix3f(new Quaternion(rotationX, rotationY, rotationZ, false));
|
||||
lll.transform(matrix3f);
|
||||
hll.transform(matrix3f);
|
||||
hhl.transform(matrix3f);
|
||||
lhl.transform(matrix3f);
|
||||
llh.transform(matrix3f);
|
||||
hlh.transform(matrix3f);
|
||||
hhh.transform(matrix3f);
|
||||
lhh.transform(matrix3f);
|
||||
down.transform(matrix3f);
|
||||
up.transform(matrix3f);
|
||||
west.transform(matrix3f);
|
||||
north.transform(matrix3f);
|
||||
east.transform(matrix3f);
|
||||
south.transform(matrix3f);
|
||||
}
|
||||
|
||||
float f4 = getU((float)textureOffsetU);
|
||||
float f5 = getU((float)textureOffsetU + sizeZ);
|
||||
float f6 = getU((float)textureOffsetU + sizeZ + sizeX);
|
||||
|
@ -149,27 +213,24 @@ public class PartBuilder {
|
|||
float f12 = getV((float)textureOffsetV + sizeZ + sizeY);
|
||||
|
||||
if (invertYZ) {
|
||||
quad(buffer, new Vector3f[]{hlh, llh, lll, hll}, f6, f11, f7, f10, Direction.DOWN);
|
||||
quad(buffer, new Vector3f[]{hhl, lhl, lhh, hhh}, f5, f10, f6, f11, Direction.UP);
|
||||
quad(buffer, new Vector3f[]{lll, llh, lhh, lhl}, f5, f12, f4, f11, Direction.WEST);
|
||||
quad(buffer, new Vector3f[]{hll, lll, lhl, hhl}, f9, f12, f8, f11, Direction.NORTH);
|
||||
quad(buffer, new Vector3f[]{hlh, hll, hhl, hhh}, f8, f12, f6, f11, Direction.EAST);
|
||||
quad(buffer, new Vector3f[]{llh, hlh, hhh, lhh}, f6, f12, f5, f11, Direction.SOUTH);
|
||||
quad(buffer, new Vector3f[]{hlh, llh, lll, hll}, f6, f11, f7, f10, down);
|
||||
quad(buffer, new Vector3f[]{hhl, lhl, lhh, hhh}, f5, f10, f6, f11, up);
|
||||
quad(buffer, new Vector3f[]{lll, llh, lhh, lhl}, f5, f12, f4, f11, west);
|
||||
quad(buffer, new Vector3f[]{hll, lll, lhl, hhl}, f9, f12, f8, f11, north);
|
||||
quad(buffer, new Vector3f[]{hlh, hll, hhl, hhh}, f8, f12, f6, f11, east);
|
||||
quad(buffer, new Vector3f[]{llh, hlh, hhh, lhh}, f6, f12, f5, f11, south);
|
||||
} else {
|
||||
quad(buffer, new Vector3f[]{hlh, llh, lll, hll}, f5, f10, f6, f11, Direction.DOWN);
|
||||
quad(buffer, new Vector3f[]{hhl, lhl, lhh, hhh}, f6, f11, f7, f10, Direction.UP);
|
||||
quad(buffer, new Vector3f[]{lll, llh, lhh, lhl}, f4, f11, f5, f12, Direction.WEST);
|
||||
quad(buffer, new Vector3f[]{hll, lll, lhl, hhl}, f5, f11, f6, f12, Direction.NORTH);
|
||||
quad(buffer, new Vector3f[]{hlh, hll, hhl, hhh}, f6, f11, f8, f12, Direction.EAST);
|
||||
quad(buffer, new Vector3f[]{llh, hlh, hhh, lhh}, f8, f11, f9, f12, Direction.SOUTH);
|
||||
quad(buffer, new Vector3f[]{hlh, llh, lll, hll}, f5, f10, f6, f11, down);
|
||||
quad(buffer, new Vector3f[]{hhl, lhl, lhh, hhh}, f6, f11, f7, f10, up);
|
||||
quad(buffer, new Vector3f[]{lll, llh, lhh, lhl}, f4, f11, f5, f12, west);
|
||||
quad(buffer, new Vector3f[]{hll, lll, lhl, hhl}, f5, f11, f6, f12, north);
|
||||
quad(buffer, new Vector3f[]{hlh, hll, hhl, hhh}, f6, f11, f8, f12, east);
|
||||
quad(buffer, new Vector3f[]{llh, hlh, hhh, lhh}, f8, f11, f9, f12, south);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void quad(VecBuffer buffer, Vector3f[] vertices, float minU, float minV, float maxU, float maxV, Direction dir) {
|
||||
|
||||
Vector3f normal = dir.step();
|
||||
|
||||
public void quad(VecBuffer buffer, Vector3f[] vertices, float minU, float minV, float maxU, float maxV, Vector3f normal) {
|
||||
buffer.putVec3(vertices[0].x(), vertices[0].y(), vertices[0].z()).putVec3(nb(normal.x()), nb(normal.y()), nb(normal.z())).putVec2(maxU, minV);
|
||||
buffer.putVec3(vertices[1].x(), vertices[1].y(), vertices[1].z()).putVec3(nb(normal.x()), nb(normal.y()), nb(normal.z())).putVec2(minU, minV);
|
||||
buffer.putVec3(vertices[2].x(), vertices[2].y(), vertices[2].z()).putVec3(nb(normal.x()), nb(normal.y()), nb(normal.z())).putVec2(minU, maxV);
|
||||
|
@ -181,14 +242,14 @@ public class PartBuilder {
|
|||
if (sprite != null)
|
||||
return sprite.getU(u * 16 / partBuilder.sizeU);
|
||||
else
|
||||
return u;
|
||||
return u / partBuilder.sizeU;
|
||||
}
|
||||
|
||||
public float getV(float v) {
|
||||
if (sprite != null)
|
||||
return sprite.getV(v * 16 / partBuilder.sizeV);
|
||||
else
|
||||
return v;
|
||||
return v / partBuilder.sizeV;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
package com.jozufozu.flywheel.vanilla;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||
import com.jozufozu.flywheel.backend.state.TextureRenderState;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.materials.ModelData;
|
||||
import com.jozufozu.flywheel.core.model.BlockModel;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
import com.jozufozu.flywheel.core.model.ModelPart;
|
||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
|
||||
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.math.vector.Vector3f;
|
||||
|
||||
public class MinecartInstance<T extends AbstractMinecartEntity> extends EntityInstance<T> implements IDynamicInstance {
|
||||
|
||||
private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png");
|
||||
|
||||
MatrixTransformStack stack = new MatrixTransformStack();
|
||||
|
||||
private final ModelData body;
|
||||
private final ModelData contents;
|
||||
|
||||
public MinecartInstance(MaterialManager materialManager, T entity) {
|
||||
super(materialManager, entity);
|
||||
|
||||
contents = getContents();
|
||||
body = getBody();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame() {
|
||||
stack.setIdentity();
|
||||
float pt = AnimationTickHolder.getPartialTicks();
|
||||
|
||||
stack.translate(
|
||||
MathHelper.lerp(pt, entity.xOld, entity.getX()),
|
||||
MathHelper.lerp(pt, entity.yOld, entity.getY()),
|
||||
MathHelper.lerp(pt, entity.zOld, entity.getZ())
|
||||
);
|
||||
|
||||
|
||||
float yaw = MathHelper.lerp(pt, entity.yRotO, entity.yRot);
|
||||
|
||||
long i = (long)entity.getId() * 493286711L;
|
||||
i = i * i * 4392167121L + i * 98761L;
|
||||
float f = (((float)(i >> 16 & 7L) + 0.5F) / 8 - 0.5F) * 0.004F;
|
||||
float f1 = (((float)(i >> 20 & 7L) + 0.5F) / 8 - 0.5F) * 0.004F;
|
||||
float f2 = (((float)(i >> 24 & 7L) + 0.5F) / 8 - 0.5F) * 0.004F;
|
||||
stack.translate(f, f1, f2);
|
||||
stack.nudge(entity.getId());
|
||||
double d0 = MathHelper.lerp(pt, entity.xOld, entity.getX());
|
||||
double d1 = MathHelper.lerp(pt, entity.yOld, entity.getY());
|
||||
double d2 = MathHelper.lerp(pt, entity.zOld, entity.getZ());
|
||||
Vector3d vector3d = entity.getPos(d0, d1, d2);
|
||||
float f3 = MathHelper.lerp(pt, entity.xRotO, entity.xRot);
|
||||
if (vector3d != null) {
|
||||
Vector3d vector3d1 = entity.getPosOffs(d0, d1, d2, 0.3F);
|
||||
Vector3d vector3d2 = entity.getPosOffs(d0, d1, d2, -0.3F);
|
||||
if (vector3d1 == null) {
|
||||
vector3d1 = vector3d;
|
||||
}
|
||||
|
||||
if (vector3d2 == null) {
|
||||
vector3d2 = vector3d;
|
||||
}
|
||||
|
||||
stack.translate(vector3d.x - d0, (vector3d1.y + vector3d2.y) / 2.0D - d1, vector3d.z - d2);
|
||||
Vector3d vector3d3 = vector3d2.add(-vector3d1.x, -vector3d1.y, -vector3d1.z);
|
||||
if (vector3d3.length() != 0.0D) {
|
||||
vector3d3 = vector3d3.normalize();
|
||||
yaw = (float)(Math.atan2(vector3d3.z, vector3d3.x) * 180.0D / Math.PI);
|
||||
f3 = (float)(Math.atan(vector3d3.y) * 73.0D);
|
||||
}
|
||||
}
|
||||
|
||||
stack.translate(0.0D, 0.375D, 0.0D);
|
||||
stack.multiply(Vector3f.YP.rotationDegrees(180 - yaw));
|
||||
stack.multiply(Vector3f.ZP.rotationDegrees(-f3));
|
||||
float f5 = (float)entity.getHurtTime() - pt;
|
||||
float f6 = entity.getDamage() - pt;
|
||||
if (f6 < 0) {
|
||||
f6 = 0;
|
||||
}
|
||||
|
||||
if (f5 > 0) {
|
||||
stack.multiply(Vector3f.XP.rotationDegrees(MathHelper.sin(f5) * f5 * f6 / 10 * (float)entity.getHurtDir()));
|
||||
}
|
||||
|
||||
int j = entity.getDisplayOffset();
|
||||
if (contents != null) {
|
||||
stack.push();
|
||||
stack.scale(0.75F);
|
||||
stack.translate(-0.5D, (float)(j - 8) / 16, 0.5D);
|
||||
stack.multiply(Vector3f.YP.rotationDegrees(90));
|
||||
contents.setTransform(stack.unwrap());
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
body.setTransform(stack.unwrap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
if (contents == null)
|
||||
relight(getWorldPosition(), body);
|
||||
else
|
||||
relight(getWorldPosition(), body, contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
body.delete();
|
||||
if (contents != null) contents.delete();
|
||||
}
|
||||
|
||||
private ModelData getContents() {
|
||||
BlockState blockstate = entity.getDisplayBlockState();
|
||||
|
||||
if (blockstate.getRenderShape() == BlockRenderType.INVISIBLE)
|
||||
return null;
|
||||
|
||||
return materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(blockstate)
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
private ModelData getBody() {
|
||||
return materialManager.solid(TextureRenderState.get(MINECART_LOCATION))
|
||||
.material(Materials.TRANSFORMED)
|
||||
.model(entity.getType(), this::getBodyModel)
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
private IModel getBodyModel() {
|
||||
int y = -3;
|
||||
return ModelPart.builder(64, 32)
|
||||
.cuboid().invertYZ().start(-10, -8, -y).size(20, 16, 2).textureOffset(0, 10).rotateX(((float)Math.PI / 2F)).endCuboid()
|
||||
.cuboid().invertYZ().start(-8, y, -10).size(16, 8, 2).rotateY(((float)Math.PI * 1.5F)).endCuboid()
|
||||
.cuboid().invertYZ().start(-8, y, -10).size(16, 8, 2).rotateY(((float)Math.PI / 2F)).endCuboid()
|
||||
.cuboid().invertYZ().start(-8, y, -8).size(16, 8, 2).rotateY((float)Math.PI).endCuboid()
|
||||
.cuboid().invertYZ().start(-8, y, -8).size(16, 8, 2).endCuboid()
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.vanilla;
|
|||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
|
||||
/**
|
||||
|
@ -46,5 +47,15 @@ public class VanillaInstances {
|
|||
r.tile(TileEntityType.SHULKER_BOX)
|
||||
.setSkipRender(true)
|
||||
.factory(ShulkerBoxInstance::new);
|
||||
|
||||
r.entity(EntityType.MINECART)
|
||||
.setSkipRender(true)
|
||||
.factory(MinecartInstance::new);
|
||||
r.entity(EntityType.HOPPER_MINECART)
|
||||
.setSkipRender(true)
|
||||
.factory(MinecartInstance::new);
|
||||
r.entity(EntityType.FURNACE_MINECART)
|
||||
.setSkipRender(true)
|
||||
.factory(MinecartInstance::new);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue