Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
misode committed Nov 23, 2023
2 parents 617a434 + ef9a328 commit 6d5ec65
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 20 deletions.
40 changes: 30 additions & 10 deletions src/render/ChunkBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Mesh } from './Mesh.js'
import { SpecialRenderer, SpecialRenderers } from './SpecialRenderer.js'

export class ChunkBuilder {
private chunks: Mesh[][][] = []
private chunks: {mesh: Mesh, transparentMesh: Mesh}[][][] = []
private readonly chunkSize: vec3

constructor(
Expand All @@ -24,13 +24,19 @@ export class ChunkBuilder {
}

public updateStructureBuffers(chunkPositions?: vec3[]): void {
if (!this.structure)
return

if (!chunkPositions) {
this.chunks.forEach(x => x.forEach(y => y.forEach(chunk => {
chunk.clear()
chunk.mesh.clear()
chunk.transparentMesh.clear()
})))
} else {
chunkPositions.forEach(chunkPos => {
this.getChunk(chunkPos).clear()
const chunk = this.getChunk(chunkPos)
chunk.mesh.clear()
chunk.transparentMesh.clear()
})
}

Expand Down Expand Up @@ -68,7 +74,11 @@ export class ChunkBuilder {
}
if (!mesh.isEmpty()) {
this.finishChunkMesh(mesh, b.pos)
chunk.merge(mesh)
if (this.resources.getBlockFlags(b.state.getName())?.semi_transparent){
chunk.transparentMesh.merge(mesh)
} else {
chunk.mesh.merge(mesh)
}
}
} catch (e) {
console.error(`Error rendering block ${blockName}`, e)
Expand All @@ -77,23 +87,33 @@ export class ChunkBuilder {

if (!chunkPositions) {
this.chunks.forEach(x => x.forEach(y => y.forEach(chunk => {
chunk.rebuild(this.gl, { pos: true, color: true, texture: true, normal: true, blockPos: true })
chunk.mesh.rebuild(this.gl, { pos: true, color: true, texture: true, normal: true, blockPos: true })
chunk.transparentMesh.rebuild(this.gl, { pos: true, color: true, texture: true, normal: true, blockPos: true })
})))
} else {
chunkPositions.forEach(chunkPos => {
this.getChunk(chunkPos).rebuild(this.gl, { pos: true, color: true, texture: true, normal: true, blockPos: true })
const chunk = this.getChunk(chunkPos)
chunk.mesh.rebuild(this.gl, { pos: true, color: true, texture: true, normal: true, blockPos: true })
chunk.transparentMesh.rebuild(this.gl, { pos: true, color: true, texture: true, normal: true, blockPos: true })
})
}
}

public getMeshes(): Mesh[] {
return this.chunks.flatMap(x => x.flatMap(y => y.flatMap(chunk => chunk ?? [])))
const chunks = this.chunks.flatMap(x => x.flatMap(y => y.flatMap(chunk => chunk ?? [])))
return chunks.flatMap(chunk => chunk.mesh.isEmpty() ? [] : chunk.mesh).concat(chunks.flatMap(chunk => chunk.transparentMesh.isEmpty() ? [] : chunk.transparentMesh))
}

private needsCull(block: PlacedBlock, dir: Direction) {
const neighbor = this.structure.getBlock(BlockPos.towards(block.pos, dir))?.state
if (!neighbor) return false
if (this.resources.getBlockFlags(neighbor.getName())?.opaque) {
const neighborFlags = this.resources.getBlockFlags(neighbor.getName())

if (block.state.getName().equals(neighbor.getName()) && neighborFlags?.self_culling){
return true
}

if (neighborFlags?.opaque) {
return !(dir === Direction.UP && block.state.isFluid())
} else {
return block.state.isFluid() && neighbor.isFluid()
Expand All @@ -112,14 +132,14 @@ export class ChunkBuilder {
}
}

private getChunk(chunkPos: vec3): Mesh {
private getChunk(chunkPos: vec3): {mesh: Mesh, transparentMesh: Mesh} {
const x = Math.abs(chunkPos[0]) * 2 + (chunkPos[0] < 0 ? 1 : 0)
const y = Math.abs(chunkPos[1]) * 2 + (chunkPos[1] < 0 ? 1 : 0)
const z = Math.abs(chunkPos[2]) * 2 + (chunkPos[2] < 0 ? 1 : 0)

if (!this.chunks[x]) this.chunks[x] = []
if (!this.chunks[x][y]) this.chunks[x][y] = []
if (!this.chunks[x][y][z]) this.chunks[x][y][z] = new Mesh()
if (!this.chunks[x][y][z]) this.chunks[x][y][z] = {mesh: new Mesh(), transparentMesh: new Mesh()}

return this.chunks[x][y][z]
}
Expand Down
45 changes: 45 additions & 0 deletions src/render/SpecialRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,49 @@ function chestRenderer(facing: string, type: string, uvProvider: TextureAtlasPro
])).transform(rotation)
}

function decoratedPotRenderer(uvProvider: TextureAtlasProvider){
const id = Identifier.create('decorated_pot')
return dummy(id, uvProvider, {}, new BlockModel(id, undefined, {
0: 'entity/decorated_pot/decorated_pot_side',
1: 'entity/decorated_pot/decorated_pot_base',
}, [
{
from: [1, 0, 1],
to: [15, 16, 15],
faces: {
north: {uv: [1, 0, 15, 16], texture: '#0'},
east: {uv: [1, 0, 15, 16], texture: '#0'},
south: {uv: [1, 0, 15, 16], texture: '#0'},
west: {uv: [1, 0, 15, 16], texture: '#0'},
up: {uv: [0, 6.5, 7, 13.5], texture: '#1'},
down: {uv: [7, 6.5, 14, 13.5], texture: '#1'},
},
},
{
from: [5, 16, 5],
to: [11, 17, 11],
faces: {
north: {uv: [0, 5.5, 3, 6], texture: '#1'},
east: {uv: [3, 5.5, 6, 6], texture: '#1'},
south: {uv: [6, 5.5, 9, 6], texture: '#1'},
west: {uv: [9, 5.5, 12, 6], texture: '#1'},
},
},
{
from: [4, 17, 4],
to: [12, 20, 12],
faces: {
north: {uv: [0, 4, 4, 5.5], texture: '#1'},
east: {uv: [4, 4, 8, 5.5], texture: '#1'},
south: {uv: [8, 4, 12, 5.5], texture: '#1'},
west: {uv: [12, 4, 16, 5.5], texture: '#1'},
up: {uv: [4, 0, 8, 4], texture: '#1'},
down: {uv: [8, 0, 12, 4], texture: '#1'},
},
},
]))
}

export const SpecialRenderer: {
[key: string]: (props: { [key: string]: string }, uvProvider: TextureAtlasProvider, cull: Cull) => any,
} = {
Expand All @@ -89,6 +132,8 @@ export const SpecialRenderer: {
liquidRenderer('lava', parseInt(props.level), uvProvider, cull),
'minecraft:chest': (props, uvProvider) =>
chestRenderer(props.facing || 'south', props.type || 'single', uvProvider),
'minecraft:decorated_pot': (_, uvProvider) =>
decoratedPotRenderer(uvProvider),
}

export const SpecialRenderers = new Set(Object.keys(SpecialRenderer))
13 changes: 3 additions & 10 deletions src/render/StructureRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,10 @@ const fsGrid = `
}
`




type GridBuffers = {
position: WebGLBuffer,
color: WebGLBuffer,
length: number,
}

type BlockFlags = {
export type BlockFlags = {
opaque?: boolean,
semi_transparent?: boolean,
self_culling?: boolean,
}

export interface BlockFlagsProvider {
Expand Down

0 comments on commit 6d5ec65

Please sign in to comment.