implement swing arm animation and entity brightness
(cherry picked from commit b9e76a3d9bd1c0c89f1ffde1a3516ff115cf3235)
This commit is contained in:
@@ -229,6 +229,8 @@ window.Minecraft = class {
|
||||
this.world.setBlockAt(hitResult.x, hitResult.y, hitResult.z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
this.player.swingArm();
|
||||
}
|
||||
|
||||
// Pick block
|
||||
|
||||
@@ -15,7 +15,6 @@ window.Entity = class {
|
||||
this.motionZ = 0;
|
||||
|
||||
this.onGround = false;
|
||||
|
||||
this.sneaking = false;
|
||||
|
||||
this.rotationYaw = 0;
|
||||
@@ -32,6 +31,8 @@ window.Entity = class {
|
||||
this.nextStepDistance = 1;
|
||||
|
||||
this.ticksExisted = 0;
|
||||
|
||||
this.boundingBox = new BoundingBox();
|
||||
}
|
||||
|
||||
onUpdate() {
|
||||
@@ -49,4 +50,15 @@ window.Entity = class {
|
||||
this.ticksExisted++;
|
||||
}
|
||||
|
||||
getEntityBrightness() {
|
||||
let x = MathHelper.floor(this.x);
|
||||
let y = MathHelper.floor(this.y + this.getEyeHeight());
|
||||
let z = MathHelper.floor(this.z);
|
||||
return this.world.getLightBrightness(x, y, z);
|
||||
}
|
||||
|
||||
getEyeHeight() {
|
||||
return this.boundingBox.height() * 0.8;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,9 @@ window.EntityLiving = class extends Entity {
|
||||
this.moveStrafing = 0.0;
|
||||
|
||||
this.swingProgress = 0;
|
||||
this.prevSwingProgress = 0;
|
||||
this.swingProgressInt = 0;
|
||||
this.swingInProgress = false;
|
||||
|
||||
this.renderYawOffset = 0;
|
||||
this.rotationYawHead = 0;
|
||||
@@ -141,6 +144,9 @@ window.EntityLiving = class extends Entity {
|
||||
onEntityUpdate() {
|
||||
this.prevRenderYawOffset = this.renderYawOffset;
|
||||
this.prevRotationYawHead = this.rotationYawHead;
|
||||
this.prevSwingProgress = this.swingProgress;
|
||||
|
||||
this.updateArmSwingProgress();
|
||||
|
||||
super.onEntityUpdate();
|
||||
}
|
||||
@@ -169,6 +175,31 @@ window.EntityLiving = class extends Entity {
|
||||
return distanceTravelledSqrt;
|
||||
}
|
||||
|
||||
swingArm() {
|
||||
let swingAnimationEnd = 6;
|
||||
if (!this.isSwingInProgress || this.swingProgressInt >= swingAnimationEnd / 2 || this.swingProgressInt < 0) {
|
||||
this.swingProgressInt = -1;
|
||||
this.isSwingInProgress = true;
|
||||
}
|
||||
}
|
||||
|
||||
updateArmSwingProgress() {
|
||||
let swingAnimationEnd = 6;
|
||||
|
||||
if (this.isSwingInProgress) {
|
||||
++this.swingProgressInt;
|
||||
|
||||
if (this.swingProgressInt >= swingAnimationEnd) {
|
||||
this.swingProgressInt = 0;
|
||||
this.isSwingInProgress = false;
|
||||
}
|
||||
} else {
|
||||
this.swingProgressInt = 0;
|
||||
}
|
||||
|
||||
this.swingProgress = this.swingProgressInt / swingAnimationEnd;
|
||||
}
|
||||
|
||||
computeAngleWithBound(value, subtract, limit) {
|
||||
let wrapped = MathHelper.wrapAngleTo180(value - subtract);
|
||||
if (wrapped < -limit) {
|
||||
|
||||
@@ -213,9 +213,9 @@ window.PlayerEntity = class extends EntityLiving {
|
||||
|
||||
// Step sound
|
||||
if (!isSlow) {
|
||||
let blockX = MathHelper.floor_double(this.x);
|
||||
let blockY = MathHelper.floor_double(this.y - 0.2);
|
||||
let blockZ = MathHelper.floor_double(this.z);
|
||||
let blockX = MathHelper.floor(this.x);
|
||||
let blockY = MathHelper.floor(this.y - 0.2);
|
||||
let blockZ = MathHelper.floor(this.z);
|
||||
let typeId = this.world.getBlockAt(blockX, blockY, blockZ);
|
||||
|
||||
let distanceX = this.x - prevX;
|
||||
|
||||
@@ -92,6 +92,8 @@ window.WorldRenderer = class {
|
||||
// Render entities
|
||||
for (let entity of this.minecraft.world.entities) {
|
||||
if (entity === player && this.minecraft.settings.thirdPersonView === 0) {
|
||||
entity.group.clear();
|
||||
entity.lastRenderedBrightness = -1; // TODO: Find a better way to trigger this
|
||||
continue;
|
||||
}
|
||||
this.renderEntity(entity, partialTicks);
|
||||
|
||||
@@ -2,13 +2,26 @@ window.EntityRenderer = class {
|
||||
|
||||
constructor(model) {
|
||||
this.model = model;
|
||||
this.tessellator = new Tessellator();
|
||||
}
|
||||
|
||||
rebuild(tessellator, entity) {
|
||||
this.model.rebuild(tessellator, entity.group);
|
||||
rebuild(entity) {
|
||||
let brightness = entity.getEntityBrightness();
|
||||
entity.lastRenderedBrightness = brightness;
|
||||
|
||||
// Apply brightness
|
||||
this.tessellator.setColor(brightness, brightness, brightness);
|
||||
|
||||
// Rebuild
|
||||
this.model.rebuild(this.tessellator, entity.group);
|
||||
}
|
||||
|
||||
render(entity, partialTicks) {
|
||||
let brightness = entity.getEntityBrightness();
|
||||
if (entity.lastRenderedBrightness !== brightness) {
|
||||
this.rebuild(entity);
|
||||
}
|
||||
|
||||
let group = entity.group;
|
||||
|
||||
let rotationBody = this.interpolateRotation(entity.prevRenderYawOffset, entity.renderYawOffset, partialTicks);
|
||||
@@ -32,19 +45,20 @@ window.EntityRenderer = class {
|
||||
|
||||
// Actual size of the entity
|
||||
let scale = 7.0 / 120.0;
|
||||
group.scale.set(scale, -scale, scale);
|
||||
group.scale.set(-scale,- scale, scale);
|
||||
|
||||
// Rotate entity model
|
||||
group.rotation.y = MathHelper.toRadians(-rotationBody + 180);
|
||||
|
||||
// Render entity model
|
||||
let timeAlive = entity.ticksExisted + partialTicks;
|
||||
this.model.render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch);
|
||||
this.model.render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch, partialTicks);
|
||||
}
|
||||
|
||||
interpolateRotation(prevValue, value, partialTicks) {
|
||||
let factor;
|
||||
for (factor = value - prevValue; factor < -180.0; factor += 360.0) {}
|
||||
for (factor = value - prevValue; factor < -180.0; factor += 360.0) {
|
||||
}
|
||||
while (factor >= 180.0) {
|
||||
factor -= 360.0;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,12 @@ window.PlayerRenderer = class extends EntityRenderer {
|
||||
}
|
||||
|
||||
rebuild(tessellator, entity) {
|
||||
tessellator.bindTexture(this.textureCharacter);
|
||||
this.tessellator.bindTexture(this.textureCharacter);
|
||||
super.rebuild(tessellator, entity);
|
||||
}
|
||||
|
||||
render(entity, partialTicks) {
|
||||
super.render(entity, partialTicks);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@ window.FontRenderer = class {
|
||||
constructor() {
|
||||
this.charWidths = [];
|
||||
|
||||
this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
||||
this.texture = Gui.loadTexture("gui/font.png")
|
||||
|
||||
let bitMap = this.createBitMap(this.texture);
|
||||
@@ -44,7 +45,9 @@ window.FontRenderer = class {
|
||||
}
|
||||
|
||||
drawString(stack, string, x, y, color = -1) {
|
||||
this.drawStringRaw(stack, string, x + 1, y + 1, (color & 0xFCFCFC) >> 2, true);
|
||||
if (!this.isSafari) { // TODO Fix brightness filter on Safari
|
||||
this.drawStringRaw(stack, string, x + 1, y + 1, (color & 0xFCFCFC) >> 2, true);
|
||||
}
|
||||
this.drawStringRaw(stack, string, x, y, color, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,18 +19,18 @@ window.ModelPlayer = class extends ModelBase {
|
||||
.setTextureOffset(16, 16)
|
||||
.setBox(-4.0, 0.0, -2.0, 8, 12, 4);
|
||||
|
||||
// Right arm ModelRenderer
|
||||
this.rightArm = new ModelRenderer(width, height)
|
||||
.setTextureOffset(40, 16)
|
||||
.setRotationPoint(-5.0, 2.0, 0.0)
|
||||
.setBox(-3.0, -2.0, -2.0, 4, 12, 4);
|
||||
|
||||
// Left arm ModelRenderer
|
||||
this.leftArm = new ModelRenderer(width, height)
|
||||
.setTextureOffset(40, 16)
|
||||
.setRotationPoint(5.0, 2.0, 0.0)
|
||||
.setRotationPoint(-5.0, 2.0, 0.0)
|
||||
.setBox(-1.0, -2.0, -2.0, 4, 12, 4);
|
||||
|
||||
// Right arm ModelRenderer
|
||||
this.rightArm = new ModelRenderer(width, height)
|
||||
.setTextureOffset(40, 16)
|
||||
.setRotationPoint(-3.0, 2.0, -2.0)
|
||||
.setBox(-3.0, -2.0, -2.0, 4, 12, 4);
|
||||
|
||||
// Right Legs ModelRenderer
|
||||
this.rightLeg = new ModelRenderer(width, height)
|
||||
.setTextureOffset(0, 16)
|
||||
@@ -55,7 +55,7 @@ window.ModelPlayer = class extends ModelBase {
|
||||
this.rightLeg.rebuild(tessellator, group);
|
||||
}
|
||||
|
||||
render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch) {
|
||||
render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch, partialTicks) {
|
||||
let group = entity.group;
|
||||
|
||||
this.head.rotateAngleY = MathHelper.toRadians(yaw);
|
||||
@@ -71,6 +71,40 @@ window.ModelPlayer = class extends ModelBase {
|
||||
|
||||
this.rightArm.rotateAngleY = 0.0;
|
||||
this.rightArm.rotateAngleZ = 0.0;
|
||||
this.leftArm.rotateAngleY = 0.0;
|
||||
|
||||
// Swing progress
|
||||
let swingProgress = entity.swingProgress - entity.prevSwingProgress;
|
||||
if (swingProgress < 0.0) {
|
||||
swingProgress++;
|
||||
}
|
||||
let interpolatedSwingProgress = entity.prevSwingProgress + swingProgress * partialTicks;
|
||||
if (interpolatedSwingProgress > -9990.0) {
|
||||
let swingProgress = interpolatedSwingProgress;
|
||||
|
||||
this.body.rotateAngleY = Math.sin(Math.sqrt(swingProgress) * Math.PI * 2.0) * 0.2;
|
||||
|
||||
this.rightArm.rotationPointZ = Math.sin(this.body.rotateAngleY) * 5.0;
|
||||
this.rightArm.rotationPointX = -Math.cos(this.body.rotateAngleY) * 5.0;
|
||||
this.leftArm.rotationPointZ = -Math.sin(this.body.rotateAngleY) * 5.0;
|
||||
this.leftArm.rotationPointX = Math.cos(this.body.rotateAngleY) * 5.0;
|
||||
|
||||
this.rightArm.rotateAngleY += this.body.rotateAngleY;
|
||||
this.leftArm.rotateAngleY += this.body.rotateAngleY;
|
||||
this.leftArm.rotateAngleX += this.body.rotateAngleY;
|
||||
|
||||
swingProgress = 1.0 - interpolatedSwingProgress;
|
||||
swingProgress = swingProgress * swingProgress;
|
||||
swingProgress = swingProgress * swingProgress;
|
||||
swingProgress = 1.0 - swingProgress;
|
||||
|
||||
let value1 = Math.sin(swingProgress * Math.PI);
|
||||
let value2 = Math.sin(interpolatedSwingProgress * Math.PI) * -(this.head.rotateAngleX - 0.7) * 0.75;
|
||||
|
||||
this.rightArm.rotateAngleX = (this.rightArm.rotateAngleX - (value1 * 1.2 + value2));
|
||||
this.rightArm.rotateAngleY += this.body.rotateAngleY * 2.0;
|
||||
this.rightArm.rotateAngleZ += Math.sin(interpolatedSwingProgress * Math.PI) * -0.4;
|
||||
}
|
||||
|
||||
if (entity.sneaking) {
|
||||
this.body.rotateAngleX = 0.5;
|
||||
|
||||
@@ -157,7 +157,7 @@ window.ModelRenderer = class {
|
||||
|
||||
this.bone.rotation.order = 'ZYX';
|
||||
this.bone.rotation.x = this.rotateAngleX;
|
||||
this.bone.rotation.y = -this.rotateAngleY;
|
||||
this.bone.rotation.y = this.rotateAngleY;
|
||||
this.bone.rotation.z = this.rotateAngleZ;
|
||||
|
||||
this.bone.updateMatrix();
|
||||
|
||||
@@ -21,9 +21,6 @@ window.Polygon = class {
|
||||
}
|
||||
|
||||
render(tessellator) {
|
||||
// Set color of polygon
|
||||
tessellator.setColor(1, 1, 1);
|
||||
|
||||
// Render all vertices
|
||||
for (let i = 3; i >= 0; i--) {
|
||||
let vertex = this.vertices[i];
|
||||
|
||||
@@ -15,6 +15,13 @@ window.World = class {
|
||||
|
||||
this.time = 0;
|
||||
|
||||
// Generate light brightness table
|
||||
this.lightBrightnessTable = [];
|
||||
for (let i = 0; i <= 15; i++) {
|
||||
let brightness = 1.0 - i / 15;
|
||||
this.lightBrightnessTable[i] = ((1.0 - brightness) / (brightness * 3 + 1.0)) * (1.0 - 0.05) + 0.05;
|
||||
}
|
||||
|
||||
// Load world
|
||||
this.generator = new WorldGenerator(this, Date.now() % 100000);
|
||||
|
||||
@@ -88,12 +95,12 @@ window.World = class {
|
||||
getCollisionBoxes(region) {
|
||||
let boundingBoxList = [];
|
||||
|
||||
let minX = MathHelper.floor_double(region.minX);
|
||||
let maxX = MathHelper.floor_double(region.maxX + 1.0);
|
||||
let minY = MathHelper.floor_double(region.minY);
|
||||
let maxY = MathHelper.floor_double(region.maxY + 1.0);
|
||||
let minZ = MathHelper.floor_double(region.minZ);
|
||||
let maxZ = MathHelper.floor_double(region.maxZ + 1.0);
|
||||
let minX = MathHelper.floor(region.minX);
|
||||
let maxX = MathHelper.floor(region.maxX + 1.0);
|
||||
let minY = MathHelper.floor(region.minY);
|
||||
let maxY = MathHelper.floor(region.maxY + 1.0);
|
||||
let minZ = MathHelper.floor(region.minZ);
|
||||
let maxZ = MathHelper.floor(region.maxZ + 1.0);
|
||||
|
||||
for (let x = minX; x < maxX; x++) {
|
||||
for (let y = minY; y < maxY; y++) {
|
||||
@@ -331,13 +338,13 @@ window.World = class {
|
||||
}
|
||||
|
||||
rayTraceBlocks(from, to) {
|
||||
let toX = MathHelper.floor_double(to.x);
|
||||
let toY = MathHelper.floor_double(to.y);
|
||||
let toZ = MathHelper.floor_double(to.z);
|
||||
let toX = MathHelper.floor(to.x);
|
||||
let toY = MathHelper.floor(to.y);
|
||||
let toZ = MathHelper.floor(to.z);
|
||||
|
||||
let x = MathHelper.floor_double(from.x);
|
||||
let y = MathHelper.floor_double(from.y);
|
||||
let z = MathHelper.floor_double(from.z);
|
||||
let x = MathHelper.floor(from.x);
|
||||
let y = MathHelper.floor(from.y);
|
||||
let z = MathHelper.floor(from.z);
|
||||
|
||||
let blockId = this.getBlockAt(x, y, z);
|
||||
let block = Block.getById(blockId);
|
||||
@@ -429,9 +436,9 @@ window.World = class {
|
||||
from = new Vector3(from.x + diffX * nearestZ, from.y + diffY * nearestZ, nearestZ1);
|
||||
}
|
||||
|
||||
x = MathHelper.floor_double(from.x) - (face === EnumBlockFace.EAST ? 1 : 0);
|
||||
y = MathHelper.floor_double(from.y) - (face === EnumBlockFace.TOP ? 1 : 0);
|
||||
z = MathHelper.floor_double(from.z) - (face === EnumBlockFace.SOUTH ? 1 : 0);
|
||||
x = MathHelper.floor(from.x) - (face === EnumBlockFace.EAST ? 1 : 0);
|
||||
y = MathHelper.floor(from.y) - (face === EnumBlockFace.TOP ? 1 : 0);
|
||||
z = MathHelper.floor(from.z) - (face === EnumBlockFace.SOUTH ? 1 : 0);
|
||||
|
||||
let blockId = this.getBlockAt(x, y, z);
|
||||
let block = Block.getById(blockId);
|
||||
@@ -480,6 +487,11 @@ window.World = class {
|
||||
return (Math.round(red * 255) << 16) | (Math.round(green * 255) << 8) | Math.round(blue * 255);
|
||||
}
|
||||
|
||||
getLightBrightness(x, y, z) {
|
||||
let level = this.getTotalLightAt(x, y, z);
|
||||
return this.lightBrightnessTable[level];
|
||||
}
|
||||
|
||||
getSkyColorByTemp(temperature) {
|
||||
temperature /= 3;
|
||||
if (temperature < -1) {
|
||||
@@ -506,13 +518,6 @@ window.World = class {
|
||||
addEntity(entity) {
|
||||
this.entities.push(entity);
|
||||
this.group.add(entity.group);
|
||||
|
||||
let tessellator = new Tessellator();
|
||||
|
||||
// Rebuild entity model
|
||||
let worldRenderer = this.minecraft.worldRenderer;
|
||||
let renderer = worldRenderer.entityRenderManager.getEntityRendererByEntity(entity);
|
||||
renderer.rebuild(tessellator, entity);
|
||||
}
|
||||
|
||||
removeEntityById(id) {
|
||||
|
||||
@@ -10,7 +10,7 @@ window.BoundingBox = class {
|
||||
* @param maxY Maximum y side
|
||||
* @param maxZ Maximum z side
|
||||
*/
|
||||
constructor(minX, minY, minZ, maxX, maxY, maxZ) {
|
||||
constructor(minX = 0, minY = 0, minZ = 0, maxX = 0, maxY = 0, maxZ = 0) {
|
||||
this.epsilon = 0.0;
|
||||
|
||||
this.minX = minX;
|
||||
|
||||
@@ -3,7 +3,7 @@ window.MathHelper = class {
|
||||
/**
|
||||
* Returns the greatest integer less than or equal to the double argument
|
||||
*/
|
||||
static floor_double(value) {
|
||||
static floor(value) {
|
||||
let i = parseInt(value);
|
||||
return value < i ? i - 1 : i;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user