diff --git a/examples/index.html b/examples/index.html index 0e0e12e..7287d78 100644 --- a/examples/index.html +++ b/examples/index.html @@ -128,11 +128,12 @@
-

Walk / Run

+

Walk / Run / Fly

+
@@ -260,7 +261,8 @@ const skinLayers = ["innerLayer", "outerLayer"]; const availableAnimations = { walk: skinview3d.WalkingAnimation, - run: skinview3d.RunningAnimation + run: skinview3d.RunningAnimation, + fly: skinview3d.FlyingAnimation }; let skinViewer; diff --git a/src/animation.ts b/src/animation.ts index 872a25d..8971dd8 100644 --- a/src/animation.ts +++ b/src/animation.ts @@ -195,3 +195,30 @@ export const RunningAnimation: Animation = (player, time) => { export const RotatingAnimation: Animation = (player, time) => { player.rotation.y = time; }; + +function clamp(num: number, min: number, max: number): number { + return num <= min ? min : num >= max ? max : num; +} + +export const FlyingAnimation: Animation = (player, time) => { + // body rotation finishes in 0.5s + // elytra expansion finishes in 3.3s + + if (time < 0) time = 0; + time *= 20; + const startProgress = clamp((time * time) / 100, 0, 1); + + player.rotation.x = startProgress * Math.PI / 2; + player.skin.head.rotation.x = startProgress > .5 ? Math.PI / 4 - player.rotation.x : 0; + + const basicArmRotationZ = Math.PI * .25 * startProgress; + player.skin.leftArm.rotation.z = basicArmRotationZ; + player.skin.rightArm.rotation.z = -basicArmRotationZ; + + const elytraRotationX = .34906584; + const elytraRotationZ = Math.PI / 2; + const interpolation = Math.pow(.9, time); + player.elytra.leftWing.rotation.x = elytraRotationX + interpolation * (.2617994 - elytraRotationX); + player.elytra.leftWing.rotation.z = elytraRotationZ + interpolation * (.2617994 - elytraRotationZ); + player.elytra.updateRightWing(); +};