diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89eb546..85eb982 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,13 +8,13 @@ importers: .: dependencies: - '@types/three': - specifier: ^0.165.0 - version: 0.165.0 three: specifier: ^0.165.0 version: 0.165.0 devDependencies: + '@types/three': + specifier: ^0.165.0 + version: 0.165.0 prettier: specifier: ^3.3.1 version: 3.3.1 diff --git a/public/dirt.png b/public/dirt.png new file mode 100644 index 0000000..0f569ce Binary files /dev/null and b/public/dirt.png differ diff --git a/src/main.ts b/src/main.ts index e543fa0..602ed0f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,6 +4,7 @@ import { OrbitControls } from "three/addons/controls/OrbitControls.js" import Face from "./face" import Block from "./block" import TextureLoader from "./textureLoader" +// import TextureLoader from "./textureLoader" const scene = new THREE.Scene() const camera = new THREE.PerspectiveCamera( @@ -20,7 +21,16 @@ const controls = new OrbitControls(camera, renderer.domElement) controls.update() document.body.appendChild(renderer.domElement) -new TextureLoader("/grass.png", 16, 16, onTextureLoaded) +let grassTextures = [] as THREE.Texture[] +let dirtTextures = [] as THREE.Texture[] + +async function loadTextures() { + const textureLoader = new TextureLoader(16, 16) + grassTextures = await textureLoader.load("/grass.png") + dirtTextures = await textureLoader.load("/dirt.png") + // const debugTextures = await textureLoader.load("/debug.png") + onTextureLoaded() +} // const gridHelper = new THREE.GridHelper(1000, 1000) // scene.add(gridHelper) @@ -83,48 +93,58 @@ function countVisibleFaces( return faceCounts } -function onTextureLoaded(textures: THREE.Texture[]) { +function onTextureLoaded() { const chunk = [] as THREE.Vector3[] const chunkSet = new Set() - const radius = 64 - for (let i = -radius; i < radius; i++) { - for (let j = -radius; j < radius; j++) { - const block = new THREE.Vector3( - i, - Math.ceil(Math.sin(i / 25) * 8 + Math.cos(j / 25) * 8), - j - ) - chunk.push(block) - chunkSet.add(block.toArray().toString()) + const radius = 32 + for (let i = 0; i < radius; i++) { + for (let j = 0; j < radius; j++) { + const max = Math.ceil(Math.sin(i / 30) * 10 + Math.cos(j / 30) * 10) + for (let k = -64; k < max; k++) { + const vec3 = new THREE.Vector3(i, k, j) + chunk.push(vec3) + chunkSet.add(vec3.toArray().toString()) + } } } const faceCounts = countVisibleFaces(chunkSet, chunk) - const faces = [ - new Face("Up", faceCounts.Up, textures[0]), - new Face("North", faceCounts.North, textures[1]), - new Face("South", faceCounts.South, textures[2]), - new Face("East", faceCounts.East, textures[3]), - new Face("West", faceCounts.West, textures[4]), - new Face("Down", faceCounts.Down, textures[5]) + const grassFaces = [ + new Face("Up", faceCounts.Up, grassTextures[0]), + new Face("North", faceCounts.North, grassTextures[1]), + new Face("South", faceCounts.South, grassTextures[2]), + new Face("East", faceCounts.East, grassTextures[3]), + new Face("West", faceCounts.West, grassTextures[4]), + new Face("Down", faceCounts.Down, grassTextures[5]) + ] + + const dirtFaces = [ + new Face("Up", faceCounts.Up, dirtTextures[0]), + new Face("North", faceCounts.North, dirtTextures[1]), + new Face("South", faceCounts.South, dirtTextures[2]), + new Face("East", faceCounts.East, dirtTextures[3]), + new Face("West", faceCounts.West, dirtTextures[4]), + new Face("Down", faceCounts.Down, dirtTextures[5]) ] const cubes = [] as Block[] chunk.forEach((block) => { - cubes.push(new Block(filterFaces(faces, block, chunkSet), block)) + cubes.push(new Block(filterFaces(grassFaces, block, chunkSet), block)) }) - faces.forEach((face) => { + grassFaces.forEach((face) => { if (face.instancedMesh) scene.add(face.instancedMesh) }) } -camera.position.x = 5 -camera.position.y = 5 -camera.position.z = 5 +camera.position.x = 15 +camera.position.y = 15 +camera.position.z = 15 function animate(elapsedTimeMs: number) { renderer.render(scene, camera) controls.update() } + +loadTextures() diff --git a/src/textureLoader.ts b/src/textureLoader.ts index 7cc4943..2584621 100644 --- a/src/textureLoader.ts +++ b/src/textureLoader.ts @@ -1,55 +1,58 @@ -import { NearestFilter, Texture } from "three" +import { NearestFilter, Texture } from "three"; export default class TextureLoader { - private image: HTMLImageElement - private width: number - private height: number + private image: HTMLImageElement; + private width: number; + private height: number; - constructor( - src: string, - width: number, - height: number, - callback: (textures: Texture[]) => void - ) { - this.image = document.createElement("img") - this.image.src = src - this.width = width - this.height = height + constructor(width: number, height: number) { + this.image = document.createElement("img"); + this.width = width; + this.height = height; + } - this.image.addEventListener( - "load", - () => this.onImageLoaded(callback), - false - ) - } + load(src: string): Promise { + return new Promise((resolve, reject) => { + this.image.src = src; + this.image.addEventListener( + "load", + () => { + const textures = this.onImageLoaded(); + resolve(textures); + }, + false + ); + this.image.addEventListener("error", (err) => reject(err), false); + }); + } - private onImageLoaded(callback: (textures: Texture[]) => void) { - const textures = [] as Texture[] + private onImageLoaded(): Texture[] { + const textures = [] as Texture[]; - for (let i = 0; i < 6; i++) { - const canvas = document.createElement("canvas") - canvas.width = this.width - canvas.height = this.height + for (let i = 0; i < 6; i++) { + const canvas = document.createElement("canvas"); + canvas.width = this.width; + canvas.height = this.height; - const context = canvas.getContext("2d") - context?.drawImage( - this.image, - 0, - this.height * i, - this.width, - this.height, - 0, - 0, - this.width, - this.height - ) + const context = canvas.getContext("2d"); + context?.drawImage( + this.image, + 0, + this.height * i, + this.width, + this.height, + 0, + 0, + this.width, + this.height + ); - const texture = new Texture(canvas) - texture.needsUpdate = true - texture.magFilter = NearestFilter - textures.push(texture) - } + const texture = new Texture(canvas); + texture.needsUpdate = true; + texture.magFilter = NearestFilter; + textures.push(texture); + } - callback(textures) - } + return textures; + } }