From 0f9d4bc8946f6689aeee2f451bc259cccea5d058 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Tue, 14 Nov 2023 23:10:58 +0300 Subject: [PATCH] test --- prismarine-viewer/viewer/lib/viewer.ts | 70 ++++++++++++++++++- .../viewer/lib/worldDataEmitter.ts | 8 ++- src/index.ts | 2 - 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/prismarine-viewer/viewer/lib/viewer.ts b/prismarine-viewer/viewer/lib/viewer.ts index 92860fbf..ca5bc144 100644 --- a/prismarine-viewer/viewer/lib/viewer.ts +++ b/prismarine-viewer/viewer/lib/viewer.ts @@ -21,10 +21,12 @@ export class Viewer { isSneaking: boolean version: string cameraObjectOverride?: THREE.Object3D // for xr + /** default sky color */ + skyColour = new THREE.Color('lightblue') - constructor (public renderer: THREE.WebGLRenderer, numWorkers?: number) { + constructor(public renderer: THREE.WebGLRenderer, numWorkers?: number) { this.scene = new THREE.Scene() - this.scene.background = new THREE.Color('lightblue') + this.scene.background = this.skyColour this.ambientLight = new THREE.AmbientLight(0xcc_cc_cc) this.scene.add(this.ambientLight) @@ -50,6 +52,11 @@ export class Viewer { this.world.resetWorld() this.entities.clear() this.primitives.clear() + + this.scene.background = this.skyColour + this.ambientLight.intensity = 1 + this.directionalLight.intensity = 1 + this.directionalLight.position.set(1, 1, 0.5).normalize() } setVersion (userVersion: string) { @@ -81,6 +88,61 @@ export class Viewer { this.primitives.update(p) } + updateTimecycleLighting (timeOfDay, moonPhase, isRaining) { + if (timeOfDay === undefined) { return } + const lightIntensity = this.calculateIntensity(timeOfDay) + const newSkyColor = `#${this.darkenSkyColour(lightIntensity, isRaining).padStart(6, '0')}` + + function timeToRads (time) { + return time * (Math.PI / 12000) + } + + // Update colours + this.scene.background = new THREE.Color(newSkyColor) + 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.intensity = newAmbientIntensity + this.directionalLight.intensity = newDirectionalIntensity + this.directionalLight.position.set( + Math.cos(timeToRads(timeOfDay)), + Math.sin(timeToRads(timeOfDay)), + 0.2 + ).normalize() + } + + calculateIntensity (currentTicks) { + const transitionStart = 12000 + const transitionEnd = 18000 + const timeInDay = (currentTicks % 24000) + let lightIntensity: number + + if (timeInDay < transitionStart) { + lightIntensity = 1.0 + } else if (timeInDay < transitionEnd) { + lightIntensity = 1 - (timeInDay - transitionStart) / (transitionEnd - transitionStart) + } else { + lightIntensity = (timeInDay - transitionEnd) / (24000 - transitionEnd) + } + + return lightIntensity + } + + /** Darken by factor (0 to black, 0.5 half as bright, 1 unchanged) */ + darkenSkyColour (factor: number, isRaining) { + const skyColour = this.skyColour.getHex() + let r = (skyColour & 0x00_00_FF); + let g = ((skyColour >> 8) & 0x00_FF); + let b = (skyColour >> 16); + if (isRaining) { + r = 111 / 255 + g = 156 / 255 + b = 236 / 255 + } + return (Math.round(r * factor) | + (Math.round(g * factor) << 8) | + (Math.round(b * factor) << 16)).toString(16) + } + setFirstPersonCamera (pos: Vec3 | null, yaw: number, pitch: number, roll = 0) { const cam = this.cameraObjectOverride || this.camera if (pos) { @@ -122,6 +184,10 @@ export class Viewer { this.world.updateViewerPosition(pos) }) + emitter.on('timecycleUpdate', ({ timeOfDay, moonPhase, isRaining }) => { + this.updateTimecycleLighting(timeOfDay, moonPhase, isRaining) + }) + emitter.emit('listening') this.domElement.addEventListener('pointerdown', (evt) => { diff --git a/prismarine-viewer/viewer/lib/worldDataEmitter.ts b/prismarine-viewer/viewer/lib/worldDataEmitter.ts index 9ecb1f43..e303005d 100644 --- a/prismarine-viewer/viewer/lib/worldDataEmitter.ts +++ b/prismarine-viewer/viewer/lib/worldDataEmitter.ts @@ -4,6 +4,7 @@ import { chunkPos } from './simpleUtils' import { generateSpiralMatrix, ViewRect } from 'flying-squid/src/utils' import { Vec3 } from 'vec3' import { EventEmitter } from 'events' +import { BotEvents } from 'mineflayer' export type ChunkPosKey = string type ChunkPos = { x: number, z: number } @@ -54,8 +55,11 @@ export class WorldDataEmitter extends EventEmitter { blockUpdate: (oldBlock: any, newBlock: any) => { const stateId = newBlock.stateId ? newBlock.stateId : ((newBlock.type << 4) | newBlock.metadata) this.emitter.emit('blockUpdate', { pos: oldBlock.position, stateId }) - } - } + }, + time: () => { + this.emitter.emit('timecycleUpdate', { timeOfDay: bot.time.timeOfDay, moonPhase: bot.time.moonPhase, isRaining: bot.isRaining }) + }, + } satisfies Partial this.emitter.on('listening', () => { this.emitter.emit('blockEntities', new Proxy({}, { diff --git a/src/index.ts b/src/index.ts index 948f4500..e1ca2bc4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -560,8 +560,6 @@ async function connect (connectOptions: { worldView.listenToBot(bot) void worldView.init(bot.entity.position) - dayCycle() - // Bot position callback function botPosition () { // this might cause lag, but not sure