diff --git a/src/js/net/minecraft/client/entity/Entity.js b/src/js/net/minecraft/client/entity/Entity.js index ba3bc0f..272958b 100644 --- a/src/js/net/minecraft/client/entity/Entity.js +++ b/src/js/net/minecraft/client/entity/Entity.js @@ -18,20 +18,20 @@ window.Entity = class { this.sneaking = false; - this.yaw = 0; - this.pitch = 0; - this.renderYawOffset = 0; + this.rotationYaw = 0; + this.rotationPitch = 0; this.prevX = 0; this.prevY = 0; this.prevZ = 0; - this.prevYaw = 0; - this.prevPitch = 0; - this.prevRenderYawOffset = 0; + this.prevRotationYaw = 0; + this.prevRotationPitch = 0; this.distanceWalked = 0; this.nextStepDistance = 1; + + this.ticksExisted = 0; } onUpdate() { @@ -43,8 +43,10 @@ window.Entity = class { this.prevY = this.y; this.prevZ = this.z; - this.prevPitch = this.pitch; - this.prevYaw = this.yaw; + this.prevRotationPitch = this.rotationPitch; + this.prevRotationYaw = this.rotationYaw; + + this.ticksExisted++; } } \ No newline at end of file diff --git a/src/js/net/minecraft/client/entity/EntityLiving.js b/src/js/net/minecraft/client/entity/EntityLiving.js index c7309e4..a92da71 100644 --- a/src/js/net/minecraft/client/entity/EntityLiving.js +++ b/src/js/net/minecraft/client/entity/EntityLiving.js @@ -9,19 +9,71 @@ window.EntityLiving = class extends Entity { this.moveForward = 0.0; this.moveStrafing = 0.0; + + this.swingProgress = 0; + + this.renderYawOffset = 0; + this.rotationYawHead = 0; + + this.prevRotationYawHead = 0; + this.prevRenderYawOffset = 0; + + this.limbSwing = 0; + this.limbSwingAmount = 0; + this.prevLimbSwingAmount = 0; } onUpdate() { super.onUpdate(); this.onLivingUpdate(); + let motionX = this.x - this.prevX; + let motionZ = this.z - this.prevZ; + + let bodyRotation = this.renderYawOffset; + + let distanceTravelled = motionX * motionX + motionZ * motionZ; + let distanceTravelledSqrt = 0.0; + + if (distanceTravelled > 0.0025000002) { + distanceTravelledSqrt = Math.sqrt(distanceTravelled) * 3.0; + bodyRotation = Math.atan2(motionZ, motionX) * 180.0 / Math.PI - 90.0; + } + + if (this.swingProgress > 0.0) { + bodyRotation = this.rotationYaw; + } + + // TODO handle travel distance + distanceTravelledSqrt = this.updateBodyRotation(bodyRotation, distanceTravelledSqrt); + + while (this.rotationYaw - this.prevRotationYaw < -180.0) { + this.prevRotationYaw -= 360.0; + } + while (this.rotationYaw - this.prevRotationYaw >= 180.0) { + this.prevRotationYaw += 360.0; + } + while (this.renderYawOffset - this.prevRenderYawOffset < -180.0) { this.prevRenderYawOffset -= 360.0; } - while (this.renderYawOffset - this.prevRenderYawOffset >= 180.0) { this.prevRenderYawOffset += 360.0; } + + while (this.rotationPitch - this.prevRotationPitch < -180.0) { + this.prevRotationPitch -= 360.0; + } + while (this.rotationPitch - this.prevRotationPitch >= 180.0) { + this.prevRotationPitch += 360.0; + } + + while (this.rotationYawHead - this.prevRotationYawHead < -180.0) { + this.prevRotationYawHead -= 360.0; + } + while (this.rotationYawHead - this.prevRotationYawHead >= 180.0) { + this.prevRotationYawHead += 360.0; + } } onLivingUpdate() { @@ -40,6 +92,8 @@ window.EntityLiving = class extends Entity { this.motionZ = 0.0; } + this.rotationYawHead = this.rotationYaw; + // Jump if (this.jumping) { if (this.isInWater()) { @@ -70,13 +124,60 @@ window.EntityLiving = class extends Entity { this.travel(moveForward, 0, moveStrafing); } } + + this.prevLimbSwingAmount = this.limbSwingAmount; + + let motionX = this.x - this.prevX; + let motionZ = this.z - this.prevZ; + + let distance = Math.sqrt(motionX * motionX + motionZ * motionZ) * 4.0; + if (distance > 1.0) { + distance = 1.0; + } + this.limbSwingAmount += (distance - this.limbSwingAmount) * 0.4; + this.limbSwing += this.limbSwingAmount; } onEntityUpdate() { this.prevRenderYawOffset = this.renderYawOffset; + this.prevRotationYawHead = this.rotationYawHead; super.onEntityUpdate(); + } + updateBodyRotation(bodyRotation, distanceTravelledSqrt) { + let bodyRotationDifference = MathHelper.wrapAngleTo180(bodyRotation - this.renderYawOffset); + this.renderYawOffset += bodyRotationDifference * 0.3; + + let yaw = MathHelper.wrapAngleTo180(this.rotationYaw - this.renderYawOffset); + let turn = yaw < -90.0 || yaw >= 90.0; + + if (yaw < -75.0) { + yaw = -75.0; + } + if (yaw >= 75.0) { + yaw = 75.0; + } + this.renderYawOffset = this.rotationYaw - yaw; + + if (yaw * yaw > 2500.0) { + this.renderYawOffset += yaw * 0.2; + } + if (turn) { + distanceTravelledSqrt *= -1.0; + } + return distanceTravelledSqrt; + } + + computeAngleWithBound(value, subtract, limit) { + let wrapped = MathHelper.wrapAngleTo180(value - subtract); + if (wrapped < -limit) { + wrapped = -limit; + } + if (wrapped >= limit) { + wrapped = limit; + } + return value - wrapped; } } \ No newline at end of file diff --git a/src/js/net/minecraft/client/entity/PlayerEntity.js b/src/js/net/minecraft/client/entity/PlayerEntity.js index f04ee02..f495538 100644 --- a/src/js/net/minecraft/client/entity/PlayerEntity.js +++ b/src/js/net/minecraft/client/entity/PlayerEntity.js @@ -51,15 +51,15 @@ window.PlayerEntity = class extends EntityLiving { } turn(motionX, motionY) { - this.yaw = this.yaw + motionX * 0.15; - this.pitch = this.pitch - motionY * 0.15; + this.rotationYaw = this.rotationYaw + motionX * 0.15; + this.rotationPitch = this.rotationPitch - motionY * 0.15; - if (this.pitch < -90.0) { - this.pitch = -90.0; + if (this.rotationPitch < -90.0) { + this.rotationPitch = -90.0; } - if (this.pitch > 90.0) { - this.pitch = 90.0; + if (this.rotationPitch > 90.0) { + this.rotationPitch = 90.0; } } @@ -131,7 +131,7 @@ window.PlayerEntity = class extends EntityLiving { this.motionY = 0.42; if (this.sprinting) { - let radiansYaw = MathHelper.toRadians(this.yaw + 180); + let radiansYaw = MathHelper.toRadians(this.rotationYaw + 180); this.motionX -= Math.sin(radiansYaw) * 0.2; this.motionZ += Math.cos(radiansYaw) * 0.2; } @@ -259,7 +259,7 @@ window.PlayerEntity = class extends EntityLiving { up = up * distance; forward = forward * distance; - let yawRadians = MathHelper.toRadians(this.yaw + 180); + let yawRadians = MathHelper.toRadians(this.rotationYaw + 180); let sin = Math.sin(yawRadians); let cos = Math.cos(yawRadians); @@ -469,7 +469,7 @@ window.PlayerEntity = class extends EntityLiving { */ getLook(partialTicks) { // TODO interpolation - return this.getVectorForRotation(this.pitch, this.yaw); + return this.getVectorForRotation(this.rotationPitch, this.rotationYaw); } /** diff --git a/src/js/net/minecraft/client/render/WorldRenderer.js b/src/js/net/minecraft/client/render/WorldRenderer.js index dadb557..3c76fb8 100644 --- a/src/js/net/minecraft/client/render/WorldRenderer.js +++ b/src/js/net/minecraft/client/render/WorldRenderer.js @@ -104,8 +104,8 @@ window.WorldRenderer = class { orientCamera(partialTicks) { let player = this.minecraft.player; - let rotationY = -MathHelper.toRadians(player.yaw + 180); - let rotationX = -MathHelper.toRadians(player.pitch); + let rotationY = -MathHelper.toRadians(player.rotationYaw + 180); + let rotationX = -MathHelper.toRadians(player.rotationPitch); // Position let x = player.prevX + (player.x - player.prevX) * partialTicks; @@ -116,8 +116,10 @@ window.WorldRenderer = class { let mode = this.minecraft.settings.thirdPersonView; if (mode !== 0) { // Flip for front view - if (mode === 2) { + let frontView = mode === 2; + if (frontView) { rotationY += Math.PI; + rotationX *= -1; } // Shift camera diff --git a/src/js/net/minecraft/client/render/entity/EntityRenderer.js b/src/js/net/minecraft/client/render/entity/EntityRenderer.js index 24cf50e..6bf70ba 100644 --- a/src/js/net/minecraft/client/render/entity/EntityRenderer.js +++ b/src/js/net/minecraft/client/render/entity/EntityRenderer.js @@ -11,9 +11,15 @@ window.EntityRenderer = class { render(entity, partialTicks) { let group = entity.group; - let rotationOffset = this.interpolateRotation(entity.prevRenderYawOffset, entity.renderYawOffset, partialTicks); + let rotationBody = this.interpolateRotation(entity.prevRenderYawOffset, entity.renderYawOffset, partialTicks); let rotationHead = this.interpolateRotation(entity.prevRotationYawHead, entity.rotationYawHead, partialTicks); + let limbSwing = entity.prevLimbSwingAmount + (entity.limbSwingAmount - entity.prevLimbSwingAmount) * partialTicks; + let limbSwingAmount = entity.limbSwing - entity.limbSwingAmount * (1.0 - partialTicks); + + let yaw = rotationHead - rotationBody; + let pitch = entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks; + // Interpolate entity position let interpolatedX = entity.prevX + (entity.x - entity.prevX) * partialTicks; let interpolatedY = entity.prevY + (entity.y - entity.prevY) * partialTicks; @@ -29,11 +35,11 @@ window.EntityRenderer = class { group.scale.set(scale, -scale, scale); // Rotate entity model - group.rotation.y = MathHelper.toRadians(-entity.yaw + 180); + group.rotation.y = MathHelper.toRadians(-rotationBody + 180); // Render entity model - let time = Date.now() / 100; - this.model.render(group, time); + let timeAlive = entity.ticksExisted + partialTicks; + this.model.render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch); } interpolateRotation(prevValue, value, partialTicks) { diff --git a/src/js/net/minecraft/client/render/model/ModelBase.js b/src/js/net/minecraft/client/render/model/ModelBase.js index af33133..3f1c7d0 100644 --- a/src/js/net/minecraft/client/render/model/ModelBase.js +++ b/src/js/net/minecraft/client/render/model/ModelBase.js @@ -10,14 +10,8 @@ window.ModelBase = class { } - /** - * Render the model - * - * @param group Group to render - * @param time Animation offset - */ - render(group, time) { - group.updateMatrix(); + render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch) { + entity.group.updateMatrix(); } } \ No newline at end of file diff --git a/src/js/net/minecraft/client/render/model/model/ModelPlayer.js b/src/js/net/minecraft/client/render/model/model/ModelPlayer.js index 238387c..1e6a338 100644 --- a/src/js/net/minecraft/client/render/model/model/ModelPlayer.js +++ b/src/js/net/minecraft/client/render/model/model/ModelPlayer.js @@ -22,25 +22,25 @@ window.ModelPlayer = class extends ModelBase { // Right arm ModelRenderer this.rightArm = new ModelRenderer(width, height) .setTextureOffset(40, 16) - .setPosition(-5.0, 2.0, 0.0) + .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) - .setPosition(5.0, 2.0, 0.0) + .setRotationPoint(5.0, 2.0, 0.0) .setBox(-1.0, -2.0, -2.0, 4, 12, 4); // Right Legs ModelRenderer this.rightLeg = new ModelRenderer(width, height) .setTextureOffset(0, 16) - .setPosition(-2.0, 12.0, 0.0) + .setRotationPoint(-2.0, 12.0, 0.0) .setBox(-2.0, 0.0, -2.0, 4, 12, 4); // Left leg ModelRenderer this.leftLeg = new ModelRenderer(width, height) .setTextureOffset(0, 16) - .setPosition(2.0, 12.0, 0.0) + .setRotationPoint(2.0, 12.0, 0.0) .setBox(-2.0, 0.0, -2.0, 4, 12, 4); } @@ -55,22 +55,47 @@ window.ModelPlayer = class extends ModelBase { this.rightLeg.rebuild(tessellator, group); } - /** - * Render the model - * - * @param group Group to update position and rotation of - * @param time Animation offset - */ - render(group, time) { - // Set rotation of cubes - this.head.yRotation = Math.sin(time * 0.83); - this.head.xRotation = Math.sin(time) * 0.8; - this.rightArm.xRotation = Math.sin(time * 0.6662 + Math.PI) * 2.0; - this.rightArm.zRotation = (Math.sin(time * 0.2312) + 1.0); - this.leftArm.xRotation = Math.sin(time * 0.6662) * 2.0; - this.leftArm.zRotation = (Math.sin(time * 0.2812) - 1.0); - this.rightLeg.xRotation = Math.sin(time * 0.6662) * 1.4; - this.leftLeg.xRotation = Math.sin(time * 0.6662 + Math.PI) * 1.4; + render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch) { + let group = entity.group; + + this.head.rotateAngleY = MathHelper.toRadians(yaw); + this.head.rotateAngleX = MathHelper.toRadians(pitch); + this.rightArm.rotateAngleX = Math.cos(limbSwingAmount * 0.6662 + Math.PI) * 2.0 * limbSwing * 0.5; + this.leftArm.rotateAngleX = Math.cos(limbSwingAmount * 0.6662) * 2.0 * limbSwing * 0.5; + this.rightArm.rotateAngleZ = 0.0; + this.leftArm.rotateAngleZ = 0.0; + this.rightLeg.rotateAngleX = Math.cos(limbSwingAmount * 0.6662) * 1.4 * limbSwing; + this.leftLeg.rotateAngleX = Math.cos(limbSwingAmount * 0.6662 + Math.PI) * 1.4 * limbSwing; + this.rightLeg.rotateAngleY = 0.0; + this.leftLeg.rotateAngleY = 0.0; + + this.rightArm.rotateAngleY = 0.0; + this.rightArm.rotateAngleZ = 0.0; + + if (entity.sneaking) { + this.body.rotateAngleX = 0.5; + this.rightArm.rotateAngleX += 0.4; + this.leftArm.rotateAngleX += 0.4; + this.rightLeg.rotationPointZ = 4.0; + this.leftLeg.rotationPointZ = 4.0; + this.rightLeg.rotationPointY = 9.0; + this.leftLeg.rotationPointY = 9.0; + this.head.rotationPointY = 1.0; + + group.translateY(-0.2); + } else { + this.body.rotateAngleX = 0.0; + this.rightLeg.rotationPointZ = 0.1; + this.leftLeg.rotationPointZ = 0.1; + this.rightLeg.rotationPointY = 12.0; + this.leftLeg.rotationPointY = 12.0; + this.head.rotationPointY = 0.0; + } + + this.rightArm.rotateAngleZ += Math.cos(timeAlive * 0.09) * 0.05 + 0.05; + this.leftArm.rotateAngleZ -= Math.cos(timeAlive * 0.09) * 0.05 + 0.05; + this.rightArm.rotateAngleX += Math.sin(timeAlive * 0.067) * 0.05; + this.leftArm.rotateAngleX -= Math.sin(timeAlive * 0.067) * 0.05; // Render cubes this.head.render(group); @@ -80,7 +105,7 @@ window.ModelPlayer = class extends ModelBase { this.rightLeg.render(group); this.leftLeg.render(group); - super.render(group, time); + super.render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch); } } \ No newline at end of file diff --git a/src/js/net/minecraft/client/render/model/renderer/ModelRenderer.js b/src/js/net/minecraft/client/render/model/renderer/ModelRenderer.js index d9ccb51..04a11c5 100644 --- a/src/js/net/minecraft/client/render/model/renderer/ModelRenderer.js +++ b/src/js/net/minecraft/client/render/model/renderer/ModelRenderer.js @@ -10,13 +10,13 @@ window.ModelRenderer = class { this.textureOffsetX = 0; this.textureOffsetY = 0; - this.xRotation = 0; - this.yRotation = 0; - this.zRotation = 0; + this.rotateAngleX = 0; + this.rotateAngleY = 0; + this.rotateAngleZ = 0; - this.x = 0; - this.y = 0; - this.z = 0; + this.rotationPointX = 0; + this.rotationPointY = 0; + this.rotationPointZ = 0; this.bone = new THREE.Object3D(); } @@ -128,10 +128,10 @@ window.ModelRenderer = class { * @param y Absolute y position of cube * @param z Absolute z position of cube */ - setPosition(x, y, z) { - this.x = x; - this.y = y; - this.z = z; + setRotationPoint(x, y, z) { + this.rotationPointX = x; + this.rotationPointY = y; + this.rotationPointZ = z; return this; } @@ -151,14 +151,14 @@ window.ModelRenderer = class { } render(group) { - this.bone.position.setX(this.x); - this.bone.position.setY(this.y); - this.bone.position.setZ(this.z); + this.bone.position.setX(this.rotationPointX); + this.bone.position.setY(this.rotationPointY); + this.bone.position.setZ(this.rotationPointZ); this.bone.rotation.order = 'ZYX'; - this.bone.rotation.x = this.xRotation; - this.bone.rotation.y = this.yRotation; - this.bone.rotation.z = this.zRotation; + this.bone.rotation.x = this.rotateAngleX; + this.bone.rotation.y = -this.rotateAngleY; + this.bone.rotation.z = this.rotateAngleZ; this.bone.updateMatrix(); } diff --git a/src/js/net/minecraft/util/MathHelper.js b/src/js/net/minecraft/util/MathHelper.js index ccc4041..7d598a0 100644 --- a/src/js/net/minecraft/util/MathHelper.js +++ b/src/js/net/minecraft/util/MathHelper.js @@ -33,6 +33,17 @@ window.MathHelper = class { return angle; } + static wrapAngleTo180(value) { + value = value % 360.0; + if (value >= 180.0) { + value -= 360.0; + } + if (value < -180.0) { + value += 360.0; + } + return value; + } + static hsbToRgb(hue, saturation, brightness) { let r = 0, g = 0, b = 0; if (saturation === 0) {