Compare commits
2 commits
next
...
fix-frames
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02a1be8eea | ||
|
|
b3807fff65 |
3 changed files with 51 additions and 17 deletions
|
|
@ -52,7 +52,8 @@ export const defaultWorldRendererConfig = {
|
|||
foreground: true,
|
||||
enableDebugOverlay: false,
|
||||
_experimentalSmoothChunkLoading: true,
|
||||
_renderByChunks: false
|
||||
_renderByChunks: false,
|
||||
volume: 1
|
||||
}
|
||||
|
||||
export type WorldRendererConfig = typeof defaultWorldRendererConfig
|
||||
|
|
@ -239,7 +240,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
await Promise.all([
|
||||
this.resetWorkers(),
|
||||
(async () => {
|
||||
if (this.resourcesManager.currentResources) {
|
||||
if (this.resourcesManager.currentResources?.itemsRenderer) {
|
||||
await this.updateAssetsData()
|
||||
}
|
||||
})()
|
||||
|
|
@ -812,7 +813,16 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
})
|
||||
|
||||
worldEmitter.on('onWorldSwitch', () => {
|
||||
for (const fn of this.onWorldSwitched) fn()
|
||||
for (const fn of this.onWorldSwitched) {
|
||||
try {
|
||||
fn()
|
||||
} catch (e) {
|
||||
setTimeout(() => {
|
||||
console.log('[Renderer Backend] Error in onWorldSwitched:')
|
||||
throw e
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
worldEmitter.on('time', (timeOfDay) => {
|
||||
|
|
|
|||
|
|
@ -302,13 +302,8 @@ export class Entities {
|
|||
const dz = entity.position.z - botPos.z
|
||||
const distanceSquared = dx * dx + dy * dy + dz * dz
|
||||
|
||||
// Get chunk coordinates
|
||||
const chunkX = Math.floor(entity.position.x / 16) * 16
|
||||
const chunkZ = Math.floor(entity.position.z / 16) * 16
|
||||
const chunkKey = `${chunkX},${chunkZ}`
|
||||
|
||||
// Entity is visible if within 16 blocks OR in a finished chunk
|
||||
entity.visible = !!(distanceSquared < VISIBLE_DISTANCE || this.worldRenderer.finishedChunks[chunkKey])
|
||||
entity.visible = !!(distanceSquared < VISIBLE_DISTANCE || this.worldRenderer.shouldObjectVisible(entity))
|
||||
|
||||
this.maybeRenderPlayerSkin(entityId)
|
||||
}
|
||||
|
|
@ -540,6 +535,12 @@ export class Entities {
|
|||
}
|
||||
}
|
||||
|
||||
debugSwingArm () {
|
||||
const playerObject = Object.values(this.entities).find(entity => entity.playerObject?.animation instanceof WalkingGeneralSwing)
|
||||
if (!playerObject) return
|
||||
(playerObject.playerObject!.animation as WalkingGeneralSwing).swingArm()
|
||||
}
|
||||
|
||||
playAnimation (entityPlayerId, animation: 'walking' | 'running' | 'oneSwing' | 'idle' | 'crouch' | 'crouchWalking') {
|
||||
const playerObject = this.getPlayerObject(entityPlayerId)
|
||||
if (!playerObject) return
|
||||
|
|
@ -693,7 +694,7 @@ export class Entities {
|
|||
return
|
||||
}
|
||||
|
||||
let mesh
|
||||
let mesh: THREE.Object3D | undefined
|
||||
if (e === undefined) {
|
||||
const group = new THREE.Group()
|
||||
if (entity.name === 'item' || entity.name === 'tnt' || entity.name === 'falling_block') {
|
||||
|
|
@ -722,7 +723,7 @@ export class Entities {
|
|||
if (entity.name === 'item') {
|
||||
mesh.onBeforeRender = () => {
|
||||
const delta = clock.getDelta()
|
||||
mesh.rotation.y += delta
|
||||
mesh!.rotation.y += delta
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -846,7 +847,7 @@ export class Entities {
|
|||
//@ts-expect-error
|
||||
// set visibility
|
||||
const isInvisible = entity.metadata?.[0] & 0x20
|
||||
for (const child of mesh.children ?? []) {
|
||||
for (const child of mesh!.children ?? []) {
|
||||
if (child.name !== 'nametag') {
|
||||
child.visible = !isInvisible
|
||||
}
|
||||
|
|
@ -885,8 +886,8 @@ export class Entities {
|
|||
const hasArms = (parseInt(armorStandMeta.client_flags, 10) & 0x04) !== 0
|
||||
const hasBasePlate = (parseInt(armorStandMeta.client_flags, 10) & 0x08) === 0
|
||||
const isMarker = (parseInt(armorStandMeta.client_flags, 10) & 0x10) !== 0
|
||||
mesh.castShadow = !isMarker
|
||||
mesh.receiveShadow = !isMarker
|
||||
mesh!.castShadow = !isMarker
|
||||
mesh!.receiveShadow = !isMarker
|
||||
if (isSmall) {
|
||||
e.scale.set(0.5, 0.5, 0.5)
|
||||
} else {
|
||||
|
|
@ -955,7 +956,9 @@ export class Entities {
|
|||
// TODO: fix type
|
||||
// todo! fix errors in mc-data (no entities data prior 1.18.2)
|
||||
const item = (itemFrameMeta?.item ?? entity.metadata?.[8]) as any as { itemId, blockId, components, nbtData: { value: { map: { value: number } } } }
|
||||
mesh.scale.set(1, 1, 1)
|
||||
mesh!.scale.set(1, 1, 1)
|
||||
mesh!.position.set(0, 0, -0.5)
|
||||
|
||||
e.rotation.x = -entity.pitch
|
||||
e.children.find(c => {
|
||||
if (c.name.startsWith('map_')) {
|
||||
|
|
@ -972,25 +975,33 @@ export class Entities {
|
|||
}
|
||||
return false
|
||||
})?.removeFromParent()
|
||||
|
||||
if (item && (item.itemId ?? item.blockId ?? 0) !== 0) {
|
||||
// Get rotation from metadata, default to 0 if not present
|
||||
// Rotation is stored in 45° increments (0-7) for items, 90° increments (0-3) for maps
|
||||
const rotation = (itemFrameMeta.rotation as any as number) ?? 0
|
||||
const mapNumber = item.nbtData?.value?.map?.value ?? item.components?.find(x => x.type === 'map_id')?.data
|
||||
if (mapNumber) {
|
||||
// TODO: Use proper larger item frame model when a map exists
|
||||
mesh.scale.set(16 / 12, 16 / 12, 1)
|
||||
mesh!.scale.set(16 / 12, 16 / 12, 1)
|
||||
// Handle map rotation (4 possibilities, 90° increments)
|
||||
this.addMapModel(e, mapNumber, rotation)
|
||||
} else {
|
||||
// Handle regular item rotation (8 possibilities, 45° increments)
|
||||
const itemMesh = this.getItemMesh(item, {
|
||||
'minecraft:display_context': 'fixed',
|
||||
})
|
||||
if (itemMesh) {
|
||||
itemMesh.mesh.position.set(0, 0, 0.43)
|
||||
itemMesh.mesh.position.set(0, 0, -0.05)
|
||||
// itemMesh.mesh.position.set(0, 0, 0.43)
|
||||
if (itemMesh.isBlock) {
|
||||
itemMesh.mesh.scale.set(0.25, 0.25, 0.25)
|
||||
} else {
|
||||
itemMesh.mesh.scale.set(0.5, 0.5, 0.5)
|
||||
}
|
||||
// Rotate 180° around Y axis first
|
||||
itemMesh.mesh.rotateY(Math.PI)
|
||||
// Then apply the 45° increment rotation
|
||||
itemMesh.mesh.rotateZ(-rotation * Math.PI / 4)
|
||||
itemMesh.mesh.name = 'item'
|
||||
e.add(itemMesh.mesh)
|
||||
|
|
@ -1105,6 +1116,7 @@ export class Entities {
|
|||
} else {
|
||||
mapMesh.position.set(0, 0, 0.437)
|
||||
}
|
||||
// Apply 90° increment rotation for maps (0-3)
|
||||
mapMesh.rotateZ(Math.PI * 2 - rotation * Math.PI / 2)
|
||||
mapMesh.name = `map_${mapNumber}`
|
||||
|
||||
|
|
|
|||
|
|
@ -710,6 +710,18 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
super.destroy()
|
||||
}
|
||||
|
||||
shouldObjectVisible (object: THREE.Object3D) {
|
||||
// Get chunk coordinates
|
||||
const chunkX = Math.floor(object.position.x / 16) * 16
|
||||
const chunkZ = Math.floor(object.position.z / 16) * 16
|
||||
const sectionY = Math.floor(object.position.y / 16) * 16
|
||||
|
||||
const chunkKey = `${chunkX},${chunkZ}`
|
||||
const sectionKey = `${chunkX},${sectionY},${chunkZ}`
|
||||
|
||||
return !!this.finishedChunks[chunkKey] || !!this.sectionObjects[sectionKey]
|
||||
}
|
||||
|
||||
updateSectionOffsets () {
|
||||
const currentTime = performance.now()
|
||||
for (const [key, anim] of Object.entries(this.sectionsOffsetsAnimations)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue