mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-13 05:54:17 +01:00
avoid floating point accuracy errors at high coordinate values.
refactor contraption model translation to be a method in AbstractContraptionEntity. - this simplifies the setup required for the fast rendering.
This commit is contained in:
parent
11616a0b16
commit
1e95fe4c7b
@ -1,11 +1,7 @@
|
|||||||
package com.simibubi.create;
|
package com.simibubi.create;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.actors.SeatEntity;
|
import com.simibubi.create.content.contraptions.components.actors.SeatEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.*;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntityRenderer;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntityRenderer;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueRenderer;
|
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueRenderer;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
@ -51,7 +47,7 @@ public class AllEntityTypes {
|
|||||||
@OnlyIn(value = Dist.CLIENT)
|
@OnlyIn(value = Dist.CLIENT)
|
||||||
public static void registerRenderers() {
|
public static void registerRenderers() {
|
||||||
RenderingRegistry.registerEntityRenderingHandler(CONTROLLED_CONTRAPTION.get(),
|
RenderingRegistry.registerEntityRenderingHandler(CONTROLLED_CONTRAPTION.get(),
|
||||||
ControlledContraptionEntityRenderer::new);
|
ContraptionEntityRenderer::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(ORIENTED_CONTRAPTION.get(),
|
RenderingRegistry.registerEntityRenderingHandler(ORIENTED_CONTRAPTION.get(),
|
||||||
OrientedContraptionEntityRenderer::new);
|
OrientedContraptionEntityRenderer::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(SUPER_GLUE.get(), SuperGlueRenderer::new);
|
RenderingRegistry.registerEntityRenderingHandler(SUPER_GLUE.get(), SuperGlueRenderer::new);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.simibubi.create.content.contraptions.base;
|
package com.simibubi.create.content.contraptions.base;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
|
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@ -19,6 +20,10 @@ public class KineticData<D extends KineticData<D>> extends InstanceData {
|
|||||||
private float rotationalSpeed;
|
private float rotationalSpeed;
|
||||||
private float rotationOffset;
|
private float rotationOffset;
|
||||||
|
|
||||||
|
protected KineticData(InstancedModel<?> owner) {
|
||||||
|
super(owner);
|
||||||
|
}
|
||||||
|
|
||||||
public D setTileEntity(KineticTileEntity te) {
|
public D setTileEntity(KineticTileEntity te) {
|
||||||
setPosition(te.getPos());
|
setPosition(te.getPos());
|
||||||
if (te.hasSource()) {
|
if (te.hasSource()) {
|
||||||
@ -37,6 +42,14 @@ public class KineticData<D extends KineticData<D>> extends InstanceData {
|
|||||||
return setPosition(pos.getX(), pos.getY(), pos.getZ());
|
return setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public D setPosition(int x, int y, int z) {
|
||||||
|
BlockPos origin = owner.renderer.getOriginCoordinate();
|
||||||
|
|
||||||
|
return setPosition((float) (x - origin.getX()),
|
||||||
|
(float) (y - origin.getY()),
|
||||||
|
(float) (z - origin.getZ()));
|
||||||
|
}
|
||||||
|
|
||||||
public D setPosition(float x, float y, float z) {
|
public D setPosition(float x, float y, float z) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.simibubi.create.content.contraptions.base;
|
package com.simibubi.create.content.contraptions.base;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
|
||||||
@ -16,6 +17,10 @@ public class RotatingData extends KineticData<RotatingData> {
|
|||||||
private byte rotationAxisY;
|
private byte rotationAxisY;
|
||||||
private byte rotationAxisZ;
|
private byte rotationAxisZ;
|
||||||
|
|
||||||
|
protected RotatingData(InstancedModel<?> owner) {
|
||||||
|
super(owner);
|
||||||
|
}
|
||||||
|
|
||||||
public RotatingData setRotationAxis(Direction.Axis axis) {
|
public RotatingData setRotationAxis(Direction.Axis axis) {
|
||||||
Direction orientation = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis);
|
Direction orientation = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis);
|
||||||
setRotationAxis(orientation.getUnitVector());
|
setRotationAxis(orientation.getUnitVector());
|
||||||
|
@ -2,16 +2,17 @@ package com.simibubi.create.content.contraptions.base;
|
|||||||
|
|
||||||
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
|
||||||
public class RotatingInstancedModel extends InstancedModel<RotatingData> {
|
public class RotatingInstancedModel extends InstancedModel<RotatingData> {
|
||||||
public RotatingInstancedModel(BufferBuilder buf) {
|
public RotatingInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||||
super(buf);
|
super(renderer, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingData newInstance() {
|
protected RotatingData newInstance() {
|
||||||
return new RotatingData();
|
return new RotatingData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.actors;
|
|||||||
|
|
||||||
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
|
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@ -28,6 +29,11 @@ public class ContraptionActorData extends InstanceData {
|
|||||||
private byte rotationCenterY = 64;
|
private byte rotationCenterY = 64;
|
||||||
private byte rotationCenterZ = 64;
|
private byte rotationCenterZ = 64;
|
||||||
|
|
||||||
|
protected ContraptionActorData(InstancedModel<?> owner) {
|
||||||
|
super(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public ContraptionActorData setPosition(BlockPos pos) {
|
public ContraptionActorData setPosition(BlockPos pos) {
|
||||||
this.x = pos.getX();
|
this.x = pos.getX();
|
||||||
this.y = pos.getY();
|
this.y = pos.getY();
|
||||||
|
@ -2,11 +2,12 @@ package com.simibubi.create.content.contraptions.components.actors;
|
|||||||
|
|
||||||
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
|
||||||
public class RotatingActorModel extends InstancedModel<ContraptionActorData> {
|
public class RotatingActorModel extends InstancedModel<ContraptionActorData> {
|
||||||
public RotatingActorModel(BufferBuilder buf) {
|
public RotatingActorModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||||
super(buf);
|
super(renderer, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -16,6 +17,6 @@ public class RotatingActorModel extends InstancedModel<ContraptionActorData> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ContraptionActorData newInstance() {
|
protected ContraptionActorData newInstance() {
|
||||||
return new ContraptionActorData();
|
return new ContraptionActorData(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import org.apache.commons.lang3.mutable.MutableInt;
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
|
|
||||||
@ -593,6 +594,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public abstract void doLocalTransforms(float partialTicks, MatrixStack[] matrixStacks);
|
||||||
|
|
||||||
public static class ContraptionRotationState {
|
public static class ContraptionRotationState {
|
||||||
static final ContraptionRotationState NONE = new ContraptionRotationState();
|
static final ContraptionRotationState NONE = new ContraptionRotationState();
|
||||||
|
|
||||||
|
@ -10,37 +10,26 @@ import net.minecraft.client.renderer.entity.EntityRendererManager;
|
|||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
public abstract class AbstractContraptionEntityRenderer<C extends AbstractContraptionEntity> extends EntityRenderer<C> {
|
public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> extends EntityRenderer<C> {
|
||||||
|
|
||||||
protected AbstractContraptionEntityRenderer(EntityRendererManager p_i46179_1_) {
|
public ContraptionEntityRenderer(EntityRendererManager p_i46179_1_) {
|
||||||
super(p_i46179_1_);
|
super(p_i46179_1_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceLocation getEntityTexture(C p_110775_1_) {
|
public ResourceLocation getEntityTexture(C entity) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void transform(C contraptionEntity, float partialTicks, MatrixStack[] matrixStacks);
|
|
||||||
|
|
||||||
public MatrixStack makeTransformMatrix(C contraptionEntity, float partialTicks) {
|
|
||||||
MatrixStack stack = getLocalTransform(contraptionEntity, partialTicks);
|
|
||||||
|
|
||||||
transform(contraptionEntity, partialTicks, new MatrixStack[]{ stack });
|
|
||||||
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRender(C entity, ClippingHelperImpl p_225626_2_, double p_225626_3_, double p_225626_5_,
|
public boolean shouldRender(C entity, ClippingHelperImpl clippingHelper, double p_225626_3_, double p_225626_5_,
|
||||||
double p_225626_7_) {
|
double p_225626_7_) {
|
||||||
if (!super.shouldRender(entity, p_225626_2_, p_225626_3_, p_225626_5_, p_225626_7_))
|
if (entity.getContraption() == null)
|
||||||
return false;
|
return false;
|
||||||
if (!entity.isAlive())
|
if (!entity.isAlive())
|
||||||
return false;
|
return false;
|
||||||
if (entity.getContraption() == null)
|
|
||||||
return false;
|
return super.shouldRender(entity, clippingHelper, p_225626_3_, p_225626_5_, p_225626_7_);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -49,11 +38,11 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
|
|||||||
super.render(entity, yaw, partialTicks, ms, buffers, overlay);
|
super.render(entity, yaw, partialTicks, ms, buffers, overlay);
|
||||||
|
|
||||||
// Keep a copy of the transforms in order to determine correct lighting
|
// Keep a copy of the transforms in order to determine correct lighting
|
||||||
MatrixStack msLocal = getLocalTransform(entity, AnimationTickHolder.getRenderTick());
|
MatrixStack msLocal = translateTo(entity, AnimationTickHolder.getRenderTick());
|
||||||
MatrixStack[] matrixStacks = new MatrixStack[] { ms, msLocal };
|
MatrixStack[] matrixStacks = new MatrixStack[] { ms, msLocal };
|
||||||
|
|
||||||
ms.push();
|
ms.push();
|
||||||
transform(entity, partialTicks, matrixStacks);
|
entity.doLocalTransforms(partialTicks, matrixStacks);
|
||||||
Contraption contraption = entity.getContraption();
|
Contraption contraption = entity.getContraption();
|
||||||
if (contraption != null) {
|
if (contraption != null) {
|
||||||
ContraptionRenderDispatcher.render(entity, ms, buffers, msLocal, contraption);
|
ContraptionRenderDispatcher.render(entity, ms, buffers, msLocal, contraption);
|
||||||
@ -62,7 +51,7 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MatrixStack getLocalTransform(AbstractContraptionEntity entity, float pt) {
|
protected MatrixStack translateTo(AbstractContraptionEntity entity, float pt) {
|
||||||
MatrixStack matrixStack = new MatrixStack();
|
MatrixStack matrixStack = new MatrixStack();
|
||||||
double x = MathHelper.lerp(pt, entity.lastTickPosX, entity.getX());
|
double x = MathHelper.lerp(pt, entity.lastTickPosX, entity.getX());
|
||||||
double y = MathHelper.lerp(pt, entity.lastTickPosY, entity.getY());
|
double y = MathHelper.lerp(pt, entity.lastTickPosY, entity.getY());
|
@ -2,8 +2,10 @@ package com.simibubi.create.content.contraptions.components.structureMovement;
|
|||||||
|
|
||||||
import static com.simibubi.create.foundation.utility.AngleHelper.angleLerp;
|
import static com.simibubi.create.foundation.utility.AngleHelper.angleLerp;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllEntityTypes;
|
import com.simibubi.create.AllEntityTypes;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption;
|
||||||
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
@ -225,4 +227,18 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
|
|||||||
setPos(x, y, z);
|
setPos(x, y, z);
|
||||||
this.angle = angle;
|
this.angle = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void doLocalTransforms(float partialTicks, MatrixStack[] matrixStacks) {
|
||||||
|
float angle = getAngle(partialTicks);
|
||||||
|
Axis axis = getRotationAxis();
|
||||||
|
|
||||||
|
for (MatrixStack stack : matrixStacks)
|
||||||
|
MatrixStacker.of(stack)
|
||||||
|
.nudge(getEntityId())
|
||||||
|
.centre()
|
||||||
|
.rotate(angle, axis)
|
||||||
|
.unCentre();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
|
||||||
import net.minecraft.util.Direction.Axis;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
|
|
||||||
public class ControlledContraptionEntityRenderer extends AbstractContraptionEntityRenderer<ControlledContraptionEntity> {
|
|
||||||
|
|
||||||
public ControlledContraptionEntityRenderer(EntityRendererManager p_i46179_1_) {
|
|
||||||
super(p_i46179_1_);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void transform(ControlledContraptionEntity entity, float partialTicks,
|
|
||||||
MatrixStack[] matrixStacks) {
|
|
||||||
float angle = entity.getAngle(partialTicks);
|
|
||||||
Axis axis = entity.getRotationAxis();
|
|
||||||
|
|
||||||
for (MatrixStack stack : matrixStacks)
|
|
||||||
MatrixStacker.of(stack)
|
|
||||||
.nudge(entity.getEntityId())
|
|
||||||
.centre()
|
|
||||||
.rotate(angle, axis)
|
|
||||||
.unCentre();
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,6 +7,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllEntityTypes;
|
import com.simibubi.create.AllEntityTypes;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.StabilizedContraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.StabilizedContraption;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode;
|
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||||
@ -14,10 +15,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.mou
|
|||||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
|
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.MinecartController;
|
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.MinecartController;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.*;
|
||||||
import com.simibubi.create.foundation.utility.Couple;
|
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@ -40,6 +38,8 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -494,4 +494,89 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
|
|||||||
yaw = angle;
|
yaw = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void doLocalTransforms(float partialTicks, MatrixStack[] matrixStacks) {
|
||||||
|
float angleInitialYaw = getInitialYaw();
|
||||||
|
float angleYaw = getYaw(partialTicks);
|
||||||
|
float anglePitch = getPitch(partialTicks);
|
||||||
|
|
||||||
|
for (MatrixStack stack : matrixStacks)
|
||||||
|
stack.translate(-.5f, 0, -.5f);
|
||||||
|
|
||||||
|
Entity ridingEntity = getRidingEntity();
|
||||||
|
if (ridingEntity instanceof AbstractMinecartEntity)
|
||||||
|
repositionOnCart(partialTicks, matrixStacks, ridingEntity);
|
||||||
|
else if (ridingEntity instanceof AbstractContraptionEntity) {
|
||||||
|
if (ridingEntity.getRidingEntity() instanceof AbstractMinecartEntity)
|
||||||
|
repositionOnCart(partialTicks, matrixStacks, ridingEntity.getRidingEntity());
|
||||||
|
else
|
||||||
|
repositionOnContraption(partialTicks, matrixStacks, ridingEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MatrixStack stack : matrixStacks)
|
||||||
|
MatrixStacker.of(stack)
|
||||||
|
.nudge(getEntityId())
|
||||||
|
.centre()
|
||||||
|
.rotateY(angleYaw)
|
||||||
|
.rotateZ(anglePitch)
|
||||||
|
.rotateY(angleInitialYaw)
|
||||||
|
.unCentre();
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private void repositionOnContraption(float partialTicks, MatrixStack[] matrixStacks, Entity ridingEntity) {
|
||||||
|
Vec3d pos = getContraptionOffset(partialTicks, ridingEntity);
|
||||||
|
for (MatrixStack stack : matrixStacks)
|
||||||
|
stack.translate(pos.x, pos.y, pos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minecarts do not always render at their exact location, so the contraption
|
||||||
|
// has to adjust aswell
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private void repositionOnCart(float partialTicks, MatrixStack[] matrixStacks, Entity ridingEntity) {
|
||||||
|
Vec3d cartPos = getCartOffset(partialTicks, ridingEntity);
|
||||||
|
|
||||||
|
if (cartPos == Vec3d.ZERO) return;
|
||||||
|
|
||||||
|
for (MatrixStack stack : matrixStacks)
|
||||||
|
stack.translate(cartPos.x, cartPos.y, cartPos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private Vec3d getContraptionOffset(float partialTicks, Entity ridingEntity) {
|
||||||
|
AbstractContraptionEntity parent = (AbstractContraptionEntity) ridingEntity;
|
||||||
|
Vec3d passengerPosition = parent.getPassengerPosition(this, partialTicks);
|
||||||
|
double x = passengerPosition.x - MathHelper.lerp(partialTicks, this.lastTickPosX, this.getX());
|
||||||
|
double y = passengerPosition.y - MathHelper.lerp(partialTicks, this.lastTickPosY, this.getY());
|
||||||
|
double z = passengerPosition.z - MathHelper.lerp(partialTicks, this.lastTickPosZ, this.getZ());
|
||||||
|
|
||||||
|
return new Vec3d(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private Vec3d getCartOffset(float partialTicks, Entity ridingEntity) {
|
||||||
|
AbstractMinecartEntity cart = (AbstractMinecartEntity) ridingEntity;
|
||||||
|
double cartX = MathHelper.lerp(partialTicks, cart.lastTickPosX, cart.getX());
|
||||||
|
double cartY = MathHelper.lerp(partialTicks, cart.lastTickPosY, cart.getY());
|
||||||
|
double cartZ = MathHelper.lerp(partialTicks, cart.lastTickPosZ, cart.getZ());
|
||||||
|
Vec3d cartPos = cart.getPos(cartX, cartY, cartZ);
|
||||||
|
|
||||||
|
if (cartPos != null) {
|
||||||
|
Vec3d cartPosFront = cart.getPosOffset(cartX, cartY, cartZ, (double) 0.3F);
|
||||||
|
Vec3d cartPosBack = cart.getPosOffset(cartX, cartY, cartZ, (double) -0.3F);
|
||||||
|
if (cartPosFront == null)
|
||||||
|
cartPosFront = cartPos;
|
||||||
|
if (cartPosBack == null)
|
||||||
|
cartPosBack = cartPos;
|
||||||
|
|
||||||
|
cartX = cartPos.x - cartX;
|
||||||
|
cartY = (cartPosFront.y + cartPosBack.y) / 2.0D - cartY;
|
||||||
|
cartZ = cartPos.z - cartZ;
|
||||||
|
|
||||||
|
return new Vec3d(cartX, cartY, cartZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Vec3d.ZERO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,113 +1,20 @@
|
|||||||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.culling.ClippingHelperImpl;
|
import net.minecraft.client.renderer.culling.ClippingHelperImpl;
|
||||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
|
||||||
import net.minecraft.util.Direction;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
|
|
||||||
public class OrientedContraptionEntityRenderer extends AbstractContraptionEntityRenderer<OrientedContraptionEntity> {
|
public class OrientedContraptionEntityRenderer extends ContraptionEntityRenderer<OrientedContraptionEntity> {
|
||||||
|
|
||||||
public OrientedContraptionEntityRenderer(EntityRendererManager p_i46179_1_) {
|
public OrientedContraptionEntityRenderer(EntityRendererManager p_i46179_1_) {
|
||||||
super(p_i46179_1_);
|
super(p_i46179_1_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRender(OrientedContraptionEntity entity, ClippingHelperImpl p_225626_2_, double p_225626_3_,
|
public boolean shouldRender(OrientedContraptionEntity entity, ClippingHelperImpl clippingHelper, double p_225626_3_,
|
||||||
double p_225626_5_, double p_225626_7_) {
|
double p_225626_5_, double p_225626_7_) {
|
||||||
if (!super.shouldRender(entity, p_225626_2_, p_225626_3_, p_225626_5_, p_225626_7_))
|
if (!super.shouldRender(entity, clippingHelper, p_225626_3_, p_225626_5_, p_225626_7_))
|
||||||
return false;
|
return false;
|
||||||
if (entity.getContraption()
|
|
||||||
.getType() == AllContraptionTypes.MOUNTED && entity.getRidingEntity() == null)
|
return entity.getContraption().getType() != AllContraptionTypes.MOUNTED || entity.getRidingEntity() != null;
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void transform(OrientedContraptionEntity entity, float partialTicks, MatrixStack[] matrixStacks) {
|
|
||||||
float angleInitialYaw = entity.getInitialYaw();
|
|
||||||
float angleYaw = entity.getYaw(partialTicks);
|
|
||||||
float anglePitch = entity.getPitch(partialTicks);
|
|
||||||
|
|
||||||
for (MatrixStack stack : matrixStacks)
|
|
||||||
stack.translate(-.5f, 0, -.5f);
|
|
||||||
|
|
||||||
Entity ridingEntity = entity.getRidingEntity();
|
|
||||||
if (ridingEntity instanceof AbstractMinecartEntity)
|
|
||||||
repositionOnCart(partialTicks, matrixStacks, ridingEntity);
|
|
||||||
else if (ridingEntity instanceof AbstractContraptionEntity) {
|
|
||||||
if (ridingEntity.getRidingEntity() instanceof AbstractMinecartEntity)
|
|
||||||
repositionOnCart(partialTicks, matrixStacks, ridingEntity.getRidingEntity());
|
|
||||||
else
|
|
||||||
repositionOnContraption(entity, partialTicks, matrixStacks, ridingEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MatrixStack stack : matrixStacks)
|
|
||||||
MatrixStacker.of(stack)
|
|
||||||
.nudge(entity.getEntityId())
|
|
||||||
.centre()
|
|
||||||
.rotateY(angleYaw)
|
|
||||||
.rotateZ(anglePitch)
|
|
||||||
.rotateY(angleInitialYaw)
|
|
||||||
.unCentre();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void repositionOnContraption(OrientedContraptionEntity entity, float partialTicks,
|
|
||||||
MatrixStack[] matrixStacks, Entity ridingEntity) {
|
|
||||||
Vec3d pos = getContraptionOffset(entity, partialTicks, ridingEntity);
|
|
||||||
for (MatrixStack stack : matrixStacks)
|
|
||||||
stack.translate(pos.x, pos.y, pos.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minecarts do not always render at their exact location, so the contraption
|
|
||||||
// has to adjust aswell
|
|
||||||
private void repositionOnCart(float partialTicks, MatrixStack[] matrixStacks, Entity ridingEntity) {
|
|
||||||
Vec3d cartPos = getCartOffset(partialTicks, ridingEntity);
|
|
||||||
|
|
||||||
if (cartPos == Vec3d.ZERO) return;
|
|
||||||
|
|
||||||
for (MatrixStack stack : matrixStacks)
|
|
||||||
stack.translate(cartPos.x, cartPos.y, cartPos.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vec3d getContraptionOffset(OrientedContraptionEntity entity, float partialTicks, Entity ridingEntity) {
|
|
||||||
AbstractContraptionEntity parent = (AbstractContraptionEntity) ridingEntity;
|
|
||||||
Vec3d passengerPosition = parent.getPassengerPosition(entity, partialTicks);
|
|
||||||
double x = passengerPosition.x - MathHelper.lerp(partialTicks, entity.lastTickPosX, entity.getX());
|
|
||||||
double y = passengerPosition.y - MathHelper.lerp(partialTicks, entity.lastTickPosY, entity.getY());
|
|
||||||
double z = passengerPosition.z - MathHelper.lerp(partialTicks, entity.lastTickPosZ, entity.getZ());
|
|
||||||
|
|
||||||
return new Vec3d(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vec3d getCartOffset(float partialTicks, Entity ridingEntity) {
|
|
||||||
AbstractMinecartEntity cart = (AbstractMinecartEntity) ridingEntity;
|
|
||||||
double cartX = MathHelper.lerp(partialTicks, cart.lastTickPosX, cart.getX());
|
|
||||||
double cartY = MathHelper.lerp(partialTicks, cart.lastTickPosY, cart.getY());
|
|
||||||
double cartZ = MathHelper.lerp(partialTicks, cart.lastTickPosZ, cart.getZ());
|
|
||||||
Vec3d cartPos = cart.getPos(cartX, cartY, cartZ);
|
|
||||||
|
|
||||||
if (cartPos != null) {
|
|
||||||
Vec3d cartPosFront = cart.getPosOffset(cartX, cartY, cartZ, (double) 0.3F);
|
|
||||||
Vec3d cartPosBack = cart.getPosOffset(cartX, cartY, cartZ, (double) -0.3F);
|
|
||||||
if (cartPosFront == null)
|
|
||||||
cartPosFront = cartPos;
|
|
||||||
if (cartPosBack == null)
|
|
||||||
cartPosBack = cartPos;
|
|
||||||
|
|
||||||
cartX = cartPos.x - cartX;
|
|
||||||
cartY = (cartPosFront.y + cartPosBack.y) / 2.0D - cartY;
|
|
||||||
cartZ = cartPos.z - cartZ;
|
|
||||||
|
|
||||||
return new Vec3d(cartX, cartY, cartZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Vec3d.ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,20 @@ import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
|||||||
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
||||||
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
|
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
|
||||||
import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel;
|
import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
|
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerMaterials() {
|
public void registerMaterials() {
|
||||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_BELT, BeltInstancedModel::new));
|
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_BELT, BeltInstancedModel::new));
|
||||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_ROTATING, RotatingInstancedModel::new));
|
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ROTATING, RotatingInstancedModel::new));
|
||||||
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_ACTOR, RotatingActorModel::new));
|
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ACTOR, RotatingActorModel::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getOriginCoordinate() {
|
||||||
|
return BlockPos.ZERO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
|||||||
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
||||||
import net.minecraft.client.renderer.Matrix4f;
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import org.lwjgl.opengl.GL20;
|
import org.lwjgl.opengl.GL20;
|
||||||
|
|
||||||
public class ContraptionProgram extends BasicProgram {
|
public class ContraptionProgram extends BasicProgram {
|
||||||
@ -26,9 +27,12 @@ public class ContraptionProgram extends BasicProgram {
|
|||||||
uLightVolume = setSamplerBinding("uLightVolume", 4);
|
uLightVolume = setSamplerBinding("uLightVolume", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(Matrix4f model, GridAlignedBB lightVolume) {
|
public void bind(Matrix4f model, AxisAlignedBB lightVolume) {
|
||||||
GL20.glUniform3f(uLightBoxSize, lightVolume.sizeX(), lightVolume.sizeY(), lightVolume.sizeZ());
|
double sizeX = lightVolume.maxX - lightVolume.minX;
|
||||||
GL20.glUniform3f(uLightBoxMin, lightVolume.minX, lightVolume.minY, lightVolume.minZ);
|
double sizeY = lightVolume.maxY - lightVolume.minY;
|
||||||
|
double sizeZ = lightVolume.maxZ - lightVolume.minZ;
|
||||||
|
GL20.glUniform3f(uLightBoxSize, (float) sizeX, (float) sizeY, (float) sizeZ);
|
||||||
|
GL20.glUniform3f(uLightBoxMin, (float) lightVolume.minX, (float) lightVolume.minY, (float) lightVolume.minZ);
|
||||||
uploadMatrixUniform(uModel, model);
|
uploadMatrixUniform(uModel, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,60 +38,34 @@ import org.lwjgl.opengl.GL40;
|
|||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
import java.util.concurrent.ForkJoinPool;
|
|
||||||
|
|
||||||
public class ContraptionRenderDispatcher {
|
public class ContraptionRenderDispatcher {
|
||||||
public static final Int2ObjectMap<RenderedContraption> renderers = new Int2ObjectOpenHashMap<>();
|
public static final Int2ObjectMap<RenderedContraption> renderers = new Int2ObjectOpenHashMap<>();
|
||||||
public static final Compartment<Pair<Contraption, Integer>> CONTRAPTION = new Compartment<>();
|
public static final Compartment<Pair<Contraption, Integer>> CONTRAPTION = new Compartment<>();
|
||||||
protected static PlacementSimulationWorld renderWorld;
|
protected static PlacementSimulationWorld renderWorld;
|
||||||
|
|
||||||
|
private static boolean firstLayer = true;
|
||||||
|
|
||||||
public static void notifyLightUpdate(ILightReader world, LightType type, SectionPos pos) {
|
public static void notifyLightUpdate(ILightReader world, LightType type, SectionPos pos) {
|
||||||
for (RenderedContraption renderer : renderers.values()) {
|
for (RenderedContraption renderer : renderers.values()) {
|
||||||
renderer.getLighter().lightVolume.notifyLightUpdate(world, type, pos);
|
renderer.getLighter().lightVolume.notifyLightUpdate(world, type, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderTick(TickEvent.RenderTickEvent event) {
|
public static void renderTick() {
|
||||||
if (!Backend.canUseVBOs()) return;
|
firstLayer = true;
|
||||||
|
|
||||||
ClientWorld world = Minecraft.getInstance().world;
|
|
||||||
if (event.phase == TickEvent.Phase.START && world != null) {
|
|
||||||
Map<Integer, WeakReference<AbstractContraptionEntity>> map = ContraptionHandler.loadedContraptions.get(world);
|
|
||||||
|
|
||||||
for (WeakReference<AbstractContraptionEntity> weakReference : map.values()) {
|
|
||||||
AbstractContraptionEntity entity = weakReference.get();
|
|
||||||
|
|
||||||
if (entity == null) continue;
|
|
||||||
|
|
||||||
EntityRendererManager renderManager = Minecraft.getInstance().getRenderManager();
|
|
||||||
|
|
||||||
EntityRenderer<?> renderer = renderManager.getRenderer(entity);
|
|
||||||
|
|
||||||
if (renderer instanceof AbstractContraptionEntityRenderer) {
|
|
||||||
updateTransform(entity, (AbstractContraptionEntityRenderer<? super AbstractContraptionEntity>) renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
public static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
||||||
IRenderTypeBuffer buffer) {
|
IRenderTypeBuffer buffer) {
|
||||||
if (Backend.canUseInstancing()) {
|
PlacementSimulationWorld renderWorld = null;
|
||||||
|
if (Backend.canUseVBOs()) {
|
||||||
RenderedContraption renderer = getRenderer(world, c);
|
RenderedContraption renderer = getRenderer(world, c);
|
||||||
|
|
||||||
TileEntityRenderHelper.renderTileEntities(world, renderer.renderWorld, c.specialRenderedTileEntities, ms, msLocal, buffer);
|
renderWorld = renderer.renderWorld;
|
||||||
} else {
|
|
||||||
TileEntityRenderHelper.renderTileEntities(world, c.specialRenderedTileEntities, ms, msLocal, buffer);
|
|
||||||
}
|
}
|
||||||
}
|
TileEntityRenderHelper.renderTileEntities(world, renderWorld, c.specialRenderedTileEntities, ms, msLocal, buffer);
|
||||||
|
|
||||||
private static <C extends AbstractContraptionEntity> void updateTransform(C c, AbstractContraptionEntityRenderer<C> entityRenderer) {
|
|
||||||
MatrixStack stack = entityRenderer.makeTransformMatrix(c, AnimationTickHolder.getPartialTicks());
|
|
||||||
|
|
||||||
Contraption c1 = c.getContraption();
|
|
||||||
getRenderer(c1.entity.world, c1).setRenderSettings(stack.peek().getModel());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick() {
|
public static void tick() {
|
||||||
@ -112,11 +86,20 @@ public class ContraptionRenderDispatcher {
|
|||||||
return contraption;
|
return contraption;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderLayer(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ) {
|
public static void renderLayer(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
removeDeadContraptions();
|
removeDeadContraptions();
|
||||||
|
|
||||||
if (renderers.isEmpty()) return;
|
if (renderers.isEmpty()) return;
|
||||||
|
|
||||||
|
if (firstLayer) {
|
||||||
|
|
||||||
|
for (RenderedContraption renderer : renderers.values()) {
|
||||||
|
renderer.beginFrame(camX, camY, camZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
firstLayer = false;
|
||||||
|
}
|
||||||
|
|
||||||
layer.startDrawing();
|
layer.startDrawing();
|
||||||
GL11.glEnable(GL13.GL_TEXTURE_3D);
|
GL11.glEnable(GL13.GL_TEXTURE_3D);
|
||||||
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
|
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
|
||||||
@ -142,19 +125,13 @@ public class ContraptionRenderDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void removeDeadContraptions() {
|
public static void removeDeadContraptions() {
|
||||||
ArrayList<Integer> toRemove = new ArrayList<>();
|
renderers.values().removeIf(renderer -> {
|
||||||
|
|
||||||
for (RenderedContraption renderer : renderers.values()) {
|
|
||||||
if (renderer.isDead()) {
|
if (renderer.isDead()) {
|
||||||
toRemove.add(renderer.getEntityId());
|
|
||||||
renderer.invalidate();
|
renderer.invalidate();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
for (Integer id : toRemove) {
|
|
||||||
renderers.remove(id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void invalidateAll() {
|
public static void invalidateAll() {
|
||||||
|
@ -3,23 +3,26 @@ package com.simibubi.create.content.contraptions.components.structureMovement.re
|
|||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllMovementBehaviours;
|
import com.simibubi.create.AllMovementBehaviours;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.*;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
|
||||||
import com.simibubi.create.foundation.render.backend.Backend;
|
import com.simibubi.create.foundation.render.backend.Backend;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||||
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
|
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
||||||
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
|
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
|
||||||
import net.minecraft.block.BlockRenderType;
|
import net.minecraft.block.BlockRenderType;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.*;
|
import net.minecraft.client.renderer.*;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.gen.feature.template.Template;
|
import net.minecraft.world.gen.feature.template.Template;
|
||||||
import net.minecraft.world.lighting.WorldLightManager;
|
import net.minecraft.world.lighting.WorldLightManager;
|
||||||
@ -45,6 +48,7 @@ public class RenderedContraption {
|
|||||||
public Contraption contraption;
|
public Contraption contraption;
|
||||||
|
|
||||||
private Matrix4f model;
|
private Matrix4f model;
|
||||||
|
private AxisAlignedBB lightBox;
|
||||||
|
|
||||||
public RenderedContraption(World world, Contraption contraption) {
|
public RenderedContraption(World world, Contraption contraption) {
|
||||||
this.contraption = contraption;
|
this.contraption = contraption;
|
||||||
@ -76,14 +80,55 @@ public class RenderedContraption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void doRenderLayer(RenderType layer, ContraptionProgram shader) {
|
public void doRenderLayer(RenderType layer, ContraptionProgram shader) {
|
||||||
ContraptionModel buffer = renderLayers.get(layer);
|
ContraptionModel structure = renderLayers.get(layer);
|
||||||
if (buffer != null) {
|
if (structure != null) {
|
||||||
setup(shader);
|
setup(shader);
|
||||||
buffer.render();
|
structure.render();
|
||||||
teardown();
|
teardown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void beginFrame(double camX, double camY, double camZ) {
|
||||||
|
AbstractContraptionEntity entity = contraption.entity;
|
||||||
|
float pt = AnimationTickHolder.getPartialTicks();
|
||||||
|
|
||||||
|
MatrixStack stack = new MatrixStack();
|
||||||
|
|
||||||
|
double x = MathHelper.lerp(pt, entity.lastTickPosX, entity.getX()) - camX;
|
||||||
|
double y = MathHelper.lerp(pt, entity.lastTickPosY, entity.getY()) - camY;
|
||||||
|
double z = MathHelper.lerp(pt, entity.lastTickPosZ, entity.getZ()) - camZ;
|
||||||
|
stack.translate(x, y, z);
|
||||||
|
|
||||||
|
entity.doLocalTransforms(pt, new MatrixStack[]{ stack });
|
||||||
|
|
||||||
|
model = stack.peek().getModel();
|
||||||
|
|
||||||
|
AxisAlignedBB lightBox = GridAlignedBB.toAABB(lighter.lightVolume.getTextureVolume());
|
||||||
|
|
||||||
|
this.lightBox = lightBox.offset(-camX, -camY, -camZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup(ContraptionProgram shader) {
|
||||||
|
if (model == null || lightBox == null) return;
|
||||||
|
shader.bind(model, lightBox);
|
||||||
|
lighter.lightVolume.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void teardown() {
|
||||||
|
lighter.lightVolume.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate() {
|
||||||
|
for (ContraptionModel buffer : renderLayers.values()) {
|
||||||
|
buffer.delete();
|
||||||
|
}
|
||||||
|
renderLayers.clear();
|
||||||
|
|
||||||
|
lighter.lightVolume.delete();
|
||||||
|
|
||||||
|
kinetics.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
private void buildLayers() {
|
private void buildLayers() {
|
||||||
for (ContraptionModel buffer : renderLayers.values()) {
|
for (ContraptionModel buffer : renderLayers.values()) {
|
||||||
buffer.delete();
|
buffer.delete();
|
||||||
@ -128,37 +173,12 @@ public class RenderedContraption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRenderSettings(Matrix4f model) {
|
|
||||||
this.model = model;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup(ContraptionProgram shader) {
|
|
||||||
if (model == null) return;
|
|
||||||
shader.bind(model, lighter.lightVolume.getTextureVolume());
|
|
||||||
lighter.lightVolume.use();
|
|
||||||
}
|
|
||||||
|
|
||||||
void teardown() {
|
|
||||||
lighter.lightVolume.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalidate() {
|
|
||||||
for (ContraptionModel buffer : renderLayers.values()) {
|
|
||||||
buffer.delete();
|
|
||||||
}
|
|
||||||
renderLayers.clear();
|
|
||||||
|
|
||||||
lighter.lightVolume.delete();
|
|
||||||
|
|
||||||
kinetics.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ContraptionModel buildStructureModel(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) {
|
private static ContraptionModel buildStructureModel(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) {
|
||||||
BufferBuilder builder = buildStructure(renderWorld, c, layer);
|
BufferBuilder builder = buildStructure(renderWorld, c, layer);
|
||||||
return new ContraptionModel(builder);
|
return new ContraptionModel(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlacementSimulationWorld setupRenderWorld(World world, Contraption c) {
|
private static PlacementSimulationWorld setupRenderWorld(World world, Contraption c) {
|
||||||
PlacementSimulationWorld renderWorld = new PlacementSimulationWorld(world);
|
PlacementSimulationWorld renderWorld = new PlacementSimulationWorld(world);
|
||||||
|
|
||||||
renderWorld.setTileEntities(c.presentTileEntities.values());
|
renderWorld.setTileEntities(c.presentTileEntities.values());
|
||||||
@ -176,7 +196,7 @@ public class RenderedContraption {
|
|||||||
return renderWorld;
|
return renderWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BufferBuilder buildStructure(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) {
|
private static BufferBuilder buildStructure(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) {
|
||||||
|
|
||||||
ForgeHooksClient.setRenderLayer(layer);
|
ForgeHooksClient.setRenderLayer(layer);
|
||||||
MatrixStack ms = new MatrixStack();
|
MatrixStack ms = new MatrixStack();
|
||||||
|
@ -4,6 +4,7 @@ import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
|||||||
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticVertexAttributes;
|
import com.simibubi.create.content.contraptions.base.KineticVertexAttributes;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticData;
|
import com.simibubi.create.content.contraptions.base.KineticData;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -25,6 +26,10 @@ public class BeltData extends KineticData<BeltData> {
|
|||||||
private float maxV;
|
private float maxV;
|
||||||
private byte scrollMult;
|
private byte scrollMult;
|
||||||
|
|
||||||
|
protected BeltData(InstancedModel<?> owner) {
|
||||||
|
super(owner);
|
||||||
|
}
|
||||||
|
|
||||||
public BeltData setRotation(float rotX, float rotY, float rotZ) {
|
public BeltData setRotation(float rotX, float rotY, float rotZ) {
|
||||||
this.rotX = rotX;
|
this.rotX = rotX;
|
||||||
this.rotY = rotY;
|
this.rotY = rotY;
|
||||||
@ -32,7 +37,6 @@ public class BeltData extends KineticData<BeltData> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public BeltData setScrollTexture(SpriteShiftEntry spriteShift) {
|
public BeltData setScrollTexture(SpriteShiftEntry spriteShift) {
|
||||||
TextureAtlasSprite source = spriteShift.getOriginal();
|
TextureAtlasSprite source = spriteShift.getOriginal();
|
||||||
TextureAtlasSprite target = spriteShift.getTarget();
|
TextureAtlasSprite target = spriteShift.getTarget();
|
||||||
|
@ -2,16 +2,17 @@ package com.simibubi.create.content.contraptions.relays.belt;
|
|||||||
|
|
||||||
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
|
||||||
public class BeltInstancedModel extends InstancedModel<BeltData> {
|
public class BeltInstancedModel extends InstancedModel<BeltData> {
|
||||||
public BeltInstancedModel(BufferBuilder buf) {
|
public BeltInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||||
super(buf);
|
super(renderer, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BeltData newInstance() {
|
protected BeltData newInstance() {
|
||||||
return new BeltData();
|
return new BeltData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package com.simibubi.create.content.schematics.client;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
|
|
||||||
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
|
|
||||||
public class SchematicRendererWithInstancing extends SchematicRenderer {
|
|
||||||
public final ContraptionKineticRenderer tiles;
|
|
||||||
|
|
||||||
public SchematicRendererWithInstancing() {
|
|
||||||
this.tiles = new ContraptionKineticRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void redraw(Minecraft minecraft) {
|
|
||||||
super.redraw(minecraft);
|
|
||||||
|
|
||||||
tiles.invalidate();
|
|
||||||
|
|
||||||
schematic.getRenderedTileEntities().forEach(tiles::add);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(MatrixStack ms, SuperRenderTypeBuffer buffer) {
|
|
||||||
super.render(ms, buffer);
|
|
||||||
|
|
||||||
//tiles.render(RenderType.getCutoutMipped(), FastRenderDispatcher.getProjectionMatrix(), );
|
|
||||||
}
|
|
||||||
}
|
|
@ -195,7 +195,7 @@ public class ClientEvents {
|
|||||||
if (!isGameActive())
|
if (!isGameActive())
|
||||||
return;
|
return;
|
||||||
TurntableHandler.gameRenderTick();
|
TurntableHandler.gameRenderTick();
|
||||||
ContraptionRenderDispatcher.renderTick(event);
|
ContraptionRenderDispatcher.renderTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean isGameActive() {
|
protected static boolean isGameActive() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.simibubi.create.foundation.mixin;
|
package com.simibubi.create.foundation.mixin;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.simibubi.create.CreateClient;
|
import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||||
import com.simibubi.create.foundation.render.backend.Backend;
|
import com.simibubi.create.foundation.render.backend.Backend;
|
||||||
@ -38,17 +39,12 @@ public class RenderHooksMixin {
|
|||||||
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ, CallbackInfo ci) {
|
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ, CallbackInfo ci) {
|
||||||
if (!Backend.available()) return;
|
if (!Backend.available()) return;
|
||||||
|
|
||||||
float cameraX = (float) camX;
|
Matrix4f viewProjection = stack.peek().getModel().copy();
|
||||||
float cameraY = (float) camY;
|
|
||||||
float cameraZ = (float) camZ;
|
|
||||||
|
|
||||||
Matrix4f viewProjection = Matrix4f.translate(-cameraX, -cameraY, -cameraZ);
|
|
||||||
viewProjection.multiplyBackward(stack.peek().getModel());
|
|
||||||
viewProjection.multiplyBackward(FastRenderDispatcher.getProjectionMatrix());
|
viewProjection.multiplyBackward(FastRenderDispatcher.getProjectionMatrix());
|
||||||
|
|
||||||
FastRenderDispatcher.renderLayer(type, viewProjection, cameraX, cameraY, cameraZ);
|
FastRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ);
|
||||||
|
|
||||||
ContraptionRenderDispatcher.renderLayer(type, viewProjection, cameraX, cameraY, cameraZ);
|
ContraptionRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ);
|
||||||
|
|
||||||
GL20.glUseProgram(0);
|
GL20.glUseProgram(0);
|
||||||
}
|
}
|
||||||
@ -60,6 +56,6 @@ public class RenderHooksMixin {
|
|||||||
OptifineHandler.refresh();
|
OptifineHandler.refresh();
|
||||||
Backend.refresh();
|
Backend.refresh();
|
||||||
|
|
||||||
if (world != null) world.loadedTileEntityList.forEach(CreateClient.kineticRenderer::add);
|
if (Backend.canUseInstancing() && world != null) world.loadedTileEntityList.forEach(CreateClient.kineticRenderer::add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,73 @@ import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
|||||||
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
|
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
|
||||||
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
||||||
|
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
|
public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
|
||||||
|
public static int MAX_ORIGIN_DISTANCE = 1000;
|
||||||
|
|
||||||
|
public BlockPos originCoordinate = BlockPos.ZERO;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerMaterials() {
|
public void registerMaterials() {
|
||||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllProgramSpecs.BELT, BeltInstancedModel::new));
|
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::new));
|
||||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllProgramSpecs.ROTATING, RotatingInstancedModel::new));
|
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingInstancedModel::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getOriginCoordinate() {
|
||||||
|
return originCoordinate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
Entity renderViewEntity = mc.renderViewEntity;
|
||||||
|
|
||||||
|
if (renderViewEntity == null) return;
|
||||||
|
|
||||||
|
BlockPos renderViewPosition = renderViewEntity.getPosition();
|
||||||
|
|
||||||
|
int dX = Math.abs(renderViewPosition.getX() - originCoordinate.getX());
|
||||||
|
int dY = Math.abs(renderViewPosition.getY() - originCoordinate.getY());
|
||||||
|
int dZ = Math.abs(renderViewPosition.getZ() - originCoordinate.getZ());
|
||||||
|
|
||||||
|
if (dX > MAX_ORIGIN_DISTANCE ||
|
||||||
|
dY > MAX_ORIGIN_DISTANCE ||
|
||||||
|
dZ > MAX_ORIGIN_DISTANCE) {
|
||||||
|
|
||||||
|
originCoordinate = renderViewPosition;
|
||||||
|
|
||||||
|
ArrayList<TileEntity> instancedTiles = new ArrayList<>(instances.keySet());
|
||||||
|
invalidate();
|
||||||
|
instancedTiles.forEach(this::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, ShaderCallback<BasicProgram> callback) {
|
||||||
|
BlockPos originCoordinate = getOriginCoordinate();
|
||||||
|
|
||||||
|
camX -= originCoordinate.getX();
|
||||||
|
camY -= originCoordinate.getY();
|
||||||
|
camZ -= originCoordinate.getZ();
|
||||||
|
|
||||||
|
Matrix4f translate = Matrix4f.translate((float) -camX, (float) -camY, (float) -camZ);
|
||||||
|
|
||||||
|
translate.multiplyBackward(viewProjection);
|
||||||
|
|
||||||
|
super.render(layer, translate, camX, camY, camZ, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,6 @@ import java.util.function.Predicate;
|
|||||||
|
|
||||||
public class Backend {
|
public class Backend {
|
||||||
public static final Logger log = LogManager.getLogger(Backend.class);
|
public static final Logger log = LogManager.getLogger(Backend.class);
|
||||||
public static final FloatBuffer FLOAT_BUFFER = MemoryUtil.memAllocFloat(1); // TODO: these leak 80 bytes of memory per program launch
|
|
||||||
public static final FloatBuffer VEC4_BUFFER = MemoryUtil.memAllocFloat(4);
|
|
||||||
public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16);
|
public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16);
|
||||||
|
|
||||||
private static final Map<ResourceLocation, ProgramSpec<?>> registry = new HashMap<>();
|
private static final Map<ResourceLocation, ProgramSpec<?>> registry = new HashMap<>();
|
||||||
|
@ -29,7 +29,6 @@ import java.util.function.Consumer;
|
|||||||
public class FastRenderDispatcher {
|
public class FastRenderDispatcher {
|
||||||
|
|
||||||
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> queuedUpdates = new WorldAttached<>(ConcurrentHashMap::newKeySet);
|
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> queuedUpdates = new WorldAttached<>(ConcurrentHashMap::newKeySet);
|
||||||
public static WorldAttached<ConcurrentHashMap<TileEntity, Integer>> addedLastTick = new WorldAttached<>(ConcurrentHashMap::new);
|
|
||||||
|
|
||||||
private static Matrix4f projectionMatrixThisFrame = null;
|
private static Matrix4f projectionMatrixThisFrame = null;
|
||||||
|
|
||||||
@ -44,26 +43,7 @@ public class FastRenderDispatcher {
|
|||||||
public static void tick() {
|
public static void tick() {
|
||||||
ClientWorld world = Minecraft.getInstance().world;
|
ClientWorld world = Minecraft.getInstance().world;
|
||||||
|
|
||||||
// Clean up twice a second. This doesn't have to happen every tick,
|
CreateClient.kineticRenderer.tick();
|
||||||
// but this does need to be run to ensure we don't miss anything.
|
|
||||||
int ticks = AnimationTickHolder.getTicks();
|
|
||||||
|
|
||||||
ConcurrentHashMap<TileEntity, Integer> map = addedLastTick.get(world);
|
|
||||||
map
|
|
||||||
.entrySet()
|
|
||||||
.stream()
|
|
||||||
.filter(it -> ticks - it.getValue() > 10)
|
|
||||||
.map(Map.Entry::getKey)
|
|
||||||
.forEach(te -> {
|
|
||||||
map.remove(te);
|
|
||||||
|
|
||||||
CreateClient.kineticRenderer.onLightUpdate(te);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if (ticks % 10 == 0) {
|
|
||||||
CreateClient.kineticRenderer.clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
runQueue(queuedUpdates.get(world), CreateClient.kineticRenderer::update);
|
runQueue(queuedUpdates.get(world), CreateClient.kineticRenderer::update);
|
||||||
}
|
}
|
||||||
@ -98,7 +78,7 @@ public class FastRenderDispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderLayer(RenderType layer, Matrix4f viewProjection, float cameraX, float cameraY, float cameraZ) {
|
public static void renderLayer(RenderType layer, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||||
if (!Backend.canUseInstancing()) return;
|
if (!Backend.canUseInstancing()) return;
|
||||||
|
|
||||||
layer.startDrawing();
|
layer.startDrawing();
|
||||||
|
@ -37,14 +37,14 @@ public class BasicProgram extends GlProgram {
|
|||||||
uLightMap = setSamplerBinding("uLightMap", 2);
|
uLightMap = setSamplerBinding("uLightMap", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(Matrix4f viewProjection, float camX, float camY, float camZ, int debugMode) {
|
public void bind(Matrix4f viewProjection, double camX, double camY, double camZ, int debugMode) {
|
||||||
super.bind();
|
super.bind();
|
||||||
|
|
||||||
GL20.glUniform1i(uDebug, debugMode);
|
GL20.glUniform1i(uDebug, debugMode);
|
||||||
GL20.glUniform1f(uTime, AnimationTickHolder.getRenderTick());
|
GL20.glUniform1f(uTime, AnimationTickHolder.getRenderTick());
|
||||||
|
|
||||||
uploadMatrixUniform(uViewProjection, viewProjection);
|
uploadMatrixUniform(uViewProjection, viewProjection);
|
||||||
GL20.glUniform3f(uCameraPos, camX, camY, camZ);
|
GL20.glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
|
||||||
|
|
||||||
GL20.glUniform2f(uFogRange, GlFog.getFogStart(), GlFog.getFogEnd());
|
GL20.glUniform2f(uFogRange, GlFog.getFogStart(), GlFog.getFogEnd());
|
||||||
GL20.glUniform4fv(uFogColor, GlFog.FOG_COLOR);
|
GL20.glUniform4fv(uFogColor, GlFog.FOG_COLOR);
|
||||||
|
@ -4,6 +4,12 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
public abstract class InstanceData {
|
public abstract class InstanceData {
|
||||||
|
|
||||||
|
protected final InstancedModel<?> owner;
|
||||||
|
|
||||||
|
protected InstanceData(InstancedModel<?> owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void write(ByteBuffer buf);
|
public abstract void write(ByteBuffer buf);
|
||||||
|
|
||||||
public void putVec4(ByteBuffer buf, float x, float y, float z, float w) {
|
public void putVec4(ByteBuffer buf, float x, float y, float z, float w) {
|
||||||
|
@ -17,6 +17,8 @@ import java.util.function.Consumer;
|
|||||||
public abstract class InstancedModel<D extends InstanceData> extends BufferedModel {
|
public abstract class InstancedModel<D extends InstanceData> extends BufferedModel {
|
||||||
public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelVertexAttributes.class).build();
|
public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelVertexAttributes.class).build();
|
||||||
|
|
||||||
|
public final InstancedTileRenderer<?> renderer;
|
||||||
|
|
||||||
protected GlVertexArray vao;
|
protected GlVertexArray vao;
|
||||||
protected GlBuffer instanceVBO;
|
protected GlBuffer instanceVBO;
|
||||||
protected int glBufferSize = -1;
|
protected int glBufferSize = -1;
|
||||||
@ -27,8 +29,9 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
|
|||||||
protected int minIndexChanged = -1;
|
protected int minIndexChanged = -1;
|
||||||
protected int maxIndexChanged = -1;
|
protected int maxIndexChanged = -1;
|
||||||
|
|
||||||
public InstancedModel(BufferBuilder buf) {
|
public InstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
|
this.renderer = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
package com.simibubi.create.foundation.render.backend.instancing;
|
package com.simibubi.create.foundation.render.backend.instancing;
|
||||||
|
|
||||||
|
import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||||
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
||||||
import com.simibubi.create.foundation.render.backend.Backend;
|
import com.simibubi.create.foundation.render.backend.Backend;
|
||||||
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
|
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
|
import com.simibubi.create.foundation.utility.WorldAttached;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.Matrix4f;
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
||||||
|
public static WorldAttached<ConcurrentHashMap<TileEntity, Integer>> addedLastTick = new WorldAttached<>(ConcurrentHashMap::new);
|
||||||
|
|
||||||
protected Map<TileEntity, TileEntityInstance<?>> instances = new HashMap<>();
|
protected Map<TileEntity, TileEntityInstance<?>> instances = new HashMap<>();
|
||||||
|
|
||||||
protected Map<MaterialType<?>, RenderMaterial<P, ?>> materials = new HashMap<>();
|
protected Map<MaterialType<?>, RenderMaterial<P, ?>> materials = new HashMap<>();
|
||||||
@ -22,8 +30,35 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||||||
registerMaterials();
|
registerMaterials();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract BlockPos getOriginCoordinate();
|
||||||
|
|
||||||
public abstract void registerMaterials();
|
public abstract void registerMaterials();
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
ClientWorld world = Minecraft.getInstance().world;
|
||||||
|
|
||||||
|
int ticks = AnimationTickHolder.getTicks();
|
||||||
|
|
||||||
|
ConcurrentHashMap<TileEntity, Integer> map = addedLastTick.get(world);
|
||||||
|
map
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter(it -> ticks - it.getValue() > 10)
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.forEach(te -> {
|
||||||
|
map.remove(te);
|
||||||
|
|
||||||
|
onLightUpdate(te);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Clean up twice a second. This doesn't have to happen every tick,
|
||||||
|
// but this does need to be run to ensure we don't miss anything.
|
||||||
|
if (ticks % 10 == 0) {
|
||||||
|
clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <M extends InstancedModel<?>> RenderMaterial<P, M> getMaterial(MaterialType<M> materialType) {
|
public <M extends InstancedModel<?>> RenderMaterial<P, M> getMaterial(MaterialType<M> materialType) {
|
||||||
return (RenderMaterial<P, M>) materials.get(materialType);
|
return (RenderMaterial<P, M>) materials.get(materialType);
|
||||||
@ -47,7 +82,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||||||
TileEntityInstance<? super T> renderer = InstancedTileRenderRegistry.instance.create(this, tile);
|
TileEntityInstance<? super T> renderer = InstancedTileRenderRegistry.instance.create(this, tile);
|
||||||
|
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).put(tile, AnimationTickHolder.getTicks());
|
addedLastTick.get(tile.getWorld()).put(tile, AnimationTickHolder.getTicks());
|
||||||
instances.put(tile, renderer);
|
instances.put(tile, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +93,8 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T extends TileEntity> void onLightUpdate(T tile) {
|
public <T extends TileEntity> void onLightUpdate(T tile) {
|
||||||
|
if (!Backend.canUseInstancing()) return;
|
||||||
|
|
||||||
if (tile instanceof IInstanceRendered) {
|
if (tile instanceof IInstanceRendered) {
|
||||||
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
||||||
|
|
||||||
@ -67,12 +104,16 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T extends TileEntity> void add(T tile) {
|
public <T extends TileEntity> void add(T tile) {
|
||||||
|
if (!Backend.canUseInstancing()) return;
|
||||||
|
|
||||||
if (tile instanceof IInstanceRendered) {
|
if (tile instanceof IInstanceRendered) {
|
||||||
getInstance(tile);
|
getInstance(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends TileEntity> void update(T tile) {
|
public <T extends TileEntity> void update(T tile) {
|
||||||
|
if (!Backend.canUseInstancing()) return;
|
||||||
|
|
||||||
if (tile instanceof IInstanceRendered) {
|
if (tile instanceof IInstanceRendered) {
|
||||||
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
||||||
|
|
||||||
@ -82,6 +123,8 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T extends TileEntity> void remove(T tile) {
|
public <T extends TileEntity> void remove(T tile) {
|
||||||
|
if (!Backend.canUseInstancing()) return;
|
||||||
|
|
||||||
if (tile instanceof IInstanceRendered) {
|
if (tile instanceof IInstanceRendered) {
|
||||||
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
||||||
|
|
||||||
@ -103,11 +146,11 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||||||
instances.clear();
|
instances.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ) {
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
render(layer, viewProjection, camX, camY, camZ, null);
|
render(layer, viewProjection, camX, camY, camZ, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ, ShaderCallback<P> callback) {
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, ShaderCallback<P> callback) {
|
||||||
for (RenderMaterial<P, ?> material : materials.values()) {
|
for (RenderMaterial<P, ?> material : materials.values()) {
|
||||||
if (material.canRenderInLayer(layer))
|
if (material.canRenderInLayer(layer))
|
||||||
material.render(layer, viewProjection, camX, camY, camZ, callback);
|
material.render(layer, viewProjection, camX, camY, camZ, callback);
|
||||||
|
@ -4,5 +4,5 @@ import net.minecraft.client.renderer.BufferBuilder;
|
|||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ModelFactory<B extends InstancedModel<?>> {
|
public interface ModelFactory<B extends InstancedModel<?>> {
|
||||||
B convert(BufferBuilder buf);
|
B makeModel(InstancedTileRenderer<?> renderer, BufferBuilder buf);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import static com.simibubi.create.foundation.render.Compartment.PARTIAL;
|
|||||||
|
|
||||||
public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel<?>> {
|
public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel<?>> {
|
||||||
|
|
||||||
|
protected final InstancedTileRenderer<?> renderer;
|
||||||
protected final Map<Compartment<?>, Cache<Object, MODEL>> models;
|
protected final Map<Compartment<?>, Cache<Object, MODEL>> models;
|
||||||
protected final ModelFactory<MODEL> factory;
|
protected final ModelFactory<MODEL> factory;
|
||||||
protected final ProgramSpec<P> programSpec;
|
protected final ProgramSpec<P> programSpec;
|
||||||
@ -41,11 +42,12 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
|
|||||||
/**
|
/**
|
||||||
* Creates a material that renders in the default layer (CUTOUT_MIPPED)
|
* Creates a material that renders in the default layer (CUTOUT_MIPPED)
|
||||||
*/
|
*/
|
||||||
public RenderMaterial(ProgramSpec<P> programSpec, ModelFactory<MODEL> factory) {
|
public RenderMaterial(InstancedTileRenderer<?> renderer, ProgramSpec<P> programSpec, ModelFactory<MODEL> factory) {
|
||||||
this(programSpec, factory, type -> type == RenderType.getCutoutMipped());
|
this(renderer, programSpec, factory, type -> type == RenderType.getCutoutMipped());
|
||||||
}
|
}
|
||||||
|
|
||||||
public RenderMaterial(ProgramSpec<P> programSpec, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
|
public RenderMaterial(InstancedTileRenderer<?> renderer, ProgramSpec<P> programSpec, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
|
||||||
|
this.renderer = renderer;
|
||||||
this.models = new HashMap<>();
|
this.models = new HashMap<>();
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
this.programSpec = programSpec;
|
this.programSpec = programSpec;
|
||||||
@ -59,11 +61,11 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
|
|||||||
return layerPredicate.test(layer);
|
return layerPredicate.test(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(RenderType layer, Matrix4f projection, float camX, float camY, float camZ) {
|
public void render(RenderType layer, Matrix4f projection, double camX, double camY, double camZ) {
|
||||||
render(layer, projection, camX, camY, camZ, null);
|
render(layer, projection, camX, camY, camZ, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ, ShaderCallback<P> setup) {
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, ShaderCallback<P> setup) {
|
||||||
P program = Backend.getProgram(programSpec);
|
P program = Backend.getProgram(programSpec);
|
||||||
program.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode());
|
program.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode());
|
||||||
|
|
||||||
@ -142,7 +144,7 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
|
|||||||
private MODEL buildModel(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
private MODEL buildModel(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||||
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
||||||
|
|
||||||
return factory.convert(builder);
|
return factory.makeModel(renderer, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ public abstract class TileEntityInstance<T extends TileEntity> {
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void init();
|
|
||||||
|
|
||||||
public final void update() {
|
public final void update() {
|
||||||
BlockState currentState = tile.getBlockState();
|
BlockState currentState = tile.getBlockState();
|
||||||
if (lastState == currentState) {
|
if (lastState == currentState) {
|
||||||
@ -35,9 +33,24 @@ public abstract class TileEntityInstance<T extends TileEntity> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire all {@link InstanceKey}s and initialize any data you may need to calculate the instance properties.
|
||||||
|
*/
|
||||||
|
protected abstract void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update changed instance data using the {@link InstanceKey}s you got in {@link #init()}.
|
||||||
|
* You don't have to update light data. That should be done in {@link #updateLight()}
|
||||||
|
*/
|
||||||
protected abstract void onUpdate();
|
protected abstract void onUpdate();
|
||||||
|
|
||||||
public abstract void updateLight();
|
/**
|
||||||
|
* Called when a light update occurs in the world. If your model needs it, update light here.
|
||||||
|
*/
|
||||||
|
public void updateLight() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link InstanceKey#delete()} on all acquired keys.
|
||||||
|
*/
|
||||||
public abstract void remove();
|
public abstract void remove();
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ public class LightVolume {
|
|||||||
bufferDirty = true;
|
bufferDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void use() {
|
public void bind() {
|
||||||
// just in case something goes wrong or we accidentally call this before this volume is properly disposed of.
|
// just in case something goes wrong or we accidentally call this before this volume is properly disposed of.
|
||||||
if (lightData == null || removed) return;
|
if (lightData == null || removed) return;
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ public class LightVolume {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void release() {
|
public void unbind() {
|
||||||
glTexture.unbind();
|
glTexture.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,13 +67,15 @@ void main() {
|
|||||||
vec4 worldPos = localRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
|
vec4 worldPos = localRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
|
||||||
|
|
||||||
#ifdef CONTRAPTION
|
#ifdef CONTRAPTION
|
||||||
|
|
||||||
worldPos = uModel * worldPos;
|
worldPos = uModel * worldPos;
|
||||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
|
||||||
|
|
||||||
mat4 normalMat = uModel * localRotation;
|
mat4 normalMat = uModel * localRotation;
|
||||||
|
|
||||||
|
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||||
|
FragDistance = length(worldPos.xyz);
|
||||||
#else
|
#else
|
||||||
mat4 normalMat = localRotation;
|
mat4 normalMat = localRotation;
|
||||||
|
|
||||||
|
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
||||||
@ -84,7 +86,6 @@ void main() {
|
|||||||
Diffuse = diffuse(norm);
|
Diffuse = diffuse(norm);
|
||||||
TexCoords = aTexCoords - aSourceTexture + aScrollTexture.xy + vec2(0, scroll);
|
TexCoords = aTexCoords - aSourceTexture + aScrollTexture.xy + vec2(0, scroll);
|
||||||
Light = aLight;
|
Light = aLight;
|
||||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
|
||||||
gl_Position = uViewProjection * worldPos;
|
gl_Position = uViewProjection * worldPos;
|
||||||
|
|
||||||
#ifdef CONTRAPTION
|
#ifdef CONTRAPTION
|
||||||
|
@ -77,7 +77,7 @@ void main() {
|
|||||||
Diffuse = diffuse(norm);
|
Diffuse = diffuse(norm);
|
||||||
TexCoords = aTexCoords;
|
TexCoords = aTexCoords;
|
||||||
Light = aModelLight;
|
Light = aModelLight;
|
||||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
FragDistance = length(worldPos.xyz);
|
||||||
gl_Position = uViewProjection * worldPos;
|
gl_Position = uViewProjection * worldPos;
|
||||||
|
|
||||||
if (uDebug == 2) {
|
if (uDebug == 2) {
|
||||||
|
@ -43,17 +43,17 @@ float diffuse(vec3 normal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 worldPos = uModel * vec4(aPos, 1.);
|
vec4 viewPos = uModel * vec4(aPos, 1.);
|
||||||
|
|
||||||
vec3 norm = (uModel * vec4(aNormal, 0.)).xyz;
|
vec3 norm = (uModel * vec4(aNormal, 0.)).xyz;
|
||||||
|
|
||||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
BoxCoord = (viewPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||||
Diffuse = diffuse(norm);
|
Diffuse = diffuse(norm);
|
||||||
Color = aColor / diffuse(aNormal);
|
Color = aColor / diffuse(aNormal);
|
||||||
TexCoords = aTexCoords;
|
TexCoords = aTexCoords;
|
||||||
Light = aModelLight;
|
Light = aModelLight;
|
||||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
FragDistance = length(viewPos.xyz);
|
||||||
gl_Position = uViewProjection * worldPos;
|
gl_Position = uViewProjection * viewPos;
|
||||||
|
|
||||||
if (uDebug == 2) {
|
if (uDebug == 2) {
|
||||||
Color = vec4(norm, 1.);
|
Color = vec4(norm, 1.);
|
||||||
|
@ -65,13 +65,15 @@ void main() {
|
|||||||
vec4 worldPos = kineticRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
|
vec4 worldPos = kineticRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
|
||||||
|
|
||||||
#ifdef CONTRAPTION
|
#ifdef CONTRAPTION
|
||||||
|
|
||||||
worldPos = uModel * worldPos;
|
worldPos = uModel * worldPos;
|
||||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
|
||||||
|
|
||||||
mat4 normalMat = uModel * kineticRotation;
|
mat4 normalMat = uModel * kineticRotation;
|
||||||
|
|
||||||
|
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||||
|
FragDistance = length(worldPos.xyz);
|
||||||
#else
|
#else
|
||||||
mat4 normalMat = kineticRotation;
|
mat4 normalMat = kineticRotation;
|
||||||
|
|
||||||
|
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
||||||
@ -79,7 +81,6 @@ void main() {
|
|||||||
Diffuse = diffuse(norm);
|
Diffuse = diffuse(norm);
|
||||||
TexCoords = aTexCoords;
|
TexCoords = aTexCoords;
|
||||||
Light = aLight;
|
Light = aLight;
|
||||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
|
||||||
gl_Position = uViewProjection * worldPos;
|
gl_Position = uViewProjection * worldPos;
|
||||||
|
|
||||||
#ifdef CONTRAPTION
|
#ifdef CONTRAPTION
|
||||||
|
Loading…
Reference in New Issue
Block a user