From 5a8dde5dce6701f9d26cd4ce8a04c484c072631e Mon Sep 17 00:00:00 2001 From: test137e29b Date: Sat, 4 Nov 2023 12:54:22 +0000 Subject: [PATCH 1/4] Implement Timecycle lighting for viewer --- package.json | 12 +++++------ viewer/lib/viewer.js | 47 +++++++++++++++++++++++++++++++++++++++++ viewer/lib/worldView.js | 8 +++++++ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c991179e..35baca6b 100644 --- a/package.json +++ b/package.json @@ -38,21 +38,21 @@ "assert": "^2.0.0", "buffer": "^6.0.3", "canvas": "^2.6.1", - "process": "^0.11.10", - "node-canvas-webgl": "PrismarineJS/node-canvas-webgl", - "minecraft-assets": "^1.9.0", + "fs-extra": "^11.0.0", "jest": "^27.0.4", "jest-puppeteer": "^6.0.0", + "minecraft-assets": "^1.9.0", "minecraft-wrap": "^1.3.0", + "minecrafthawkeye": "^1.2.5", "mineflayer": "^4.0.0", "mineflayer-pathfinder": "^2.0.0", + "node-canvas-webgl": "PrismarineJS/node-canvas-webgl", "prismarine-schematic": "^1.2.0", - "minecrafthawkeye": "^1.2.5", "prismarine-viewer": "file:./", + "process": "^0.11.10", "puppeteer": "^16.0.0", "standard": "^17.0.0", "webpack": "^5.10.2", - "webpack-cli": "^5.1.1", - "fs-extra": "^11.0.0" + "webpack-cli": "^5.1.1" } } diff --git a/viewer/lib/viewer.js b/viewer/lib/viewer.js index adcb5b62..bf3ad194 100644 --- a/viewer/lib/viewer.js +++ b/viewer/lib/viewer.js @@ -85,6 +85,10 @@ class Viewer { this.setBlockStateId(new Vec3(pos.x, pos.y, pos.z), stateId) }) + emitter.on('timecycleUpdate', ({ timeOfDay, moonPhase }) => { + this.updateTimecycleLighting(timeOfDay, moonPhase) + }) + this.domElement.addEventListener('pointerdown', (evt) => { const raycaster = new THREE.Raycaster() const mouse = new THREE.Vector2() @@ -96,6 +100,49 @@ class Viewer { }) } + updateTimecycleLighting(timeOfDay, moonPhase) { + if (timeOfDay === undefined) { return } + const lightIntensity = this.calculateIntensity(timeOfDay) + const skyColor = scene.background.getHexString() + const newSkyColor = `#${this.darkenSkyColour(skyColor, lightIntensity).padStart(6, 0)}` + + function timeToRads(time) { + return time * (Math.PI / 12000) + } + + // Update colours + this.scene.background = new THREE.Color(newSkyColor) + this.ambientLight.itensity = ((lightIntensity < 0.25) ? 0.25 : lightIntensity) + (0.07 - (moonPhase / 100)) + this.directionalLight.intensity = lightIntensity + (0.07 - (moonPhase / 100)) + this.directionalLight.position.set( + Math.cos(timeToRads(timeOfDay)), + Math.sin(timeToRads(timeOfDay)), + 0.2 + ).normalize() + } + + calculateIntensity(timeOfDay) { + if ((timeOfDay >= 13000) && (timeOfDay <= 23000)) { + return 0 + } else if ((timeOfDay <= 12000) && (timeOfDay >= 0)) { + return 0.75 + } else if ((timeOfDay < 13000) && (timeOfDay > 12000)) { + const transition = timeOfDay - 12000 + return (0.75 - (0.75 * transition / 1000)) + } else { + const transition = timeOfDay - 23000 + return (0.75 * transition / 1000) + } + } + + // Darken by factor (0 to black, 0.5 half as bright, 1 unchanged) + darkenSkyColour(skyColour, factor) { + skyColour = parseInt(skyColour, 16) + return (Math.round((skyColour & 0x0000FF) * factor) | + (Math.round(((skyColour >> 8) & 0x00FF) * factor) << 8) | + (Math.round((skyColour >> 16) * factor) << 16)).toString(16) + } + update () { TWEEN.update() } diff --git a/viewer/lib/worldView.js b/viewer/lib/worldView.js index ad0ffa44..b636d523 100644 --- a/viewer/lib/worldView.js +++ b/viewer/lib/worldView.js @@ -10,6 +10,7 @@ class WorldView extends EventEmitter { this.loadedChunks = {} this.lastPos = new Vec3(0, 0, 0).update(position) this.emitter = emitter || this + this._timecycleUpdateInterval = null this.listeners = {} this.emitter.on('mouseClick', async (click) => { @@ -54,6 +55,10 @@ class WorldView extends EventEmitter { this.emitter.emit('entity', { id: e.id, name: e.name, pos: e.position, width: e.width, height: e.height, username: e.username }) } } + + this._timecycleUpdateInterval = setInterval(() => { + this.emit('timecycleUpdate', { timeOfDay: bot.time.timeOfDay, moonPhase: bot.time.moonPhase }) + }, 750) } removeListenersFromBot (bot) { @@ -61,6 +66,9 @@ class WorldView extends EventEmitter { bot.removeListener(evt, listener) } delete this.listeners[bot.username] + + clearInterval(this._timecycleUpdateInterval) + this._timecycleUpdateInterval = null } async init (pos) { From f1fd79a4b9addd6cfb90f33a8ab3502b7eef3fb9 Mon Sep 17 00:00:00 2001 From: test137e29b Date: Sat, 4 Nov 2023 12:59:42 +0000 Subject: [PATCH 2/4] Formatting --- viewer/lib/viewer.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/viewer/lib/viewer.js b/viewer/lib/viewer.js index bf3ad194..11fadd79 100644 --- a/viewer/lib/viewer.js +++ b/viewer/lib/viewer.js @@ -100,13 +100,13 @@ class Viewer { }) } - updateTimecycleLighting(timeOfDay, moonPhase) { + updateTimecycleLighting (timeOfDay, moonPhase) { if (timeOfDay === undefined) { return } const lightIntensity = this.calculateIntensity(timeOfDay) - const skyColor = scene.background.getHexString() + const skyColor = this.scene.background.getHexString() const newSkyColor = `#${this.darkenSkyColour(skyColor, lightIntensity).padStart(6, 0)}` - function timeToRads(time) { + function timeToRads (time) { return time * (Math.PI / 12000) } @@ -121,7 +121,7 @@ class Viewer { ).normalize() } - calculateIntensity(timeOfDay) { + calculateIntensity (timeOfDay) { if ((timeOfDay >= 13000) && (timeOfDay <= 23000)) { return 0 } else if ((timeOfDay <= 12000) && (timeOfDay >= 0)) { @@ -136,7 +136,7 @@ class Viewer { } // Darken by factor (0 to black, 0.5 half as bright, 1 unchanged) - darkenSkyColour(skyColour, factor) { + darkenSkyColour (skyColour, factor) { skyColour = parseInt(skyColour, 16) return (Math.round((skyColour & 0x0000FF) * factor) | (Math.round(((skyColour >> 8) & 0x00FF) * factor) << 8) | From b5e57a9ad0cb61a94fc2b53376780679d8971872 Mon Sep 17 00:00:00 2001 From: test137e29b Date: Sat, 4 Nov 2023 13:00:01 +0000 Subject: [PATCH 3/4] Remove blank line --- viewer/lib/viewer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/viewer/lib/viewer.js b/viewer/lib/viewer.js index 11fadd79..05e38701 100644 --- a/viewer/lib/viewer.js +++ b/viewer/lib/viewer.js @@ -1,4 +1,3 @@ - const THREE = require('three') const TWEEN = require('@tweenjs/tween.js') const { WorldRenderer } = require('./worldrenderer') From e83ce653df5233f217073709143c9d39b72762af Mon Sep 17 00:00:00 2001 From: test137e29b Date: Sat, 4 Nov 2023 16:49:28 +0000 Subject: [PATCH 4/4] Improvements --- .gitignore | 1 + viewer/lib/entities.js | 4 +++- viewer/lib/viewer.js | 37 +++++++++++++++++++++---------------- viewer/lib/worldView.js | 4 ++-- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 293eb55e..f4b2d90f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules package-lock.json /test/*.png +/test/server_* versions/ public/index.js* public/worker.js* diff --git a/viewer/lib/entities.js b/viewer/lib/entities.js index 660a3244..8aa8c2fa 100644 --- a/viewer/lib/entities.js +++ b/viewer/lib/entities.js @@ -7,7 +7,9 @@ const { dispose3 } = require('./dispose') function getEntityMesh (entity, scene) { if (entity.name) { try { - const e = new Entity('1.16.4', entity.name, scene) + // Old versions of minecraft use titlecase entity names (e.g. 'Zombie' instead of 'zombie') + // TODO old version name support. "entityhorse" instead of "horse" in some versions, causing a pink box to render instead + const e = new Entity('1.16.4', entity.name.toLowerCase(), scene) if (entity.username !== undefined) { const canvas = document.createElement('canvas') diff --git a/viewer/lib/viewer.js b/viewer/lib/viewer.js index 05e38701..59be4b91 100644 --- a/viewer/lib/viewer.js +++ b/viewer/lib/viewer.js @@ -10,6 +10,7 @@ class Viewer { constructor (renderer) { this.scene = new THREE.Scene() this.scene.background = new THREE.Color('lightblue') + this.skyColour = this.scene.background.getHexString() this.ambientLight = new THREE.AmbientLight(0xcccccc) this.scene.add(this.ambientLight) @@ -102,8 +103,7 @@ class Viewer { updateTimecycleLighting (timeOfDay, moonPhase) { if (timeOfDay === undefined) { return } const lightIntensity = this.calculateIntensity(timeOfDay) - const skyColor = this.scene.background.getHexString() - const newSkyColor = `#${this.darkenSkyColour(skyColor, lightIntensity).padStart(6, 0)}` + const newSkyColor = `#${this.darkenSkyColour(lightIntensity).padStart(6, 0)}` function timeToRads (time) { return time * (Math.PI / 12000) @@ -111,8 +111,10 @@ class Viewer { // Update colours this.scene.background = new THREE.Color(newSkyColor) - this.ambientLight.itensity = ((lightIntensity < 0.25) ? 0.25 : lightIntensity) + (0.07 - (moonPhase / 100)) - this.directionalLight.intensity = lightIntensity + (0.07 - (moonPhase / 100)) + const newAmbientIntensity = Math.min(0.43, lightIntensity * 0.75) + (0.04 - (moonPhase / 100)) + const newDirectionalIntensity = Math.min(0.63, lightIntensity) + (0.06 - (moonPhase / 100)) + this.ambientLight.itensity = newAmbientIntensity + this.directionalLight.intensity = newDirectionalIntensity this.directionalLight.position.set( Math.cos(timeToRads(timeOfDay)), Math.sin(timeToRads(timeOfDay)), @@ -120,23 +122,26 @@ class Viewer { ).normalize() } - calculateIntensity (timeOfDay) { - if ((timeOfDay >= 13000) && (timeOfDay <= 23000)) { - return 0 - } else if ((timeOfDay <= 12000) && (timeOfDay >= 0)) { - return 0.75 - } else if ((timeOfDay < 13000) && (timeOfDay > 12000)) { - const transition = timeOfDay - 12000 - return (0.75 - (0.75 * transition / 1000)) + calculateIntensity (currentTicks) { + const transitionStart = 12000 + const transitionEnd = 18000 + const timeInDay = (currentTicks % 24000) + let lightIntensity + + if (timeInDay < transitionStart) { + lightIntensity = 1.0 + } else if (timeInDay < transitionEnd) { + lightIntensity = 1 - (timeInDay - transitionStart) / (transitionEnd - transitionStart) } else { - const transition = timeOfDay - 23000 - return (0.75 * transition / 1000) + lightIntensity = (timeInDay - transitionEnd) / (24000 - transitionEnd) } + + return lightIntensity } // Darken by factor (0 to black, 0.5 half as bright, 1 unchanged) - darkenSkyColour (skyColour, factor) { - skyColour = parseInt(skyColour, 16) + darkenSkyColour (factor) { + const skyColour = parseInt(this.skyColour, 16) return (Math.round((skyColour & 0x0000FF) * factor) | (Math.round(((skyColour >> 8) & 0x00FF) * factor) << 8) | (Math.round((skyColour >> 16) * factor) << 16)).toString(16) diff --git a/viewer/lib/worldView.js b/viewer/lib/worldView.js index b636d523..3939533b 100644 --- a/viewer/lib/worldView.js +++ b/viewer/lib/worldView.js @@ -57,8 +57,8 @@ class WorldView extends EventEmitter { } this._timecycleUpdateInterval = setInterval(() => { - this.emit('timecycleUpdate', { timeOfDay: bot.time.timeOfDay, moonPhase: bot.time.moonPhase }) - }, 750) + this.emitter.emit('timecycleUpdate', { timeOfDay: bot.time.timeOfDay, moonPhase: bot.time.moonPhase }) + }, 1000) } removeListenersFromBot (bot) {