Smooth harvesters, step sounds v1.

This commit is contained in:
JozsefA 2021-03-20 13:16:20 -07:00
parent c0de8c4eb6
commit 3d0898c59b
17 changed files with 294 additions and 75 deletions

View file

@ -48,11 +48,10 @@ public class DrillActorInstance extends ActorInstance {
}
@Override
protected void tick() {
public void beginFrame() {
drillHead.getInstance().setSpeed(getSpeed(facing));
}
@Override
protected float getSpeed(Direction facing) {
if (context.contraption.stalled || !VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite()))
return context.getAnimationSpeed();

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.contraptions.components.actors;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
@ -7,45 +8,87 @@ import com.simibubi.create.content.contraptions.components.structureMovement.ren
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.Quaternion;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.Direction;
import net.minecraft.world.LightType;
import net.minecraft.util.math.Vec3d;
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
public class HarvesterActorInstance extends ActorInstance {
static double oneOverRadius = 16.0 / 6.5;
static float originOffset = 1 / 16f;
static Vec3d rotOffset = new Vec3d(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
InstanceKey<ContraptionActorData> harvester;
InstanceKey<ModelData> harvester;
private Direction facing;
private float horizontalAngle;
private double rotation;
private double previousRotation;
public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context);
RenderMaterial<?, InstancedModel<ContraptionActorData>> renderMaterial = modelManager.getActorMaterial();
RenderMaterial<?, InstancedModel<ModelData>> renderMaterial = modelManager.getBasicMaterial();
BlockState state = context.state;
facing = state.get(HORIZONTAL_FACING);
float originOffset = 1 / 16f;
Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
harvester = renderMaterial.getModel(AllBlockPartials.HARVESTER_BLADE, state).createInstance();
float horizontalAngle = facing.getHorizontalAngle() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0);
horizontalAngle = facing.getHorizontalAngle() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0);
harvester.getInstance()
.setPosition(context.localPos)
.setBlockLight(localBlockLight())
.setRotationOffset(0)
.setRotationCenter(rotOffset)
.setRotationAxis(-1, 0, 0)
.setLocalRotation(new Quaternion(Vector3f.POSITIVE_Y, horizontalAngle, true))
.setSpeed(getSpeed(facing));
.setBlockLight(localBlockLight());
}
@Override
protected void tick() {
harvester.getInstance().setSpeed(getSpeed(facing));
public void tick() {
super.tick();
previousRotation = rotation;
if (context.contraption.stalled || VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite()))
return;
double arcLength = context.motion.length();
double radians = arcLength * oneOverRadius;
float deg = AngleHelper.deg(radians);
deg = (float) (((int) (deg * 3000)) / 3000);
rotation += deg * 1.25;
rotation %= 360;
}
@Override
public void beginFrame() {
MatrixStack ms = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(ms);
msr.translate(context.localPos)
.centre()
.rotateY(horizontalAngle)
.unCentre()
.translate(rotOffset)
.rotateX(getRotation())
.translateBack(rotOffset);
harvester.getInstance().setTransform(ms);
}
private double getRotation() {
return AngleHelper.angleLerp(AnimationTickHolder.getPartialTicks(), previousRotation, rotation);
}
}

View file

