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,
|
foreground: true,
|
||||||
enableDebugOverlay: false,
|
enableDebugOverlay: false,
|
||||||
_experimentalSmoothChunkLoading: true,
|
_experimentalSmoothChunkLoading: true,
|
||||||
_renderByChunks: false
|
_renderByChunks: false,
|
||||||
|
volume: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WorldRendererConfig = typeof defaultWorldRendererConfig
|
export type WorldRendererConfig = typeof defaultWorldRendererConfig
|
||||||
|
|
@ -239,7 +240,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.resetWorkers(),
|
this.resetWorkers(),
|
||||||
(async () => {
|
(async () => {
|
||||||
if (this.resourcesManager.currentResources) {
|
if (this.resourcesManager.currentResources?.itemsRenderer) {
|
||||||
await this.updateAssetsData()
|
await this.updateAssetsData()
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
@ -812,7 +813,16 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
||||||
})
|
})
|
||||||
|
|
||||||
worldEmitter.on('onWorldSwitch', () => {
|
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) => {
|
worldEmitter.on('time', (timeOfDay) => {
|
||||||
|
|
|
||||||
|
|
@ -302,13 +302,8 @@ export class Entities {
|
||||||
const dz = entity.position.z - botPos.z
|
const dz = entity.position.z - botPos.z
|
||||||
const distanceSquared = dx * dx + dy * dy + dz * dz
|
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 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)
|
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') {
|
playAnimation (entityPlayerId, animation: 'walking' | 'running' | 'oneSwing' | 'idle' | 'crouch' | 'crouchWalking') {
|
||||||
const playerObject = this.getPlayerObject(entityPlayerId)
|
const playerObject = this.getPlayerObject(entityPlayerId)
|
||||||
if (!playerObject) return
|
if (!playerObject) return
|
||||||
|
|
@ -693,7 +694,7 @@ export class Entities {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let mesh
|
let mesh: THREE.Object3D | undefined
|
||||||
if (e === undefined) {
|
if (e === undefined) {
|
||||||
const group = new THREE.Group()
|
const group = new THREE.Group()
|
||||||
if (entity.name === 'item' || entity.name === 'tnt' || entity.name === 'falling_block') {
|
if (entity.name === 'item' || entity.name === 'tnt' || entity.name === 'falling_block') {
|
||||||
|
|
@ -722,7 +723,7 @@ export class Entities {
|
||||||
if (entity.name === 'item') {
|
if (entity.name === 'item') {
|
||||||
mesh.onBeforeRender = () => {
|
mesh.onBeforeRender = () => {
|
||||||
const delta = clock.getDelta()
|
const delta = clock.getDelta()
|
||||||
mesh.rotation.y += delta
|
mesh!.rotation.y += delta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -846,7 +847,7 @@ export class Entities {
|
||||||
//@ts-expect-error
|
//@ts-expect-error
|
||||||
// set visibility
|
// set visibility
|
||||||
const isInvisible = entity.metadata?.[0] & 0x20
|
const isInvisible = entity.metadata?.[0] & 0x20
|
||||||
for (const child of mesh.children ?? []) {
|
for (const child of mesh!.children ?? []) {
|
||||||
if (child.name !== 'nametag') {
|
if (child.name !== 'nametag') {
|
||||||
child.visible = !isInvisible
|
child.visible = !isInvisible
|
||||||
}
|
}
|
||||||
|
|
@ -885,8 +886,8 @@ export class Entities {
|
||||||
const hasArms = (parseInt(armorStandMeta.client_flags, 10) & 0x04) !== 0
|
const hasArms = (parseInt(armorStandMeta.client_flags, 10) & 0x04) !== 0
|
||||||
const hasBasePlate = (parseInt(armorStandMeta.client_flags, 10) & 0x08) === 0
|
const hasBasePlate = (parseInt(armorStandMeta.client_flags, 10) & 0x08) === 0
|
||||||
const isMarker = (parseInt(armorStandMeta.client_flags, 10) & 0x10) !== 0
|
const isMarker = (parseInt(armorStandMeta.client_flags, 10) & 0x10) !== 0
|
||||||
mesh.castShadow = !isMarker
|
mesh!.castShadow = !isMarker
|
||||||
mesh.receiveShadow = !isMarker
|
mesh!.receiveShadow = !isMarker
|
||||||
if (isSmall) {
|
if (isSmall) {
|
||||||
e.scale.set(0.5, 0.5, 0.5)
|
e.scale.set(0.5, 0.5, 0.5)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -955,7 +956,9 @@ export class Entities {
|
||||||
// TODO: fix type
|
// TODO: fix type
|
||||||
// todo! fix errors in mc-data (no entities data prior 1.18.2)
|
// 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 } } } }
|
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.rotation.x = -entity.pitch
|
||||||
e.children.find(c => {
|
e.children.find(c => {
|
||||||
if (c.name.startsWith('map_')) {
|
if (c.name.startsWith('map_')) {
|
||||||
|
|
@ -972,25 +975,33 @@ export class Entities {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})?.removeFromParent()
|
})?.removeFromParent()
|
||||||
|
|
||||||
if (item && (item.itemId ?? item.blockId ?? 0) !== 0) {
|
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 rotation = (itemFrameMeta.rotation as any as number) ?? 0
|
||||||
const mapNumber = item.nbtData?.value?.map?.value ?? item.components?.find(x => x.type === 'map_id')?.data
|
const mapNumber = item.nbtData?.value?.map?.value ?? item.components?.find(x => x.type === 'map_id')?.data
|
||||||
if (mapNumber) {
|
if (mapNumber) {
|
||||||
// TODO: Use proper larger item frame model when a map exists
|
// 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)
|
this.addMapModel(e, mapNumber, rotation)
|
||||||
} else {
|
} else {
|
||||||
|
// Handle regular item rotation (8 possibilities, 45° increments)
|
||||||
const itemMesh = this.getItemMesh(item, {
|
const itemMesh = this.getItemMesh(item, {
|
||||||
'minecraft:display_context': 'fixed',
|
'minecraft:display_context': 'fixed',
|
||||||
})
|
})
|
||||||
if (itemMesh) {
|
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) {
|
if (itemMesh.isBlock) {
|
||||||
itemMesh.mesh.scale.set(0.25, 0.25, 0.25)
|
itemMesh.mesh.scale.set(0.25, 0.25, 0.25)
|
||||||
} else {
|
} else {
|
||||||
itemMesh.mesh.scale.set(0.5, 0.5, 0.5)
|
itemMesh.mesh.scale.set(0.5, 0.5, 0.5)
|
||||||
}
|
}
|
||||||
|
// Rotate 180° around Y axis first
|
||||||
itemMesh.mesh.rotateY(Math.PI)
|
itemMesh.mesh.rotateY(Math.PI)
|
||||||
|
// Then apply the 45° increment rotation
|
||||||
itemMesh.mesh.rotateZ(-rotation * Math.PI / 4)
|
itemMesh.mesh.rotateZ(-rotation * Math.PI / 4)
|
||||||
itemMesh.mesh.name = 'item'
|
itemMesh.mesh.name = 'item'
|
||||||
e.add(itemMesh.mesh)
|
e.add(itemMesh.mesh)
|
||||||
|
|
@ -1105,6 +1116,7 @@ export class Entities {
|
||||||
} else {
|
} else {
|
||||||
mapMesh.position.set(0, 0, 0.437)
|
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.rotateZ(Math.PI * 2 - rotation * Math.PI / 2)
|
||||||
mapMesh.name = `map_${mapNumber}`
|
mapMesh.name = `map_${mapNumber}`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -710,6 +710,18 @@ export class WorldRendererThree extends WorldRendererCommon {
|
||||||
super.destroy()
|
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 () {
|
updateSectionOffsets () {
|
||||||
const currentTime = performance.now()
|
const currentTime = performance.now()
|
||||||
for (const [key, anim] of Object.entries(this.sectionsOffsetsAnimations)) {
|
for (const [key, anim] of Object.entries(this.sectionsOffsetsAnimations)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue