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
36 changed files with 431 additions and 351 deletions
|
@ -1,11 +1,7 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
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.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.*;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueRenderer;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
@ -51,7 +47,7 @@ public class AllEntityTypes {
|
|||
@OnlyIn(value = Dist.CLIENT)
|
||||
public static void registerRenderers() {
|
||||
RenderingRegistry.registerEntityRenderingHandler(CONTROLLED_CONTRAPTION.get(),
|
||||
ControlledContraptionEntityRenderer::new);
|
||||
ContraptionEntityRenderer::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(ORIENTED_CONTRAPTION.get(),
|
||||
OrientedContraptionEntityRenderer::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(SUPER_GLUE.get(), SuperGlueRenderer::new);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.base;
|
||||
|
||||
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 net.minecraft.client.renderer.Vector3f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -19,6 +20,10 @@ public class KineticData<D extends KineticData<D>> extends InstanceData {
|
|||
private float rotationalSpeed;
|
||||
private float rotationOffset;
|
||||
|
||||
protected KineticData(InstancedModel<?> owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
public D setTileEntity(KineticTileEntity te) {
|
||||
setPosition(te.getPos());
|
||||
if (te.hasSource()) {
|
||||
|
@ -37,6 +42,14 @@ public class KineticData<D extends KineticData<D>> extends InstanceData {
|
|||
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) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.base;
|
||||
|
||||
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.util.Direction;
|
||||
|
||||
|
@ -16,6 +17,10 @@ public class RotatingData extends KineticData<RotatingData> {
|
|||
private byte rotationAxisY;
|
||||
private byte rotationAxisZ;
|
||||
|
||||
protected RotatingData(InstancedModel<?> owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
public RotatingData setRotationAxis(Direction.Axis axis) {
|
||||
Direction orientation = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis);
|
||||
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.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
|
||||
public class RotatingInstancedModel extends InstancedModel<RotatingData> {
|
||||
public RotatingInstancedModel(BufferBuilder buf) {
|
||||
super(buf);
|
||||
public RotatingInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||
super(renderer, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RotatingData newInstance() {
|
||||
return new RotatingData();
|
||||
return new RotatingData(this);
|
||||
}
|
||||
|
||||
@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.instancing.InstanceData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||
import net.minecraft.client.renderer.Vector3f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
|
@ -28,6 +29,11 @@ public class ContraptionActorData extends InstanceData {
|
|||
private byte rotationCenterY = 64;
|
||||
private byte rotationCenterZ = 64;
|
||||
|
||||
protected ContraptionActorData(InstancedModel<?> owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
|
||||
public ContraptionActorData setPosition(BlockPos pos) {
|
||||
this.x = pos.getX();
|
||||
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.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
|
||||
public class RotatingActorModel extends InstancedModel<ContraptionActorData> {
|
||||
public RotatingActorModel(BufferBuilder buf) {
|
||||
super(buf);
|
||||
public RotatingActorModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||
super(renderer, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,6 +17,6 @@ public class RotatingActorModel extends InstancedModel<ContraptionActorData> {
|
|||
|
||||
@Override
|
||||
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.UUID;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
|
@ -593,6 +594,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
return false;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract void doLocalTransforms(float partialTicks, MatrixStack[] matrixStacks);
|
||||
|
||||
public static class 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.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_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getEntityTexture(C p_110775_1_) {
|
||||
public ResourceLocation getEntityTexture(C entity) {
|
||||
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
|
||||
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_) {
|
||||
if (!super.shouldRender(entity, p_225626_2_, p_225626_3_, p_225626_5_, p_225626_7_))
|
||||
if (entity.getContraption() == null)
|
||||
return false;
|
||||
if (!entity.isAlive())
|
||||
return false;
|
||||
if (entity.getContraption() == null)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
return super.shouldRender(entity, clippingHelper, p_225626_3_, p_225626_5_, p_225626_7_);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,11 +38,11 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
|
|||
super.render(entity, yaw, partialTicks, ms, buffers, overlay);
|
||||
|
||||
// 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 };
|
||||
|
||||
ms.push();
|
||||
transform(entity, partialTicks, matrixStacks);
|
||||
entity.doLocalTransforms(partialTicks, matrixStacks);
|
||||
Contraption contraption = entity.getContraption();
|
||||
if (contraption != null) {
|
||||
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();
|
||||
double x = MathHelper.lerp(pt, entity.lastTickPosX, entity.getX());
|
||||
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 com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
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.VecHelper;
|
||||
|
||||
|
@ -225,4 +227,18 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
|
|||
setPos(x, y, z);
|
||||
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 com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.StabilizedContraption;
|
||||
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.MinecartController;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.utility.*;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
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.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
/**
|
||||
|
@ -494,4 +494,89 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
|
|||
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;
|
||||
|
||||
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.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_) {
|
||||
super(p_i46179_1_);
|
||||
}
|
||||
|
||||
@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_) {
|
||||
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;
|
||||
if (entity.getContraption()
|
||||
.getType() == AllContraptionTypes.MOUNTED && entity.getRidingEntity() == null)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
return entity.getContraption().getType() != AllContraptionTypes.MOUNTED || entity.getRidingEntity() != null;
|
||||
}
|
||||
|
||||
@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.content.contraptions.base.RotatingInstancedModel;
|
||||
import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
|
||||
|
||||
@Override
|
||||
public void registerMaterials() {
|
||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_BELT, BeltInstancedModel::new));
|
||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_ROTATING, RotatingInstancedModel::new));
|
||||
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_ACTOR, RotatingActorModel::new));
|
||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_BELT, BeltInstancedModel::new));
|
||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ROTATING, RotatingInstancedModel::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 net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
public class ContraptionProgram extends BasicProgram {
|
||||
|
@ -26,9 +27,12 @@ public class ContraptionProgram extends BasicProgram {
|
|||
uLightVolume = setSamplerBinding("uLightVolume", 4);
|
||||
}
|
||||
|
||||
public void bind(Matrix4f model, GridAlignedBB lightVolume) {
|
||||
GL20.glUniform3f(uLightBoxSize, lightVolume.sizeX(), lightVolume.sizeY(), lightVolume.sizeZ());
|
||||
GL20.glUniform3f(uLightBoxMin, lightVolume.minX, lightVolume.minY, lightVolume.minZ);
|
||||
public void bind(Matrix4f model, AxisAlignedBB lightVolume) {
|
||||
double sizeX = lightVolume.maxX - lightVolume.minX;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,60 +38,34 @@ import org.lwjgl.opengl.GL40;
|
|||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
public class ContraptionRenderDispatcher {
|
||||
public static final Int2ObjectMap<RenderedContraption> renderers = new Int2ObjectOpenHashMap<>();
|
||||
public static final Compartment<Pair<Contraption, Integer>> CONTRAPTION = new Compartment<>();
|
||||
protected static PlacementSimulationWorld renderWorld;
|
||||
|
||||
private static boolean firstLayer = true;
|
||||
|
||||
public static void notifyLightUpdate(ILightReader world, LightType type, SectionPos pos) {
|
||||
for (RenderedContraption renderer : renderers.values()) {
|
||||
renderer.getLighter().lightVolume.notifyLightUpdate(world, type, pos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void renderTick(TickEvent.RenderTickEvent event) {
|
||||
if (!Backend.canUseVBOs()) return;
|
||||
|
||||
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 renderTick() {
|
||||
firstLayer = true;
|
||||
}
|
||||
|
||||
public static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
||||
IRenderTypeBuffer buffer) {
|
||||
if (Backend.canUseInstancing()) {
|
||||
PlacementSimulationWorld renderWorld = null;
|
||||
if (Backend.canUseVBOs()) {
|
||||
RenderedContraption renderer = getRenderer(world, c);
|
||||
|
||||
TileEntityRenderHelper.renderTileEntities(world, renderer.renderWorld, c.specialRenderedTileEntities, ms, msLocal, buffer);
|
||||
} else {
|
||||
TileEntityRenderHelper.renderTileEntities(world, c.specialRenderedTileEntities, ms, msLocal, buffer);
|
||||
renderWorld = renderer.renderWorld;
|
||||
}
|
||||
}
|
||||
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() {
|
||||
|
@ -112,11 +86,20 @@ public class ContraptionRenderDispatcher {
|
|||
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();
|
||||
|
||||
if (renderers.isEmpty()) return;
|
||||
|
||||
if (firstLayer) {
|
||||
|
||||
for (RenderedContraption renderer : renderers.values()) {
|
||||
renderer.beginFrame(camX, camY, camZ);
|
||||
}
|
||||
|
||||
firstLayer = false;
|
||||
}
|
||||
|
||||
layer.startDrawing();
|
||||
GL11.glEnable(GL13.GL_TEXTURE_3D);
|
||||
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() {
|
||||
ArrayList<Integer> toRemove = new ArrayList<>();
|
||||
|
||||
for (RenderedContraption renderer : renderers.values()) {
|
||||
renderers.values().removeIf(renderer -> {
|
||||
if (renderer.isDead()) {
|
||||
toRemove.add(renderer.getEntityId());
|
||||
renderer.invalidate();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (Integer id : toRemove) {
|
||||
renderers.remove(id);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
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.simibubi.create.AllMovementBehaviours;
|
||||
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.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.*;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||
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 net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
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.texture.OverlayTexture;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template;
|
||||
import net.minecraft.world.lighting.WorldLightManager;
|
||||
|
@ -45,6 +48,7 @@ public class RenderedContraption {
|
|||
public Contraption contraption;
|
||||
|
||||
private Matrix4f model;
|
||||
private AxisAlignedBB lightBox;
|
||||
|
||||
public RenderedContraption(World world, Contraption contraption) {
|
||||
this.contraption = contraption;
|
||||
|
@ -76,14 +80,55 @@ public class RenderedContraption {
|
|||
}
|
||||
|
||||
public void doRenderLayer(RenderType layer, ContraptionProgram shader) {
|
||||
ContraptionModel buffer = renderLayers.get(layer);
|
||||
if (buffer != null) {
|
||||
ContraptionModel structure = renderLayers.get(layer);
|
||||
if (structure != null) {
|
||||
setup(shader);
|
||||
buffer.render();
|
||||
structure.render();
|
||||
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() {
|
||||
for (ContraptionModel buffer : renderLayers.values()) {
|
||||
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) {
|
||||
BufferBuilder builder = buildStructure(renderWorld, c, layer);
|
||||
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);
|
||||
|
||||
renderWorld.setTileEntities(c.presentTileEntities.values());
|
||||
|
@ -176,7 +196,7 @@ public class RenderedContraption {
|
|||
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);
|
||||
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.content.contraptions.base.KineticVertexAttributes;
|
||||
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 java.nio.ByteBuffer;
|
||||
|
@ -25,6 +26,10 @@ public class BeltData extends KineticData<BeltData> {
|
|||
private float maxV;
|
||||
private byte scrollMult;
|
||||
|
||||
protected BeltData(InstancedModel<?> owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
public BeltData setRotation(float rotX, float rotY, float rotZ) {
|
||||
this.rotX = rotX;
|
||||
this.rotY = rotY;
|
||||
|
@ -32,7 +37,6 @@ public class BeltData extends KineticData<BeltData> {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BeltData setScrollTexture(SpriteShiftEntry spriteShift) {
|
||||
TextureAtlasSprite source = spriteShift.getOriginal();
|
||||
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.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
|
||||
public class BeltInstancedModel extends InstancedModel<BeltData> {
|
||||
public BeltInstancedModel(BufferBuilder buf) {
|
||||
super(buf);
|
||||
public BeltInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||
super(renderer, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BeltData newInstance() {
|
||||
return new BeltData();
|
||||
return new BeltData(this);
|
||||
}
|
||||
|
||||
@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())
|
||||
return;
|
||||
TurntableHandler.gameRenderTick();
|
||||
ContraptionRenderDispatcher.renderTick(event);
|
||||
ContraptionRenderDispatcher.renderTick();
|
||||
}
|
||||
|
||||
protected static boolean isGameActive() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.foundation.mixin;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
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) {
|
||||
if (!Backend.available()) return;
|
||||
|
||||
float cameraX = (float) camX;
|
||||
float cameraY = (float) camY;
|
||||
float cameraZ = (float) camZ;
|
||||
|
||||
Matrix4f viewProjection = Matrix4f.translate(-cameraX, -cameraY, -cameraZ);
|
||||
viewProjection.multiplyBackward(stack.peek().getModel());
|
||||
Matrix4f viewProjection = stack.peek().getModel().copy();
|
||||
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);
|
||||
}
|
||||
|
@ -60,6 +56,6 @@ public class RenderHooksMixin {
|
|||
OptifineHandler.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.relays.belt.BeltInstancedModel;
|
||||
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 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 static int MAX_ORIGIN_DISTANCE = 1000;
|
||||
|
||||
public BlockPos originCoordinate = BlockPos.ZERO;
|
||||
|
||||
@Override
|
||||
public void registerMaterials() {
|
||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllProgramSpecs.BELT, BeltInstancedModel::new));
|
||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllProgramSpecs.ROTATING, RotatingInstancedModel::new));
|
||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::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 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);
|
||||
|
||||
private static final Map<ResourceLocation, ProgramSpec<?>> registry = new HashMap<>();
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.util.function.Consumer;
|
|||
public class FastRenderDispatcher {
|
||||
|
||||
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;
|
||||
|
||||
|
@ -44,26 +43,7 @@ public class FastRenderDispatcher {
|
|||
public static void tick() {
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
|
||||
// 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.
|
||||
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();
|
||||
}
|
||||
CreateClient.kineticRenderer.tick();
|
||||
|
||||
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;
|
||||
|
||||
layer.startDrawing();
|
||||
|
|
|
@ -37,14 +37,14 @@ public class BasicProgram extends GlProgram {
|
|||
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();
|
||||
|
||||
GL20.glUniform1i(uDebug, debugMode);
|
||||
GL20.glUniform1f(uTime, AnimationTickHolder.getRenderTick());
|
||||
|
||||
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.glUniform4fv(uFogColor, GlFog.FOG_COLOR);
|
||||
|
|
|
@ -4,6 +4,12 @@ import java.nio.ByteBuffer;
|
|||
|
||||
public abstract class InstanceData {
|
||||
|
||||
protected final InstancedModel<?> owner;
|
||||
|
||||
protected InstanceData(InstancedModel<?> owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public abstract void write(ByteBuffer buf);
|
||||
|
||||
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 static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelVertexAttributes.class).build();
|
||||
|
||||
public final InstancedTileRenderer<?> renderer;
|
||||
|
||||
protected GlVertexArray vao;
|
||||
protected GlBuffer instanceVBO;
|
||||
protected int glBufferSize = -1;
|
||||
|
@ -27,8 +29,9 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
|
|||
protected int minIndexChanged = -1;
|
||||
protected int maxIndexChanged = -1;
|
||||
|
||||
public InstancedModel(BufferBuilder buf) {
|
||||
public InstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||
super(buf);
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,19 +1,27 @@
|
|||
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.gl.BasicProgram;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
|
||||
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.RenderType;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
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<MaterialType<?>, RenderMaterial<P, ?>> materials = new HashMap<>();
|
||||
|
@ -22,8 +30,35 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||
registerMaterials();
|
||||
}
|
||||
|
||||
public abstract BlockPos getOriginCoordinate();
|
||||
|
||||
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")
|
||||
public <M extends InstancedModel<?>> RenderMaterial<P, M> getMaterial(MaterialType<M> 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);
|
||||
|
||||
if (renderer != null) {
|
||||
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).put(tile, AnimationTickHolder.getTicks());
|
||||
addedLastTick.get(tile.getWorld()).put(tile, AnimationTickHolder.getTicks());
|
||||
instances.put(tile, renderer);
|
||||
}
|
||||
|
||||
|
@ -58,6 +93,8 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||
}
|
||||
|
||||
public <T extends TileEntity> void onLightUpdate(T tile) {
|
||||
if (!Backend.canUseInstancing()) return;
|
||||
|
||||
if (tile instanceof IInstanceRendered) {
|
||||
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) {
|
||||
if (!Backend.canUseInstancing()) return;
|
||||
|
||||
if (tile instanceof IInstanceRendered) {
|
||||
getInstance(tile);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends TileEntity> void update(T tile) {
|
||||
if (!Backend.canUseInstancing()) return;
|
||||
|
||||
if (tile instanceof IInstanceRendered) {
|
||||
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) {
|
||||
if (!Backend.canUseInstancing()) return;
|
||||
|
||||
if (tile instanceof IInstanceRendered) {
|
||||
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
||||
|
||||
|
@ -103,11 +146,11 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
|||
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);
|
||||
}
|
||||
|
||||
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()) {
|
||||
if (material.canRenderInLayer(layer))
|
||||
material.render(layer, viewProjection, camX, camY, camZ, callback);
|
||||
|
|
|
@ -4,5 +4,5 @@ import net.minecraft.client.renderer.BufferBuilder;
|
|||
|
||||
@FunctionalInterface
|
||||
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<?>> {
|
||||
|
||||
protected final InstancedTileRenderer<?> renderer;
|
||||
protected final Map<Compartment<?>, Cache<Object, MODEL>> models;
|
||||
protected final ModelFactory<MODEL> factory;
|
||||
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)
|
||||
*/
|
||||
public RenderMaterial(ProgramSpec<P> programSpec, ModelFactory<MODEL> factory) {
|
||||
this(programSpec, factory, type -> type == RenderType.getCutoutMipped());
|
||||
public RenderMaterial(InstancedTileRenderer<?> renderer, ProgramSpec<P> programSpec, ModelFactory<MODEL> factory) {
|
||||
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.factory = factory;
|
||||
this.programSpec = programSpec;
|
||||
|
@ -59,11 +61,11 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
|
|||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
|
||||
protected abstract void init();
|
||||
|
||||
public final void update() {
|
||||
BlockState currentState = tile.getBlockState();
|
||||
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();
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ public class LightVolume {
|
|||
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.
|
||||
if (lightData == null || removed) return;
|
||||
|
||||
|
@ -246,7 +246,7 @@ public class LightVolume {
|
|||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
public void unbind() {
|
||||
glTexture.unbind();
|
||||
}
|
||||
|
||||
|
|
|
@ -67,13 +67,15 @@ void main() {
|
|||
vec4 worldPos = localRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
|
||||
|
||||
#ifdef CONTRAPTION
|
||||
|
||||
worldPos = uModel * worldPos;
|
||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
|
||||
mat4 normalMat = uModel * localRotation;
|
||||
|
||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
FragDistance = length(worldPos.xyz);
|
||||
#else
|
||||
mat4 normalMat = localRotation;
|
||||
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
#endif
|
||||
|
||||
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
||||
|
@ -84,7 +86,6 @@ void main() {
|
|||
Diffuse = diffuse(norm);
|
||||
TexCoords = aTexCoords - aSourceTexture + aScrollTexture.xy + vec2(0, scroll);
|
||||
Light = aLight;
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
gl_Position = uViewProjection * worldPos;
|
||||
|
||||
#ifdef CONTRAPTION
|
||||
|
|
|
@ -77,7 +77,7 @@ void main() {
|
|||
Diffuse = diffuse(norm);
|
||||
TexCoords = aTexCoords;
|
||||
Light = aModelLight;
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
FragDistance = length(worldPos.xyz);
|
||||
gl_Position = uViewProjection * worldPos;
|
||||
|
||||
if (uDebug == 2) {
|
||||
|
|
|
@ -43,17 +43,17 @@ float diffuse(vec3 normal) {
|
|||
}
|
||||
|
||||
void main() {
|
||||
vec4 worldPos = uModel * vec4(aPos, 1.);
|
||||
vec4 viewPos = uModel * vec4(aPos, 1.);
|
||||
|
||||
vec3 norm = (uModel * vec4(aNormal, 0.)).xyz;
|
||||
|
||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
BoxCoord = (viewPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
Diffuse = diffuse(norm);
|
||||
Color = aColor / diffuse(aNormal);
|
||||
TexCoords = aTexCoords;
|
||||
Light = aModelLight;
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
gl_Position = uViewProjection * worldPos;
|
||||
FragDistance = length(viewPos.xyz);
|
||||
gl_Position = uViewProjection * viewPos;
|
||||
|
||||
if (uDebug == 2) {
|
||||
Color = vec4(norm, 1.);
|
||||
|
|
|
@ -65,13 +65,15 @@ void main() {
|
|||
vec4 worldPos = kineticRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
|
||||
|
||||
#ifdef CONTRAPTION
|
||||
|
||||
worldPos = uModel * worldPos;
|
||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
|
||||
mat4 normalMat = uModel * kineticRotation;
|
||||
|
||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
FragDistance = length(worldPos.xyz);
|
||||
#else
|
||||
mat4 normalMat = kineticRotation;
|
||||
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
#endif
|
||||
|
||||
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
||||
|
@ -79,7 +81,6 @@ void main() {
|
|||
Diffuse = diffuse(norm);
|
||||
TexCoords = aTexCoords;
|
||||
Light = aLight;
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
gl_Position = uViewProjection * worldPos;
|
||||
|
||||
#ifdef CONTRAPTION
|
||||
|
|
Loading…
Reference in a new issue