@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionProgram;
import com.simibubi.create.foundation.render.Compartment;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
@ -18,7 +17,6 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE;
import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING;
@ -39,7 +37,7 @@ public class DeployerActorInstance extends ActorInstance {
public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context);
RenderMaterial<ContraptionProgram, InstancedModel<ModelData>> mat = modelManager.basicMaterial();
RenderMaterial<ContraptionProgram, InstancedModel<ModelData>> mat = modelManager.getBasicMaterial();
BlockState state = context.state;
DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class);
@ -73,7 +71,7 @@ public class DeployerActorInstance extends ActorInstance {
}
@Override
protected void tick() {
public void beginFrame() {
double factor;
if (context.contraption.stalled || context.position == null || context.data.contains("StationaryTimer")) {
factor = MathHelper.sin(AnimationTickHolder.getRenderTime() * .5f) * .25f + .25f;

View file

@ -50,7 +50,7 @@ public class DeployerInstance extends ShaftInstance implements ITickableInstance
zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
zRotPole = rotatePole ? 90 : 0;
pole = modelManager.basicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, lastState).createInstance();
pole = modelManager.getBasicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, lastState).createInstance();
updateHandPose();
relight(pos, pole.getInstance());
@ -100,7 +100,7 @@ public class DeployerInstance extends ShaftInstance implements ITickableInstance
if (hand != null) hand.delete();
hand = modelManager.basicMaterial().getModel(currentHand, lastState).createInstance();
hand = modelManager.getBasicMaterial().getModel(currentHand, lastState).createInstance();
relight(pos, hand.getInstance());

View file

@ -131,6 +131,8 @@ public abstract class Contraption {
public List<TileEntity> maybeInstancedTileEntities;
public List<TileEntity> specialRenderedTileEntities;
protected ContraptionWorld world;
public Contraption() {
blocks = new HashMap<>();
storage = new HashMap<>();
@ -148,6 +150,14 @@ public abstract class Contraption {
stabilizedSubContraptions = new HashMap<>();
}
public ContraptionWorld getContraptionWorld() {
if (world == null) {
world = new ContraptionWorld(entity.world, this);
}
return world;
}
public abstract boolean assemble(World world, BlockPos pos) throws AssemblyException;
public abstract boolean canBeStabilized(Direction facing, BlockPos localPos);

View file

@ -70,7 +70,6 @@ public class ContraptionCollider {
Vec3d contraptionPosition = contraptionEntity.getPositionVec();
Vec3d contraptionMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec());
Vec3d anchorVec = contraptionEntity.getAnchorVec();
Vec3d centerOfBlock = VecHelper.CENTER_OF_ORIGIN;
ContraptionRotationState rotation = null;
// After death, multiple refs to the client player may show up in the area
@ -103,19 +102,10 @@ public class ContraptionCollider {
// Transform entity position and motion to local space
Vec3d entityPosition = entity.getPositionVec();
AxisAlignedBB entityBounds = entity.getBoundingBox();
Vec3d centerY = new Vec3d(0, entityBounds.getYSize() / 2, 0);
Vec3d motion = entity.getMotion();
float yawOffset = rotation.getYawOffset();
Vec3d position = entityPosition;
position = position.add(centerY);
position = position.subtract(centerOfBlock);
position = position.subtract(anchorVec);
position = VecHelper.rotate(position, -yawOffset, Axis.Y);
position = rotationMatrix.transform(position);
position = position.add(centerOfBlock);
position = position.subtract(centerY);
position = position.subtract(entityPosition);
Vec3d position = getWorldToLocalTranslation(entity, anchorVec, rotationMatrix, yawOffset);
// Find all potential block shapes to collide with
AxisAlignedBB localBB = entityBounds.offset(position)
@ -264,6 +254,48 @@ public class ContraptionCollider {
}
public static Vec3d getWorldToLocalTranslation(Entity entity, AbstractContraptionEntity contraptionEntity) {
return getWorldToLocalTranslation(entity, contraptionEntity.getAnchorVec(), contraptionEntity.getRotationState());
}
public static Vec3d getWorldToLocalTranslation(Entity entity, Vec3d anchorVec, ContraptionRotationState rotation) {
return getWorldToLocalTranslation(entity, anchorVec, rotation.asMatrix(), rotation.getYawOffset());
}
public static Vec3d getWorldToLocalTranslation(Entity entity, Vec3d anchorVec, Matrix3d rotationMatrix, float yawOffset) {
Vec3d entityPosition = entity.getPositionVec();
Vec3d centerY = new Vec3d(0, entity.getBoundingBox().getYSize() / 2, 0);
Vec3d position = entityPosition;
position = position.add(centerY);
position = position.subtract(VecHelper.CENTER_OF_ORIGIN);
position = position.subtract(anchorVec);
position = VecHelper.rotate(position, -yawOffset, Axis.Y);
position = rotationMatrix.transform(position);
position = position.add(VecHelper.CENTER_OF_ORIGIN);
position = position.subtract(centerY);
position = position.subtract(entityPosition);
return position;
}
public static Vec3d getWorldToLocalTranslation(Vec3d entity, AbstractContraptionEntity contraptionEntity) {
return getWorldToLocalTranslation(entity, contraptionEntity.getAnchorVec(), contraptionEntity.getRotationState());
}
public static Vec3d getWorldToLocalTranslation(Vec3d inPos, Vec3d anchorVec, ContraptionRotationState rotation) {
return getWorldToLocalTranslation(inPos, anchorVec, rotation.asMatrix(), rotation.getYawOffset());
}
public static Vec3d getWorldToLocalTranslation(Vec3d inPos, Vec3d anchorVec, Matrix3d rotationMatrix, float yawOffset) {
Vec3d position = inPos;
position = position.subtract(VecHelper.CENTER_OF_ORIGIN);
position = position.subtract(anchorVec);
position = VecHelper.rotate(position, -yawOffset, Axis.Y);
position = rotationMatrix.transform(position);
position = position.add(VecHelper.CENTER_OF_ORIGIN);
position = position.subtract(inPos);
return position;
}
/** From Entity#getAllowedMovement **/
static Vec3d getAllowedMovement(Vec3d movement, Entity e) {
AxisAlignedBB bb = e.getBoundingBox();

View file

@ -0,0 +1,48 @@
package com.simibubi.create.content.contraptions.components.structureMovement;
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template;
public class ContraptionWorld extends WrappedWorld {
final Contraption contraption;
public ContraptionWorld(World world, Contraption contraption) {
super(world);
this.contraption = contraption;
}
@Override
public BlockState getBlockState(BlockPos pos) {
Template.BlockInfo blockInfo = contraption.getBlocks().get(pos);
if (blockInfo != null)
return blockInfo.state;
return Blocks.AIR.getDefaultState();
}
@Override
public void playSound(PlayerEntity player, double x, double y, double z, SoundEvent soundIn, SoundCategory category, float volume, float pitch) {
Vec3d worldPos = ContraptionCollider.getWorldToLocalTranslation(new Vec3d(x, y, z), this.contraption.entity);
worldPos = worldPos.add(x, y, z);
world.playSound(player, worldPos.x, worldPos.y, worldPos.z, soundIn, category, volume, pitch);
}
@Override
public void playSound(double x, double y, double z, SoundEvent p_184134_7_, SoundCategory p_184134_8_, float p_184134_9_, float p_184134_10_, boolean p_184134_11_) {
world.playSound(x, y, z, p_184134_7_, p_184134_8_, p_184134_9_, p_184134_10_, p_184134_11_);
}
}

View file

@ -1,8 +1,6 @@
package com.simibubi.create.content.contraptions.components.structureMovement.render;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.util.Direction;
import net.minecraft.world.LightType;
public abstract class ActorInstance {
@ -14,14 +12,9 @@ public abstract class ActorInstance {
this.context = context;
}
protected void tick() { }
public void tick() { }
protected float getSpeed(Direction facing) {
if (context.contraption.stalled)
return 0;
return !VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite()) ? context.getAnimationSpeed() : 0;
}
public void beginFrame() { }
protected int localBlockLight() {
return modelManager.contraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos);

View file

@ -10,21 +10,16 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapInstancedModel;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.gen.feature.template.Template;
import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
@ -46,12 +41,16 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, RotatingActorModel::new));
}
@Override
public void tick() {
actors.forEach(ActorInstance::tick);
}
@Override
public void beginFrame(double cameraX, double cameraY, double cameraZ) {
super.beginFrame(cameraX, cameraY, cameraZ);
actors.forEach(ActorInstance::tick);
actors.forEach(ActorInstance::beginFrame);
}
@Nullable

View file

@ -4,9 +4,7 @@ import java.util.List;
import java.util.Random;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL40;
import org.lwjgl.opengl.*;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllMovementBehaviours;
@ -81,8 +79,12 @@ public class ContraptionRenderDispatcher {
}
public static void tick() {
if (Minecraft.getInstance().isGamePaused()) return;
for (RenderedContraption contraption : renderers.values()) {
contraption.getLighter().tick(contraption);
contraption.kinetics.tick();
}
}

View file

@ -5,8 +5,6 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
@ -14,7 +12,6 @@ import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.block.BlockState;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
@ -46,7 +43,7 @@ public class FluidValveInstance extends ShaftInstance implements ITickableInstan
if (pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical())
pointerRotationOffset = 90;
pointer = modelManager.basicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, lastState).createInstance();
pointer = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, lastState).createInstance();
updateLight();
transformPointer((FluidValveTileEntity) tile);

