mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-03 13:11:33 +00:00
autoupdate damaged chunks, removes instance drawing
This commit is contained in:
@ -1,11 +1,19 @@
|
||||
import Foundation
|
||||
|
||||
public class World {
|
||||
private var _chunks: Dictionary<SIMD3<Int>, Chunk>
|
||||
public typealias ChunkID = SIMD3<Int>
|
||||
@inline(__always) public static func makeID<F: BinaryFloatingPoint>(position: SIMD3<F>) -> ChunkID {
|
||||
makeID(position: SIMD3(Int(floor(position.x)), Int(floor(position.y)), Int(floor(position.z))))
|
||||
}
|
||||
@inline(__always) public static func makeID(position: SIMD3<Int>) -> ChunkID { position &>> Chunk.shift }
|
||||
|
||||
private var _chunks: Dictionary<ChunkID, Chunk>
|
||||
private var _chunkDamage: Set<ChunkID>
|
||||
private var _generator: WorldGenerator
|
||||
|
||||
public init() {
|
||||
self._chunks = [:]
|
||||
self._chunkDamage = []
|
||||
self._generator = WorldGenerator()
|
||||
}
|
||||
|
||||
@ -16,10 +24,32 @@ public class World {
|
||||
}
|
||||
|
||||
func setBlock(at position: SIMD3<Int>, type: BlockType) {
|
||||
self._chunks[position &>> Chunk.shift]?.setBlock(at: position, type: type)
|
||||
// Find the chunk containing the block position
|
||||
let chunkID = position &>> Chunk.shift
|
||||
if let idx = self._chunks.index(forKey: chunkID) {
|
||||
// Set the block and mark the containing chunk for render update
|
||||
self._chunks.values[idx].setBlock(at: position, type: type)
|
||||
self._chunkDamage.insert(chunkID)
|
||||
|
||||
// Mark adjacent chunks for render update when placing along the chunk border
|
||||
let internalPos = position &- chunkID &<< Chunk.shift
|
||||
for (i, ofs) in zip(internalPos.indices, [ SIMD3<Int>.X, .Y, .Z ]) {
|
||||
if internalPos[i] == 0 {
|
||||
let id = chunkID &- ofs
|
||||
if self._chunks.keys.contains(id) {
|
||||
self._chunkDamage.insert(id)
|
||||
}
|
||||
} else if internalPos[i] == Chunk.size - 1 {
|
||||
let id = chunkID &+ ofs
|
||||
if self._chunks.keys.contains(id) {
|
||||
self._chunkDamage.insert(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getChunk(id chunkID: SIMD3<Int>) -> Chunk? {
|
||||
func getChunk(id chunkID: ChunkID) -> Chunk? {
|
||||
self._chunks[chunkID]
|
||||
}
|
||||
|
||||
@ -37,25 +67,28 @@ public class World {
|
||||
for x in 0..<width {
|
||||
let chunkID = SIMD3(x, y, z) &- orig
|
||||
self._chunks[chunkID] = self._generator.makeChunk(id: chunkID)
|
||||
self._chunkDamage.insert(chunkID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generate(chunkID: SIMD3<Int>) {
|
||||
func generate(chunkID: ChunkID) {
|
||||
self._chunks[chunkID] = self._generator.makeChunk(id: chunkID)
|
||||
}
|
||||
|
||||
var instances: [Instance] {
|
||||
self._chunks.values.flatMap { chunk in
|
||||
chunk.compactMap { block, position in
|
||||
if case let .solid(color) = block.type {
|
||||
Instance(
|
||||
position: SIMD3<Float>(position) + 0.5,
|
||||
scale: .init(repeating: 0.5),
|
||||
color: color)
|
||||
} else { nil }
|
||||
self._chunkDamage.insert(chunkID)
|
||||
for i: ChunkID in [ .X, .Y, .Z ] {
|
||||
for otherID in [ chunkID &- i, chunkID &+ i ] {
|
||||
if self._chunks.keys.contains(otherID) {
|
||||
self._chunkDamage.insert(otherID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleRenderDamagedChunks(_ body: (_ id: ChunkID, _ chunk: Chunk) -> Void) {
|
||||
for id in self._chunkDamage {
|
||||
body(id, self._chunks[id]!)
|
||||
}
|
||||
self._chunkDamage.removeAll(keepingCapacity: true)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user