minecraft-renderer 0.1.64 → 0.1.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/minecraft-renderer.js +60 -60
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +411 -411
- package/package.json +1 -1
- package/src/three/entities.ts +39 -160
- package/src/three/entity/animations.js +92 -185
package/package.json
CHANGED
package/src/three/entities.ts
CHANGED
|
@@ -45,14 +45,6 @@ export const TWEEN_DURATION = 120
|
|
|
45
45
|
|
|
46
46
|
const degreesToRadians = (degrees: number) => degrees * (Math.PI / 180)
|
|
47
47
|
|
|
48
|
-
const clamp01 = (v: number) => Math.max(0, Math.min(1, v))
|
|
49
|
-
const clamp = (v: number, a: number, b: number) => Math.max(a, Math.min(b, v))
|
|
50
|
-
const wrapPi = (a: number) => {
|
|
51
|
-
a = (a + Math.PI) % (Math.PI * 2)
|
|
52
|
-
if (a < 0) a += Math.PI * 2
|
|
53
|
-
return a - Math.PI
|
|
54
|
-
}
|
|
55
|
-
|
|
56
48
|
function convert2sComplementToHex(complement: number) {
|
|
57
49
|
if (complement < 0) {
|
|
58
50
|
complement = (0xFF_FF_FF_FF + complement + 1) >>> 0
|
|
@@ -280,130 +272,45 @@ export class Entities {
|
|
|
280
272
|
pendingModelOverrides = new Map<string, { parts: EntityModelOverridePart[] }>()
|
|
281
273
|
|
|
282
274
|
private motionCache = new Map<string, { pos: THREE.Vector3, speed: number }>()
|
|
283
|
-
private
|
|
275
|
+
private readonly MOVE_ON = 0.05
|
|
276
|
+
private readonly MOVE_OFF = 0.02
|
|
277
|
+
private readonly RUN_ON = 4.8
|
|
278
|
+
private readonly RUN_OFF = 4.2
|
|
284
279
|
|
|
285
|
-
private
|
|
286
|
-
private _tpHasBodyYaw = false
|
|
287
|
-
|
|
288
|
-
private updateAutoWalkFlags(entityKey: string, entity: SceneEntity, dt: number, samplePos?: THREE.Vector3) {
|
|
280
|
+
private updateAutoWalkFlags(entityKey: string, entity: SceneEntity, dt: number) {
|
|
289
281
|
if (!entity.playerObject?.animation) return
|
|
290
282
|
const anim: any = entity.playerObject.animation
|
|
283
|
+
if (!('isMoving' in anim) || !('isRunning' in anim)) return
|
|
291
284
|
if (dt <= 0) return
|
|
292
285
|
|
|
293
|
-
const pos = samplePos ?? entity.position
|
|
294
|
-
|
|
295
286
|
const cached = this.motionCache.get(entityKey)
|
|
296
287
|
if (!cached) {
|
|
297
|
-
this.motionCache.set(entityKey, { pos:
|
|
288
|
+
this.motionCache.set(entityKey, { pos: entity.position.clone(), speed: 0 })
|
|
298
289
|
anim.isMoving = false
|
|
299
290
|
anim.isRunning = false
|
|
300
|
-
anim.moveAmount = 0
|
|
301
|
-
anim.runAmount = 0
|
|
302
291
|
return
|
|
303
292
|
}
|
|
304
293
|
|
|
305
|
-
const dx =
|
|
306
|
-
const dz =
|
|
307
|
-
cached.pos.copy(
|
|
294
|
+
const dx = entity.position.x - cached.pos.x
|
|
295
|
+
const dz = entity.position.z - cached.pos.z
|
|
296
|
+
cached.pos.copy(entity.position)
|
|
308
297
|
|
|
309
|
-
const instSpeed = Math.hypot(dx, dz) / Math.max(dt, 1e-6)
|
|
298
|
+
const instSpeed = Math.hypot(dx, dz) / Math.max(dt, 1e-6)
|
|
310
299
|
|
|
311
|
-
|
|
312
|
-
cached.speed += (instSpeed - cached.speed) * alpha
|
|
313
|
-
|
|
314
|
-
const speed = cached.speed
|
|
315
|
-
|
|
316
|
-
const smoothstep = (a: number, b: number, x: number) => {
|
|
317
|
-
const t = clamp01((x - a) / (b - a))
|
|
318
|
-
return t * t * (3 - 2 * t)
|
|
319
|
-
}
|
|
300
|
+
cached.speed = cached.speed * 0.8 + instSpeed * 0.2
|
|
320
301
|
|
|
321
|
-
const
|
|
322
|
-
|
|
302
|
+
const movingNow = anim.isMoving
|
|
303
|
+
? cached.speed > this.MOVE_OFF
|
|
304
|
+
: cached.speed > this.MOVE_ON
|
|
323
305
|
|
|
324
|
-
const
|
|
325
|
-
|
|
306
|
+
const runningNow = anim.isRunning
|
|
307
|
+
? cached.speed > this.RUN_OFF
|
|
308
|
+
: cached.speed > this.RUN_ON
|
|
326
309
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
anim.moveAmount = moveAmount
|
|
331
|
-
anim.runAmount = runAmount
|
|
332
|
-
|
|
333
|
-
anim.isMoving = moveAmount > 0.15
|
|
334
|
-
anim.isRunning = runAmount > 0.55
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
private getLocalSneak(): boolean {
|
|
338
|
-
const ps: any = this.worldRenderer.playerStateReactive as any
|
|
339
|
-
return (
|
|
340
|
-
ps?.movementState === 'SNEAKING' ||
|
|
341
|
-
ps?.movementState === 'CROUCHING' ||
|
|
342
|
-
!!ps?.isSneaking ||
|
|
343
|
-
!!ps?.sneaking ||
|
|
344
|
-
!!ps?.isCrouching ||
|
|
345
|
-
!!ps?.crouching ||
|
|
346
|
-
!!ps?.controls?.sneak ||
|
|
347
|
-
!!ps?.controlState?.sneak
|
|
348
|
-
)
|
|
310
|
+
anim.isMoving = movingNow
|
|
311
|
+
anim.isRunning = movingNow && runningNow
|
|
349
312
|
}
|
|
350
313
|
|
|
351
|
-
private updateThirdPersonHeadAndBody(entity: SceneEntity, dt: number) {
|
|
352
|
-
const anim: any = entity.playerObject?.animation
|
|
353
|
-
const rotation = this.worldRenderer.cameraShake.getBaseRotation()
|
|
354
|
-
|
|
355
|
-
const camYaw = rotation.yaw
|
|
356
|
-
const camPitch = rotation.pitch
|
|
357
|
-
|
|
358
|
-
const move = clamp01(anim?.moveAmount ?? (anim?.isMoving ? 1 : 0))
|
|
359
|
-
const run = clamp01(anim?.runAmount ?? (anim?.isRunning ? 1 : 0))
|
|
360
|
-
const moving = move > 0.15
|
|
361
|
-
|
|
362
|
-
if (!this._tpHasBodyYaw) {
|
|
363
|
-
this._tpHasBodyYaw = true
|
|
364
|
-
this._tpBodyYaw = camYaw
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
if (moving) {
|
|
368
|
-
const k = 1 - Math.exp(-dt * (18 + 10 * run))
|
|
369
|
-
this._tpBodyYaw = this._tpBodyYaw + wrapPi(camYaw - this._tpBodyYaw) * k
|
|
370
|
-
|
|
371
|
-
entity.rotation.set(0, this._tpBodyYaw, 0)
|
|
372
|
-
|
|
373
|
-
const headMax = ((25 - 8 * run) * Math.PI) / 180
|
|
374
|
-
const headYaw = clamp(wrapPi(camYaw - this._tpBodyYaw), -headMax, headMax)
|
|
375
|
-
|
|
376
|
-
if (anim && 'lookYaw' in anim) anim.lookYaw = headYaw
|
|
377
|
-
if (anim && 'lookPitch' in anim) anim.lookPitch = -camPitch
|
|
378
|
-
return
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// idle behavior (head leads, body follows after threshold)
|
|
382
|
-
const maxHeadYaw = (85 * Math.PI) / 180
|
|
383
|
-
const bodyFollowStart = (55 * Math.PI) / 180
|
|
384
|
-
|
|
385
|
-
let desiredHeadYaw = wrapPi(camYaw - this._tpBodyYaw)
|
|
386
|
-
desiredHeadYaw = clamp(desiredHeadYaw, -maxHeadYaw, maxHeadYaw)
|
|
387
|
-
|
|
388
|
-
const excess = Math.abs(desiredHeadYaw) - bodyFollowStart
|
|
389
|
-
if (excess > 0) {
|
|
390
|
-
const push = excess / (maxHeadYaw - bodyFollowStart)
|
|
391
|
-
const targetBodyYaw = camYaw - Math.sign(desiredHeadYaw) * bodyFollowStart
|
|
392
|
-
const k = 1 - Math.exp(-dt * (6 + 10 * push))
|
|
393
|
-
this._tpBodyYaw = this._tpBodyYaw + wrapPi(targetBodyYaw - this._tpBodyYaw) * k
|
|
394
|
-
desiredHeadYaw = wrapPi(camYaw - this._tpBodyYaw)
|
|
395
|
-
desiredHeadYaw = clamp(desiredHeadYaw, -maxHeadYaw, maxHeadYaw)
|
|
396
|
-
} else {
|
|
397
|
-
const k = 1 - Math.exp(-dt * 5)
|
|
398
|
-
this._tpBodyYaw = this._tpBodyYaw + wrapPi(camYaw - this._tpBodyYaw) * (k * 0.15)
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
entity.rotation.set(0, this._tpBodyYaw, 0)
|
|
402
|
-
if (anim && 'lookYaw' in anim) anim.lookYaw = desiredHeadYaw
|
|
403
|
-
if (anim && 'lookPitch' in anim) anim.lookPitch = -camPitch
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
|
|
407
314
|
get entitiesByName(): Record<string, SceneEntity[]> {
|
|
408
315
|
const byName: Record<string, SceneEntity[]> = {}
|
|
409
316
|
for (const entity of Object.values(this.entities)) {
|
|
@@ -477,8 +384,6 @@ export class Entities {
|
|
|
477
384
|
this.currentSkinUrls = {}
|
|
478
385
|
|
|
479
386
|
this.motionCache.clear()
|
|
480
|
-
this._wasThirdPerson = false
|
|
481
|
-
this._tpHasBodyYaw = false
|
|
482
387
|
|
|
483
388
|
// Clean up player entity
|
|
484
389
|
if (this.playerEntity) {
|
|
@@ -547,93 +452,67 @@ export class Entities {
|
|
|
547
452
|
const botPos = this.worldRenderer.viewerChunkPosition
|
|
548
453
|
const VISIBLE_DISTANCE = 10 * 10
|
|
549
454
|
|
|
550
|
-
const thirdPersonNow = this.worldRenderer.playerStateUtils.isThirdPerson()
|
|
551
|
-
if (thirdPersonNow !== this._wasThirdPerson) {
|
|
552
|
-
this._wasThirdPerson = thirdPersonNow
|
|
553
|
-
const key = String(this.playerEntity?.originalEntity.id ?? 'player_entity')
|
|
554
|
-
this.motionCache.delete(key)
|
|
555
|
-
|
|
556
|
-
const anim: any = this.playerEntity?.playerObject?.animation
|
|
557
|
-
if (anim?.resetLocomotion) anim.resetLocomotion()
|
|
558
|
-
|
|
559
|
-
this._tpHasBodyYaw = false
|
|
560
|
-
}
|
|
561
|
-
|
|
562
455
|
for (const [entityIdRaw, entity] of [...Object.entries(this.entities), ['player_entity', this.playerEntity] as [string, SceneEntity | null]]) {
|
|
563
456
|
if (!entity) continue
|
|
564
457
|
|
|
458
|
+
let entityKey = entityIdRaw
|
|
565
459
|
const isPlayerEntity = entityIdRaw === 'player_entity'
|
|
566
|
-
const entityKey = isPlayerEntity ? String(this.playerEntity?.originalEntity.id ?? 'player_entity') : String(entityIdRaw)
|
|
567
460
|
|
|
568
461
|
if (isPlayerEntity) {
|
|
569
|
-
|
|
462
|
+
const thirdPerson = this.worldRenderer.playerStateUtils.isThirdPerson()
|
|
463
|
+
entity.visible = thirdPerson
|
|
570
464
|
|
|
571
|
-
if (
|
|
465
|
+
if (thirdPerson) {
|
|
572
466
|
const yOffset = this.worldRenderer.playerStateReactive.eyeHeight
|
|
573
|
-
// Set world position — proxy auto-converts to scene coords
|
|
574
467
|
entity.position.set(
|
|
575
468
|
this.worldRenderer.cameraWorldPos.x,
|
|
576
469
|
this.worldRenderer.cameraWorldPos.y - yOffset,
|
|
577
470
|
this.worldRenderer.cameraWorldPos.z
|
|
578
471
|
)
|
|
579
|
-
|
|
580
|
-
const p: any = (this.worldRenderer.playerStateReactive as any).position
|
|
581
|
-
if (p && typeof p.x === 'number') {
|
|
582
|
-
this.updateAutoWalkFlags(entityKey, entity, dtRaw, new THREE.Vector3(p.x, p.y, p.z))
|
|
583
|
-
} else {
|
|
584
|
-
const wp = this.worldRenderer.sceneOrigin.getWorldPosition(entity)
|
|
585
|
-
this.updateAutoWalkFlags(entityKey, entity, dtRaw, wp ? new THREE.Vector3(wp.x, wp.y, wp.z) : entity.position)
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
this.updateThirdPersonHeadAndBody(entity, dt)
|
|
589
|
-
} else {
|
|
590
|
-
const wp = this.worldRenderer.sceneOrigin.getWorldPosition(entity)
|
|
591
|
-
this.updateAutoWalkFlags(entityKey, entity, dtRaw, wp ? new THREE.Vector3(wp.x, wp.y, wp.z) : entity.position)
|
|
592
472
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
this.updateAutoWalkFlags(entityKey, entity, dtRaw, wp ? new THREE.Vector3(wp.x, wp.y, wp.z) : entity.position)
|
|
473
|
+
|
|
474
|
+
entityKey = String(this.playerEntity?.originalEntity.id ?? 'player_entity')
|
|
596
475
|
}
|
|
597
476
|
|
|
598
477
|
const { playerObject } = entity
|
|
599
478
|
|
|
600
|
-
|
|
601
|
-
const anim: any = playerObject.animation
|
|
602
|
-
|
|
603
|
-
const flags = Number((entity.originalEntity?.metadata?.[0] ?? 0))
|
|
604
|
-
const remoteSneak = (flags & 0x02) !== 0
|
|
605
|
-
|
|
606
|
-
const localSneak = this.getLocalSneak()
|
|
607
|
-
|
|
608
|
-
if ('isCrouched' in anim) anim.isCrouched = isPlayerEntity ? localSneak : remoteSneak
|
|
479
|
+
this.updateAutoWalkFlags(entityKey, entity, dtRaw)
|
|
609
480
|
|
|
481
|
+
if (playerObject?.animation) {
|
|
610
482
|
playerObject.animation.update(playerObject, dt)
|
|
611
483
|
}
|
|
612
484
|
|
|
613
|
-
// Update GLTF animations
|
|
614
485
|
entity.traverse(child => {
|
|
615
486
|
if (child instanceof Entity.EntityMesh) {
|
|
616
487
|
child.update(dt)
|
|
617
488
|
}
|
|
618
489
|
})
|
|
619
490
|
|
|
620
|
-
// Update visibility based on distance and chunk load status
|
|
621
491
|
if (!isPlayerEntity && botPos && entity.position) {
|
|
622
492
|
const dx = entity.position.x - botPos.x
|
|
623
493
|
const dy = entity.position.y - botPos.y
|
|
624
494
|
const dz = entity.position.z - botPos.z
|
|
625
495
|
const distanceSquared = dx * dx + dy * dy + dz * dz
|
|
626
496
|
|
|
627
|
-
// Entity is visible if within 20 blocks OR in a finished chunk
|
|
628
497
|
entity.visible = !!(distanceSquared < VISIBLE_DISTANCE || this.worldRenderer.shouldObjectVisible(entity))
|
|
629
498
|
|
|
630
499
|
this.maybeRenderPlayerSkin(entityIdRaw)
|
|
631
500
|
}
|
|
632
501
|
|
|
633
502
|
if (entity.visible) {
|
|
634
|
-
// Update armor positions
|
|
635
503
|
this.syncArmorPositions(entity)
|
|
636
504
|
}
|
|
505
|
+
|
|
506
|
+
if (isPlayerEntity && entity.visible) {
|
|
507
|
+
const rotation = this.worldRenderer.cameraShake.getBaseRotation()
|
|
508
|
+
entity.rotation.set(0, rotation.yaw, 0)
|
|
509
|
+
|
|
510
|
+
entity.traverse((c) => {
|
|
511
|
+
if (c.name === 'head') {
|
|
512
|
+
c.rotation.set(-rotation.pitch, 0, 0)
|
|
513
|
+
}
|
|
514
|
+
})
|
|
515
|
+
}
|
|
637
516
|
}
|
|
638
517
|
}
|
|
639
518
|
|
|
@@ -2,27 +2,7 @@
|
|
|
2
2
|
import { PlayerAnimation } from 'skinview3d'
|
|
3
3
|
|
|
4
4
|
const clamp01 = (v) => Math.max(0, Math.min(1, v))
|
|
5
|
-
const clamp = (v, a, b) => Math.max(a, Math.min(b, v))
|
|
6
5
|
const mix = (a, b, t) => a + (b - a) * t
|
|
7
|
-
const wrapPi = (a) => {
|
|
8
|
-
a = (a + Math.PI) % (Math.PI * 2)
|
|
9
|
-
if (a < 0) a += Math.PI * 2
|
|
10
|
-
return a - Math.PI
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {{
|
|
15
|
-
* playerRot: any,
|
|
16
|
-
* bodyPos: any, bodyRot: any,
|
|
17
|
-
* leftArmPos: any, leftArmRot: any,
|
|
18
|
-
* rightArmPos: any, rightArmRot: any,
|
|
19
|
-
* leftLegPos: any, leftLegRot: any,
|
|
20
|
-
* rightLegPos: any, rightLegRot: any,
|
|
21
|
-
* headPos: any, headRot: any,
|
|
22
|
-
* capePos: any, capeRot: any,
|
|
23
|
-
* elytraPos: any, elytraRot: any,
|
|
24
|
-
* }} Defaults
|
|
25
|
-
*/
|
|
26
6
|
|
|
27
7
|
function updateElytraRightWing(player) {
|
|
28
8
|
const elytra = player?.elytra
|
|
@@ -53,32 +33,24 @@ export class WalkingGeneralSwing extends PlayerAnimation {
|
|
|
53
33
|
isMoving = true
|
|
54
34
|
isCrouched = false
|
|
55
35
|
|
|
56
|
-
/** @type {number} 0..1 */
|
|
57
|
-
moveAmount = 0
|
|
58
|
-
/** @type {number} 0..1 */
|
|
59
|
-
runAmount = 0
|
|
60
|
-
|
|
61
|
-
/** @type {number} radians */
|
|
62
|
-
lookYaw = 0
|
|
63
|
-
/** @type {number} radians */
|
|
64
|
-
lookPitch = 0
|
|
65
|
-
|
|
66
36
|
_dt = 0
|
|
67
37
|
_phase = 0
|
|
68
|
-
_idlePhase = 0
|
|
69
|
-
|
|
70
38
|
_moveBlend = 0
|
|
71
|
-
_runBlend = 0
|
|
72
|
-
_crouchBlend = 0
|
|
73
|
-
|
|
74
|
-
_lookYawBlend = 0
|
|
75
|
-
_lookPitchBlend = 0
|
|
76
39
|
|
|
77
40
|
/** @type {number | null} */
|
|
78
41
|
_swingTime = null
|
|
79
42
|
_swingDuration = 0.25
|
|
80
43
|
|
|
81
|
-
/** @type {
|
|
44
|
+
/** @type {{
|
|
45
|
+
bodyPos: any, bodyRot: any,
|
|
46
|
+
leftArmPos: any, leftArmRot: any,
|
|
47
|
+
rightArmPos: any, rightArmRot: any,
|
|
48
|
+
leftLegPos: any, leftLegRot: any,
|
|
49
|
+
rightLegPos: any, rightLegRot: any,
|
|
50
|
+
headPos: any, headRot: any,
|
|
51
|
+
capePos: any, capeRot: any,
|
|
52
|
+
elytraPos: any, elytraRot: any,
|
|
53
|
+
} | null} */
|
|
82
54
|
_defaults = null
|
|
83
55
|
|
|
84
56
|
update(player, delta) {
|
|
@@ -96,39 +68,29 @@ export class WalkingGeneralSwing extends PlayerAnimation {
|
|
|
96
68
|
}
|
|
97
69
|
}
|
|
98
70
|
|
|
99
|
-
resetLocomotion() {
|
|
100
|
-
this._moveBlend = 0
|
|
101
|
-
this._runBlend = 0
|
|
102
|
-
this._crouchBlend = 0
|
|
103
|
-
this._phase = 0
|
|
104
|
-
}
|
|
105
|
-
|
|
106
71
|
_captureDefaults(player) {
|
|
107
|
-
const skin = player?.skin
|
|
108
72
|
this._defaults = {
|
|
109
|
-
|
|
73
|
+
bodyPos: player.skin.body.position.clone(),
|
|
74
|
+
bodyRot: player.skin.body.rotation.clone(),
|
|
110
75
|
|
|
111
|
-
|
|
112
|
-
|
|
76
|
+
leftArmPos: player.skin.leftArm.position.clone(),
|
|
77
|
+
leftArmRot: player.skin.leftArm.rotation.clone(),
|
|
78
|
+
rightArmPos: player.skin.rightArm.position.clone(),
|
|
79
|
+
rightArmRot: player.skin.rightArm.rotation.clone(),
|
|
113
80
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
81
|
+
leftLegPos: player.skin.leftLeg.position.clone(),
|
|
82
|
+
leftLegRot: player.skin.leftLeg.rotation.clone(),
|
|
83
|
+
rightLegPos: player.skin.rightLeg.position.clone(),
|
|
84
|
+
rightLegRot: player.skin.rightLeg.rotation.clone(),
|
|
118
85
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
rightLegPos: skin?.rightLeg?.position?.clone?.(),
|
|
122
|
-
rightLegRot: skin?.rightLeg?.rotation?.clone?.(),
|
|
86
|
+
headPos: player.skin.head.position.clone(),
|
|
87
|
+
headRot: player.skin.head.rotation.clone(),
|
|
123
88
|
|
|
124
|
-
|
|
125
|
-
|
|
89
|
+
capePos: player.cape.position.clone(),
|
|
90
|
+
capeRot: player.cape.rotation.clone(),
|
|
126
91
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
elytraPos: player?.elytra?.position?.clone?.(),
|
|
131
|
-
elytraRot: player?.elytra?.rotation?.clone?.(),
|
|
92
|
+
elytraPos: player.elytra.position.clone(),
|
|
93
|
+
elytraRot: player.elytra.rotation.clone(),
|
|
132
94
|
}
|
|
133
95
|
}
|
|
134
96
|
|
|
@@ -136,152 +98,102 @@ export class WalkingGeneralSwing extends PlayerAnimation {
|
|
|
136
98
|
const d = this._defaults
|
|
137
99
|
if (!d) return
|
|
138
100
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const elytra = player?.elytra
|
|
142
|
-
|
|
143
|
-
if (d.playerRot && player?.rotation) player.rotation.copy(d.playerRot)
|
|
101
|
+
player.skin.body.position.copy(d.bodyPos)
|
|
102
|
+
player.skin.body.rotation.copy(d.bodyRot)
|
|
144
103
|
|
|
145
|
-
|
|
146
|
-
|
|
104
|
+
player.skin.leftArm.position.copy(d.leftArmPos)
|
|
105
|
+
player.skin.leftArm.rotation.copy(d.leftArmRot)
|
|
106
|
+
player.skin.rightArm.position.copy(d.rightArmPos)
|
|
107
|
+
player.skin.rightArm.rotation.copy(d.rightArmRot)
|
|
147
108
|
|
|
148
|
-
|
|
149
|
-
|
|
109
|
+
player.skin.leftLeg.position.copy(d.leftLegPos)
|
|
110
|
+
player.skin.leftLeg.rotation.copy(d.leftLegRot)
|
|
111
|
+
player.skin.rightLeg.position.copy(d.rightLegPos)
|
|
112
|
+
player.skin.rightLeg.rotation.copy(d.rightLegRot)
|
|
150
113
|
|
|
151
|
-
|
|
152
|
-
|
|
114
|
+
player.skin.head.position.copy(d.headPos)
|
|
115
|
+
player.skin.head.rotation.copy(d.headRot)
|
|
153
116
|
|
|
154
|
-
|
|
155
|
-
|
|
117
|
+
player.cape.position.copy(d.capePos)
|
|
118
|
+
player.cape.rotation.copy(d.capeRot)
|
|
156
119
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if (d.headPos && skin?.head?.position) skin.head.position.copy(d.headPos)
|
|
161
|
-
if (d.headRot && skin?.head?.rotation) skin.head.rotation.copy(d.headRot)
|
|
162
|
-
|
|
163
|
-
if (d.capePos && cape?.position) cape.position.copy(d.capePos)
|
|
164
|
-
if (d.capeRot && cape?.rotation) cape.rotation.copy(d.capeRot)
|
|
165
|
-
|
|
166
|
-
if (d.elytraPos && elytra?.position) elytra.position.copy(d.elytraPos)
|
|
167
|
-
if (d.elytraRot && elytra?.rotation) elytra.rotation.copy(d.elytraRot)
|
|
120
|
+
player.elytra.position.copy(d.elytraPos)
|
|
121
|
+
player.elytra.rotation.copy(d.elytraRot)
|
|
168
122
|
}
|
|
169
123
|
|
|
170
124
|
animate(player) {
|
|
171
125
|
const dt = this._dt || 0
|
|
126
|
+
|
|
172
127
|
if (!this._defaults) this._captureDefaults(player)
|
|
173
128
|
this._applyDefaults(player)
|
|
174
129
|
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
const targetMove = clamp01(externalMove)
|
|
179
|
-
const targetRun = clamp01(externalRun)
|
|
180
|
-
const targetCrouch = this.isCrouched ? 1 : 0
|
|
181
|
-
|
|
182
|
-
const kMove = Math.min(1, dt * 8)
|
|
183
|
-
const kRun = Math.min(1, dt * 6)
|
|
184
|
-
const kCrouch = Math.min(1, dt * 7)
|
|
185
|
-
|
|
130
|
+
const targetMove = this.isMoving ? 1 : 0
|
|
131
|
+
const kMove = Math.min(1, dt * 20)
|
|
186
132
|
this._moveBlend += (targetMove - this._moveBlend) * kMove
|
|
187
|
-
this._runBlend += (targetRun - this._runBlend) * kRun
|
|
188
|
-
this._crouchBlend += (targetCrouch - this._crouchBlend) * kCrouch
|
|
189
133
|
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
const crouchBlend = clamp01(this._crouchBlend)
|
|
134
|
+
const speed = this.isRunning ? 10 : 8
|
|
135
|
+
this._phase += dt * speed * this._moveBlend
|
|
193
136
|
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
const speed = baseSpeed * crouchSpeedMul
|
|
137
|
+
const t = this._phase + (this.isRunning ? Math.PI * 0.5 : 0)
|
|
138
|
+
let reset = false
|
|
197
139
|
|
|
198
|
-
this.
|
|
199
|
-
this._idlePhase += dt * 1.15
|
|
140
|
+
applyCrouchPose(player, this.isCrouched ? 1 : 0)
|
|
200
141
|
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (boundary < 0.02) {
|
|
206
|
-
const cb = this.switchAnimationCallback
|
|
207
|
-
this.switchAnimationCallback = null
|
|
208
|
-
cb?.()
|
|
142
|
+
const boundary = this.isRunning ? Math.cos(t) : Math.sin(t)
|
|
143
|
+
if (Math.abs(boundary) < 0.02) {
|
|
144
|
+
if (this.switchAnimationCallback) {
|
|
145
|
+
reset = true
|
|
209
146
|
}
|
|
210
147
|
}
|
|
211
148
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const kLook = Math.min(1, dt * 14)
|
|
220
|
-
this._lookYawBlend += (targetLookYaw - this._lookYawBlend) * kLook
|
|
221
|
-
this._lookPitchBlend += (targetLookPitch - this._lookPitchBlend) * kLook
|
|
222
|
-
|
|
223
|
-
if (player?.skin?.head?.rotation) {
|
|
224
|
-
player.skin.head.rotation.y += this._lookYawBlend
|
|
225
|
-
player.skin.head.rotation.x += this._lookPitchBlend
|
|
149
|
+
if (this.isRunning) {
|
|
150
|
+
player.skin.leftLeg.rotation.x = Math.cos(t + Math.PI) * 1.3
|
|
151
|
+
player.skin.rightLeg.rotation.x = Math.cos(t) * 1.3
|
|
152
|
+
} else {
|
|
153
|
+
player.skin.leftLeg.rotation.x = Math.sin(t) * 0.5
|
|
154
|
+
player.skin.rightLeg.rotation.x = Math.sin(t + Math.PI) * 0.5
|
|
226
155
|
}
|
|
227
156
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
player.skin.body.rotation.x += b * 0.02 * idleStrength
|
|
232
|
-
player.skin.head.rotation.x += -b * 0.015 * idleStrength
|
|
233
|
-
player.skin.leftArm.rotation.x += b * 0.03 * idleStrength
|
|
234
|
-
player.skin.rightArm.rotation.x += -b * 0.03 * idleStrength
|
|
235
|
-
if (player?.cape?.rotation) player.cape.rotation.x += Math.sin(this._idlePhase * 0.7) * 0.03 * idleStrength
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (moveBlend > 0.0001 && player?.skin) {
|
|
239
|
-
const legAmp = mix(1, 0.85, crouchBlend)
|
|
240
|
-
const armAmp = mix(1, 0.7, crouchBlend)
|
|
241
|
-
|
|
242
|
-
const walkLegL = Math.sin(t) * 0.5
|
|
243
|
-
const walkLegR = Math.sin(t + Math.PI) * 0.5
|
|
244
|
-
const runLegL = Math.cos(t + Math.PI) * 1.3
|
|
245
|
-
const runLegR = Math.cos(t) * 1.3
|
|
246
|
-
|
|
247
|
-
player.skin.leftLeg.rotation.x += mix(walkLegL, runLegL, runBlend) * moveBlend * legAmp
|
|
248
|
-
player.skin.rightLeg.rotation.x += mix(walkLegR, runLegR, runBlend) * moveBlend * legAmp
|
|
249
|
-
|
|
250
|
-
const walkArmL = Math.sin(t + Math.PI) * 0.5
|
|
251
|
-
const walkArmR = Math.sin(t) * 0.5
|
|
252
|
-
const runArmL = Math.cos(t) * 1.5
|
|
253
|
-
const runArmR = Math.cos(t + Math.PI) * 1.5
|
|
254
|
-
|
|
255
|
-
player.skin.leftArm.rotation.x += mix(walkArmL, runArmL, runBlend) * moveBlend * armAmp
|
|
256
|
-
player.skin.rightArm.rotation.x += mix(walkArmR, runArmR, runBlend) * moveBlend * armAmp
|
|
257
|
-
|
|
258
|
-
const walkArmZBase = Math.PI * 0.02
|
|
259
|
-
const runArmZBase = Math.PI * 0.1
|
|
260
|
-
const armZBase = mix(walkArmZBase, runArmZBase, runBlend)
|
|
157
|
+
if (this.isRunning) {
|
|
158
|
+
player.skin.leftArm.rotation.x = Math.cos(t) * 1.5
|
|
159
|
+
player.skin.rightArm.rotation.x = Math.cos(t + Math.PI) * 1.5
|
|
261
160
|
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
161
|
+
const basicArmRotationZ = Math.PI * 0.1
|
|
162
|
+
player.skin.leftArm.rotation.z = Math.cos(t) * 0.1 + basicArmRotationZ
|
|
163
|
+
player.skin.rightArm.rotation.z = Math.cos(t + Math.PI) * 0.1 - basicArmRotationZ
|
|
164
|
+
} else {
|
|
165
|
+
player.skin.leftArm.rotation.x = Math.sin(t + Math.PI) * 0.5
|
|
166
|
+
player.skin.rightArm.rotation.x = Math.sin(t) * 0.5
|
|
266
167
|
|
|
267
|
-
|
|
268
|
-
player.skin.
|
|
269
|
-
|
|
270
|
-
if (this._defaults?.playerRot) {
|
|
271
|
-
player.rotation.z = this._defaults.playerRot.z + Math.cos(t + Math.PI) * 0.01 * runBlend * moveBlend
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const capeBase = mix(Math.PI * 0.06, Math.PI * 0.3, runBlend)
|
|
275
|
-
const capeWave = mix(Math.sin(t / 1.5) * 0.06, Math.sin(t * 2) * 0.1, runBlend)
|
|
276
|
-
if (player?.cape?.rotation) player.cape.rotation.x += (capeBase + capeWave) * moveBlend
|
|
168
|
+
const basicArmRotationZ = Math.PI * 0.02
|
|
169
|
+
player.skin.leftArm.rotation.z = Math.cos(t) * 0.03 + basicArmRotationZ
|
|
170
|
+
player.skin.rightArm.rotation.z = Math.cos(t + Math.PI) * 0.03 - basicArmRotationZ
|
|
277
171
|
}
|
|
278
172
|
|
|
279
173
|
if (this._swingTime !== null) {
|
|
280
174
|
this._swingTime += dt
|
|
281
175
|
const p = Math.min(this._swingTime / this._swingDuration, 1)
|
|
282
|
-
HitAnimation.animate(p, player,
|
|
176
|
+
HitAnimation.animate(p, player, this.isMoving)
|
|
283
177
|
if (p >= 1) this._swingTime = null
|
|
284
178
|
}
|
|
179
|
+
|
|
180
|
+
if (this.isRunning) {
|
|
181
|
+
player.rotation.z = Math.cos(t + Math.PI) * 0.01
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (this.isRunning) {
|
|
185
|
+
const basicCapeRotationX = Math.PI * 0.3
|
|
186
|
+
player.cape.rotation.x = Math.sin(t * 2) * 0.1 + basicCapeRotationX
|
|
187
|
+
} else {
|
|
188
|
+
const basicCapeRotationX = Math.PI * 0.06
|
|
189
|
+
player.cape.rotation.x = Math.sin(t / 1.5) * 0.06 + basicCapeRotationX
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (reset) {
|
|
193
|
+
const cb = this.switchAnimationCallback
|
|
194
|
+
this.switchAnimationCallback = null
|
|
195
|
+
cb?.()
|
|
196
|
+
}
|
|
285
197
|
}
|
|
286
198
|
}
|
|
287
199
|
|
|
@@ -289,11 +201,6 @@ const HitAnimation = {
|
|
|
289
201
|
animate(progress, player, isMovingOrRunning) {
|
|
290
202
|
if (!player?.skin?.rightArm?.rotation) return
|
|
291
203
|
|
|
292
|
-
// One swing = one arc. `swing` rises to its peak at the middle of the swing
|
|
293
|
-
// (progress 0.5) and returns to rest at both ends, matching vanilla's
|
|
294
|
-
// `sin(swingProgress * PI)` and the first-person hand. Driving the trig with
|
|
295
|
-
// `progress * 18` previously ran ~3 sine cycles per click, which made other
|
|
296
|
-
// players' arms look like they were swinging several times per hit.
|
|
297
204
|
const swing = Math.sin(progress * Math.PI)
|
|
298
205
|
player.skin.rightArm.rotation.x = -0.4537860552 * 2 - 2 * swing * 0.3
|
|
299
206
|
|
|
@@ -354,4 +261,4 @@ function applyCrouchPose(player, crouchBlend) {
|
|
|
354
261
|
|
|
355
262
|
skin.rightLeg.position.z += -3.4500310377 * s
|
|
356
263
|
skin.leftLeg.position.z += -3.4500310377 * s
|
|
357
|
-
}
|
|
264
|
+
}
|