View file

@ -33,7 +33,13 @@ public class AddRemoveTileMixin {
* to a change in block state, even on the client. By hooking into this method,
* we gain easy access to the information while having no impact on performance.
*/
@Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"), method = "removeTileEntity", locals = LocalCapture.CAPTURE_FAILHARD)
@Inject(at = @At(
value = "INVOKE_ASSIGN",
target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"
),
method = "removeTileEntity",
locals = LocalCapture.CAPTURE_FAILHARD
)
private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) {
if (isRemote) {
World thi = (World)(Object) this;
@ -49,7 +55,11 @@ public class AddRemoveTileMixin {
}
}
@Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities")
@Inject(at = @At(
value = "INVOKE",
target = "Ljava/util/Set;clear()V", ordinal = 0
),
method = "tickBlockEntities")
private void onChunkUnload(CallbackInfo ci) {
if (isRemote) {
World thi = (World)(Object) this;

View file

@ -2,6 +2,7 @@ package com.simibubi.create.foundation.mixin;
import com.simibubi.create.foundation.render.KineticRenderer;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.opengl.GL20;
import org.spongepowered.asm.mixin.Mixin;

View file

@ -0,0 +1,90 @@
package com.simibubi.create.foundation.mixin;
import com.simibubi.create.content.contraptions.components.structureMovement.*;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.MoverType;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.lang.ref.Reference;
import java.util.Set;
import java.util.stream.Collectors;
@Mixin(Entity.class)
public abstract class StepSoundMixin {
@Shadow public boolean collided;
@Shadow public World world;
@Shadow public abstract BlockPos getPosition();
@Shadow public abstract Vec3d getPositionVec();
@Shadow private float nextStepDistance;
@Shadow protected abstract float determineNextStepDistance();
@Shadow public abstract AxisAlignedBB getBoundingBox();
@Shadow protected abstract void playStepSound(BlockPos p_180429_1_, BlockState p_180429_2_);
@Inject(at = @At(
value = "JUMP",
opcode = 154, //IFNE
ordinal = 4
),
method = "move"
)
private void movementMixin(MoverType mover, Vec3d movement, CallbackInfo ci) {
Entity thi = (Entity) (Object) this;
World entityWorld = world;
Set<AbstractContraptionEntity> contraptions = ContraptionHandler.loadedContraptions.get(entityWorld)
.values()
.stream()
.map(Reference::get)
.filter(cEntity -> cEntity != null && cEntity.collidingEntities.containsKey(thi)).collect(Collectors.toSet());
contraptions.addAll(entityWorld.getEntitiesWithinAABB(AbstractContraptionEntity.class, getBoundingBox().grow(1f)));
Vec3d worldPos = thi.getPositionVector().add(0, -0.2, 0);
boolean stepped = false;
for (AbstractContraptionEntity cEntity : contraptions) {
Vec3d localPos = ContraptionCollider.getWorldToLocalTranslation(worldPos, cEntity);
localPos = worldPos.add(localPos);
BlockPos blockPos = new BlockPos(localPos);
Contraption contraption = cEntity.getContraption();
Template.BlockInfo info = contraption.getBlocks().get(blockPos);
if (info != null) {
BlockState blockstate = info.state;
this.world = contraption.getContraptionWorld();
this.playStepSound(blockPos, blockstate);
stepped = true;
}
}
if (stepped)
this.nextStepDistance = this.determineNextStepDistance();
world = entityWorld;
}
}

View file

@ -69,7 +69,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
return (RenderMaterial<P, M>) materials.get(materialType);
}
public RenderMaterial<P, InstancedModel<ModelData>> basicMaterial() {
public RenderMaterial<P, InstancedModel<ModelData>> getBasicMaterial() {
return getMaterial(RenderMaterials.MODELS);
}

View file

@ -39,13 +39,18 @@ uniform vec3 uCameraPos;
varying float FragDistance;
#endif
void main() {
mat4 kineticRotation() {
float degrees = aOffset + uTime * aSpeed * 3./10.;
vec4 kineticRot = quat(aAxis, degrees);
float angle = fract(degrees / 360.) * PI * 2.;
vec4 worldPos = vec4(rotateVertexByQuat(aPos - .5, kineticRot) + aInstancePos + .5, 1.);
return rotate(aAxis, angle);
}
vec3 norm = rotateVertexByQuat(aNormal, kineticRot);
void main() {
mat4 kineticRotation = kineticRotation();
vec4 worldPos = kineticRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
vec3 norm = modelToNormal(kineticRotation) * aNormal;
#ifdef CONTRAPTION
worldPos = uModel * worldPos;

View file

@ -3,17 +3,9 @@
"package": "com.simibubi.create.foundation.mixin",
"compatibilityLevel": "JAVA_8",
"refmap": "create.refmap.json",
"client": [
"AddRemoveTileMixin",
"ShaderCloseMixin",
"CancelTileEntityRenderMixin",
"LightUpdateMixin",
"RenderHooksMixin",
"FogColorTrackerMixin",
"NetworkLightUpdateMixin"
],
"client": ["AddRemoveTileMixin", "CancelTileEntityRenderMixin", "FogColorTrackerMixin", "LightUpdateMixin", "NetworkLightUpdateMixin", "RenderHooksMixin", "ShaderCloseMixin"],
"injectors": {
"defaultRequire": 1
},
"minVersion": "0.8"
"minVersion": "0.8", "mixins": ["StepSoundMixin"]
}