a few minor but important world renderer fixes & impr
This commit is contained in:
parent
7aeb13f9fe
commit
9a8ff32f5a
10 changed files with 63 additions and 12 deletions
|
|
@ -6,7 +6,28 @@ export default defineConfig({
|
|||
e2e: {
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
setupNodeEvents(on, config) {
|
||||
setupNodeEvents (on, config) {
|
||||
// https://medium.com/automation-with-donald/get-memory-consumption-of-web-app-with-cypress-84e2656e5a0f
|
||||
on('before:browser:launch', (browser = {
|
||||
name: "",
|
||||
family: "chromium",
|
||||
channel: "",
|
||||
displayName: "",
|
||||
version: "",
|
||||
majorVersion: "",
|
||||
path: "",
|
||||
isHeaded: false,
|
||||
isHeadless: false
|
||||
}, launchOptions) => {
|
||||
if (browser.family === 'chromium' && browser.name !== 'electron') {
|
||||
// auto open devtools
|
||||
launchOptions.args.push('--enable-precise-memory-info')
|
||||
}
|
||||
|
||||
return launchOptions
|
||||
|
||||
})
|
||||
|
||||
return require('./cypress/plugins/index.js')(on, config)
|
||||
},
|
||||
baseUrl: 'http://localhost:8080',
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ function setSectionDirty (pos, value = true) {
|
|||
}
|
||||
}
|
||||
|
||||
const softCleanup = () => {
|
||||
world.blockCache = {}
|
||||
}
|
||||
|
||||
self.onmessage = ({ data }) => {
|
||||
const globalVar: any = globalThis
|
||||
|
||||
|
|
@ -58,6 +62,7 @@ self.onmessage = ({ data }) => {
|
|||
world.addColumn(data.x, data.z, data.chunk)
|
||||
} else if (data.type === 'unloadChunk') {
|
||||
world.removeColumn(data.x, data.z)
|
||||
if (Object.keys(world.columns).length === 0) softCleanup()
|
||||
} else if (data.type === 'blockUpdate') {
|
||||
const loc = new Vec3(data.pos.x, data.pos.y, data.pos.z).floored()
|
||||
world.setBlockStateId(loc, data.stateId)
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ export class World {
|
|||
// todo export in chunk instead
|
||||
const hasChunkSection = (column, pos) => {
|
||||
if (column._getSection) return column._getSection(pos)
|
||||
if (column.sections) return column.sections[pos.y >> 4]
|
||||
if (column.skyLightSections) return column.skyLightSections[getLightSectionIndex(pos, column.minY)]
|
||||
if (column.sections) return column.sections[pos.y >> 4]
|
||||
}
|
||||
|
||||
function posInChunk (pos) {
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ export class Viewer {
|
|||
emitter.on('renderDistance', (d) => {
|
||||
this.world.viewDistance = d
|
||||
this.world.chunksLength = d === 0 ? 1 : generateSpiralMatrix(d).length
|
||||
this.world.allChunksFinished = Object.keys(this.world.finishedChunks).length === this.world.chunksLength
|
||||
})
|
||||
|
||||
emitter.on('updateLight', ({ pos }) => {
|
||||
|
|
|
|||
|
|
@ -111,10 +111,6 @@ export class ViewerWrapper {
|
|||
if (this.renderer) {
|
||||
this.renderer.setSize(width, height)
|
||||
}
|
||||
// canvas updated by renderer
|
||||
|
||||
// if (viewer.composer) {
|
||||
// viewer.updateComposerSize()
|
||||
// }
|
||||
viewer.world.handleResize()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
skyLight = 15
|
||||
smoothLighting = true
|
||||
enableLighting = true
|
||||
allChunksFinished = false
|
||||
handleResize = () => { }
|
||||
|
||||
abstract outputFormat: 'threeJs' | 'webgl'
|
||||
|
||||
|
|
@ -76,6 +78,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
const allFinished = Object.keys(this.finishedChunks).length === this.chunksLength
|
||||
if (allFinished) {
|
||||
this.allChunksLoaded?.()
|
||||
this.allChunksFinished = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,6 +130,8 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
this.active = false
|
||||
this.loadedChunks = {}
|
||||
this.sectionsOutstanding = new Map()
|
||||
this.finishedChunks = {}
|
||||
this.allChunksFinished = false
|
||||
for (const worker of this.workers) {
|
||||
worker.postMessage({ type: 'reset' })
|
||||
}
|
||||
|
|
@ -198,6 +203,8 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
for (const worker of this.workers) {
|
||||
worker.postMessage({ type: 'unloadChunk', x, z })
|
||||
}
|
||||
this.allChunksFinished = Object.keys(this.finishedChunks).length === this.chunksLength
|
||||
delete this.finishedChunks[`${x},${z}`]
|
||||
}
|
||||
|
||||
setBlockStateId (pos: Vec3, stateId: number) {
|
||||
|
|
@ -215,6 +222,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
|
||||
setSectionDirty (pos: Vec3, value = true) {
|
||||
if (this.viewDistance === -1) throw new Error('viewDistance not set')
|
||||
this.allChunksFinished = false
|
||||
const distance = this.getDistance(pos)
|
||||
if (distance[0] > this.viewDistance || distance[1] > this.viewDistance) return
|
||||
const key = `${Math.floor(pos.x / 16) * 16},${Math.floor(pos.y / 16) * 16},${Math.floor(pos.z / 16) * 16}`
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { renderSign } from '../sign-renderer/'
|
|||
import { chunkPos, sectionPos } from './simpleUtils'
|
||||
import { WorldRendererCommon } from './worldrendererCommon'
|
||||
import * as tweenJs from '@tweenjs/tween.js'
|
||||
import { BloomPass, RenderPass, UnrealBloomPass, EffectComposer, WaterPass, GlitchPass } from 'three-stdlib'
|
||||
|
||||
function mod (x, n) {
|
||||
return ((x % n) + n) % n
|
||||
|
|
@ -20,6 +21,10 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
chunkTextures = new Map<string, { [pos: string]: THREE.Texture }>()
|
||||
signsCache = new Map<string, any>()
|
||||
|
||||
get tilesRendered () {
|
||||
return Object.values(this.sectionObjects).reduce((acc, obj) => acc + (obj as any).tilesCount, 0)
|
||||
}
|
||||
|
||||
constructor(public scene: THREE.Scene, public renderer: THREE.WebGLRenderer, public camera: THREE.PerspectiveCamera, numWorkers = 4) {
|
||||
super(numWorkers)
|
||||
}
|
||||
|
|
@ -87,6 +92,8 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
boxHelper.name = 'helper'
|
||||
object.add(boxHelper)
|
||||
object.name = 'chunk'
|
||||
//@ts-ignore
|
||||
object.tilesCount = data.geometry.positions.length / 3 / 4
|
||||
if (!this.showChunkBorders) {
|
||||
boxHelper.visible = false
|
||||
}
|
||||
|
|
|
|||
10
src/index.ts
10
src/index.ts
|
|
@ -759,8 +759,14 @@ async function connect (connectOptions: {
|
|||
|
||||
if (appStatusState.isError) return
|
||||
setLoadingScreenStatus(undefined)
|
||||
void viewer.waitForChunksToRender().then(() => {
|
||||
console.log('All done and ready!')
|
||||
const start = Date.now()
|
||||
let done = false
|
||||
void viewer.world.renderUpdateEmitter.on('update', () => {
|
||||
// todo might not emit as servers simply don't send chunk if it's empty
|
||||
if (!viewer.world.allChunksFinished || done) return
|
||||
done = true
|
||||
console.log('All done and ready! In', (Date.now() - start) / 1000, 's')
|
||||
viewer.render() // ensure the last state is rendered
|
||||
document.dispatchEvent(new Event('cypress-world-ready'))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ subscribeKey(miscUiState, 'gameLoaded', async () => {
|
|||
return
|
||||
}
|
||||
if (!options.volume) return
|
||||
console.debug('play sound', soundId)
|
||||
const parts = soundString.split(';')
|
||||
const soundVolume = +parts[0]!
|
||||
const soundName = parts[1]!
|
||||
|
|
|
|||
12
src/utils.ts
12
src/utils.ts
|
|
@ -161,11 +161,19 @@ let prevRenderDistance = options.renderDistance
|
|||
export const setRenderDistance = () => {
|
||||
assertDefined(worldView)
|
||||
const { renderDistance: singleplayerRenderDistance, multiplayerRenderDistance } = options
|
||||
const renderDistance = miscUiState.singleplayer ? singleplayerRenderDistance : multiplayerRenderDistance
|
||||
let renderDistance = miscUiState.singleplayer ? singleplayerRenderDistance : multiplayerRenderDistance
|
||||
const zeroRenderDistance = miscUiState.singleplayer && renderDistance === 0
|
||||
if (zeroRenderDistance) {
|
||||
renderDistance = 1 // mineflayer limitation workaround
|
||||
}
|
||||
bot.setSettings({
|
||||
viewDistance: renderDistance
|
||||
})
|
||||
worldView.viewDistance = renderDistance
|
||||
if (zeroRenderDistance) {
|
||||
localServer!.players[0].view = 0
|
||||
renderDistance = 0
|
||||
}
|
||||
worldView.updateViewDistance(renderDistance)
|
||||
prevRenderDistance = renderDistance
|
||||
}
|
||||
export const reloadChunks = async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue