mirror of
				https://github.com/GayPizzaSpecifications/voxelotl-engine.git
				synced 2025-11-04 10:59:39 +00:00 
			
		
		
		
	turn the ChunkID type alias into a real type
This commit is contained in:
		@ -64,6 +64,7 @@ add_executable(Voxelotl MACOSX_BUNDLE
 | 
				
			|||||||
  ChunkMeshGeneration.swift
 | 
					  ChunkMeshGeneration.swift
 | 
				
			||||||
  CubeMeshBuilder.swift
 | 
					  CubeMeshBuilder.swift
 | 
				
			||||||
  ChunkMeshBuilder.swift
 | 
					  ChunkMeshBuilder.swift
 | 
				
			||||||
 | 
					  ChunkID.swift
 | 
				
			||||||
  World.swift
 | 
					  World.swift
 | 
				
			||||||
  Raycast.swift
 | 
					  Raycast.swift
 | 
				
			||||||
  Camera.swift
 | 
					  Camera.swift
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,8 @@ import Foundation
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public struct ChunkGeneration {
 | 
					public struct ChunkGeneration {
 | 
				
			||||||
  private let queue: OperationQueue
 | 
					  private let queue: OperationQueue
 | 
				
			||||||
  private let localReadyChunks = ConcurrentDictionary<SIMD3<Int>, Chunk>()
 | 
					  private let localReadyChunks = ConcurrentDictionary<ChunkID, Chunk>()
 | 
				
			||||||
  private var generatingChunkSet = Set<SIMD3<Int>>()
 | 
					  private var generatingChunkSet = Set<ChunkID>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  weak var world: World?
 | 
					  weak var world: World?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,18 +21,18 @@ public struct ChunkGeneration {
 | 
				
			|||||||
    self.generatingChunkSet.removeAll()
 | 
					    self.generatingChunkSet.removeAll()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public mutating func generate(chunkID: SIMD3<Int>) {
 | 
					  public mutating func generate(chunkID: ChunkID) {
 | 
				
			||||||
    if generatingChunkSet.insert(chunkID).inserted {
 | 
					    if generatingChunkSet.insert(chunkID).inserted {
 | 
				
			||||||
      self.queueGenerateJob(chunkID: chunkID)
 | 
					      self.queueGenerateJob(chunkID: chunkID)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  func queueGenerateJob(chunkID: SIMD3<Int>) {
 | 
					  func queueGenerateJob(chunkID: ChunkID) {
 | 
				
			||||||
    self.queue.addOperation {
 | 
					    self.queue.addOperation {
 | 
				
			||||||
      guard let world = self.world else {
 | 
					      guard let world = self.world else {
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      let chunk = world.generateSingleChunkUncommitted(chunkID: chunkID)
 | 
					      let chunk = world.generateSingleChunkUncommitted(id: chunkID)
 | 
				
			||||||
      self.localReadyChunks[chunkID] = chunk
 | 
					      self.localReadyChunks[chunkID] = chunk
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -41,12 +41,12 @@ public struct ChunkGeneration {
 | 
				
			|||||||
    guard let world = self.world else {
 | 
					    guard let world = self.world else {
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let centerChunkID = World.makeID(position: position)
 | 
					    let centerChunkID = ChunkID(fromPosition: position)
 | 
				
			||||||
    let range = -2...2
 | 
					    let range = -2...2
 | 
				
			||||||
    for z in range {
 | 
					    for z in range {
 | 
				
			||||||
      for y in range {
 | 
					      for y in range {
 | 
				
			||||||
        for x in range {
 | 
					        for x in range {
 | 
				
			||||||
          let chunkID = centerChunkID &+ SIMD3(x, y, z)
 | 
					          let chunkID = centerChunkID &+ ChunkID(x, y, z)
 | 
				
			||||||
          if world.getChunk(id: chunkID) == nil {
 | 
					          if world.getChunk(id: chunkID) == nil {
 | 
				
			||||||
            self.generate(chunkID: chunkID)
 | 
					            self.generate(chunkID: chunkID)
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@ -69,7 +69,7 @@ public struct ChunkGeneration {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (chunkID, chunk) in self.localReadyChunks.take() {
 | 
					    for (chunkID, chunk) in self.localReadyChunks.take() {
 | 
				
			||||||
      world.addChunk(chunkID: chunkID, chunk: chunk)
 | 
					      world.addChunk(id: chunkID, chunk: chunk)
 | 
				
			||||||
      self.generatingChunkSet.remove(chunkID)
 | 
					      self.generatingChunkSet.remove(chunkID)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										44
									
								
								Sources/Voxelotl/ChunkID.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Sources/Voxelotl/ChunkID.swift
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					import simd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public struct ChunkID: Hashable {
 | 
				
			||||||
 | 
					  public let id: SIMD3<Int>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  init(id: SIMD3<Int>) {
 | 
				
			||||||
 | 
					    self.id = id
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public extension ChunkID {
 | 
				
			||||||
 | 
					  @inline(__always) init(_ x: Int, _ y: Int, _ z: Int) { self.id = SIMD3(x, y, z) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @inline(__always) init<F: BinaryFloatingPoint>(fromPosition position: SIMD3<F>) {
 | 
				
			||||||
 | 
					    self.init(fromPosition: SIMD3(Int(floor(position.x)), Int(floor(position.y)), Int(floor(position.z))))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  @inline(__always) init(fromPosition position: SIMD3<Int>) { self.id = position &>> Chunk.shift }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @inline(__always) func getPosition() -> SIMD3<Int> { self.id &<< Chunk.shift }
 | 
				
			||||||
 | 
					  @inline(__always) func getPosition(offset: SIMD3<Int>) -> SIMD3<Int> { self.id &<< Chunk.shift &+ offset }
 | 
				
			||||||
 | 
					  @inline(__always) func getFloatPosition() -> SIMD3<Float> { SIMD3<Float>(self.id) * Float(Chunk.size) }
 | 
				
			||||||
 | 
					  @inline(__always) func getFloatPosition(offset: SIMD3<Float>) -> SIMD3<Float> {
 | 
				
			||||||
 | 
					    SIMD3<Float>(self.id) * Float(Chunk.size) + offset
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @inline(__always) static func &+ (lhs: Self, rhs: Self) -> Self { .init(id: lhs.id &+ rhs.id) }
 | 
				
			||||||
 | 
					  @inline(__always) static func &- (lhs: Self, rhs: Self) -> Self { .init(id: lhs.id &- rhs.id) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public extension ChunkID {
 | 
				
			||||||
 | 
					  @inlinable func distance(_ other: Self) -> Float {
 | 
				
			||||||
 | 
					    simd_distance(SIMD3<Float>(self.id), SIMD3<Float>(other.id))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public extension ChunkID {
 | 
				
			||||||
 | 
					  static var axes: [Self] {
 | 
				
			||||||
 | 
					    [ .X, .Y, .Z ].map { (j: SIMD3<Int>) -> Self in .init(id: j) }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public extension SIMD3 where Scalar == Int {
 | 
				
			||||||
 | 
					  init(_ chunkID: ChunkID) { self = chunkID.id }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -2,7 +2,7 @@ import Foundation
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public struct ChunkMeshGeneration {
 | 
					public struct ChunkMeshGeneration {
 | 
				
			||||||
  private let queue: OperationQueue
 | 
					  private let queue: OperationQueue
 | 
				
			||||||
  private let localReadyMeshes = ConcurrentDictionary<SIMD3<Int>, RendererMesh?>()
 | 
					  private let localReadyMeshes = ConcurrentDictionary<ChunkID, RendererMesh?>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  weak var game: Game?
 | 
					  weak var game: Game?
 | 
				
			||||||
  weak var renderer: Renderer?
 | 
					  weak var renderer: Renderer?
 | 
				
			||||||
@ -14,11 +14,11 @@ public struct ChunkMeshGeneration {
 | 
				
			|||||||
    self.queue.qualityOfService = .userInitiated
 | 
					    self.queue.qualityOfService = .userInitiated
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public mutating func generate(chunkID: SIMD3<Int>, chunk: Chunk) {
 | 
					  public mutating func generate(id chunkID: ChunkID, chunk: Chunk) {
 | 
				
			||||||
    self.queueGenerateJob(chunkID: chunkID, chunk: chunk)
 | 
					    self.queueGenerateJob(id: chunkID, chunk: chunk)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  func queueGenerateJob(chunkID: SIMD3<Int>, chunk: Chunk) {
 | 
					  func queueGenerateJob(id chunkID: ChunkID, chunk: Chunk) {
 | 
				
			||||||
    self.queue.addOperation {
 | 
					    self.queue.addOperation {
 | 
				
			||||||
      guard let game = self.game else {
 | 
					      guard let game = self.game else {
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ class Game: GameDelegate {
 | 
				
			|||||||
  var projection: matrix_float4x4 = .identity
 | 
					  var projection: matrix_float4x4 = .identity
 | 
				
			||||||
  var world = World(generator: StandardWorldGenerator())
 | 
					  var world = World(generator: StandardWorldGenerator())
 | 
				
			||||||
  var cubeMesh: RendererMesh?
 | 
					  var cubeMesh: RendererMesh?
 | 
				
			||||||
  var renderChunks = [SIMD3<Int>: RendererMesh?]()
 | 
					  var renderChunks = [ChunkID: RendererMesh?]()
 | 
				
			||||||
  var chunkMeshGeneration: ChunkMeshGeneration!
 | 
					  var chunkMeshGeneration: ChunkMeshGeneration!
 | 
				
			||||||
  var modelBatch: ModelBatch!
 | 
					  var modelBatch: ModelBatch!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -77,9 +77,9 @@ class Game: GameDelegate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Regenerate current chunk
 | 
					    // Regenerate current chunk
 | 
				
			||||||
    if regenChunk {
 | 
					    if regenChunk {
 | 
				
			||||||
      let chunkID = World.makeID(position: self.player.position)
 | 
					      let chunkID = ChunkID(fromPosition: self.player.position)
 | 
				
			||||||
      let chunk = self.world.generateSingleChunkUncommitted(chunkID: chunkID)
 | 
					      let chunk = self.world.generateSingleChunkUncommitted(id: chunkID)
 | 
				
			||||||
      self.world.addChunk(chunkID: chunkID, chunk: chunk)
 | 
					      self.world.addChunk(id: chunkID, chunk: chunk)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self.world.generateAdjacentChunksIfNeeded(position: self.player.position)
 | 
					    self.world.generateAdjacentChunksIfNeeded(position: self.player.position)
 | 
				
			||||||
@ -101,7 +101,7 @@ class Game: GameDelegate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Update chunk meshes if needed
 | 
					    // Update chunk meshes if needed
 | 
				
			||||||
    self.world.handleRenderDamagedChunks { id, chunk in
 | 
					    self.world.handleRenderDamagedChunks { id, chunk in
 | 
				
			||||||
      self.chunkMeshGeneration.generate(chunkID: id, chunk: chunk)
 | 
					      self.chunkMeshGeneration.generate(id: id, chunk: chunk)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    self.chunkMeshGeneration.acceptReadyMeshes()
 | 
					    self.chunkMeshGeneration.acceptReadyMeshes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -111,7 +111,7 @@ class Game: GameDelegate {
 | 
				
			|||||||
      if chunk == nil {
 | 
					      if chunk == nil {
 | 
				
			||||||
        continue
 | 
					        continue
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      let drawPos = SIMD3<Float>(id &<< Chunk.shift)
 | 
					      let drawPos = id.getFloatPosition()
 | 
				
			||||||
      self.modelBatch.draw(.init(mesh: chunk!, material: Self.material), position: drawPos)
 | 
					      self.modelBatch.draw(.init(mesh: chunk!, material: Self.material), position: drawPos)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ struct StandardWorldGenerator: WorldGenerator {
 | 
				
			|||||||
    self.colorNoise   = .init(random: &random, octaves: 15, frequency: 0.006667, amplitude: 3)
 | 
					    self.colorNoise   = .init(random: &random, octaves: 15, frequency: 0.006667, amplitude: 3)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public func makeChunk(id chunkID: SIMD3<Int>) -> Chunk {
 | 
					  public func makeChunk(id chunkID: ChunkID) -> Chunk {
 | 
				
			||||||
    let blockFunc = { (height: Float, position: SIMD3<Float>) -> BlockType in
 | 
					    let blockFunc = { (height: Float, position: SIMD3<Float>) -> BlockType in
 | 
				
			||||||
#if true
 | 
					#if true
 | 
				
			||||||
      let value = height + self.terrainNoise.get(position * SIMD3(1, 2, 1))
 | 
					      let value = height + self.terrainNoise.get(position * SIMD3(1, 2, 1))
 | 
				
			||||||
@ -37,7 +37,7 @@ struct StandardWorldGenerator: WorldGenerator {
 | 
				
			|||||||
        saturation: 0.47, value: 0.9).linear)
 | 
					        saturation: 0.47, value: 0.9).linear)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let chunkOrigin = chunkID &<< Chunk.shift
 | 
					    let chunkOrigin = chunkID.getPosition()
 | 
				
			||||||
    var chunk = Chunk(position: chunkOrigin)
 | 
					    var chunk = Chunk(position: chunkOrigin)
 | 
				
			||||||
    for z in 0..<Chunk.size {
 | 
					    for z in 0..<Chunk.size {
 | 
				
			||||||
      for x in 0..<Chunk.size {
 | 
					      for x in 0..<Chunk.size {
 | 
				
			||||||
 | 
				
			|||||||
@ -10,8 +10,8 @@ struct TerrorTowerGenerator: WorldGenerator {
 | 
				
			|||||||
    self.noise2 = LayeredNoise(random: &random, octaves: 3, frequency: 0.1)
 | 
					    self.noise2 = LayeredNoise(random: &random, octaves: 3, frequency: 0.1)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public func makeChunk(id chunkID: SIMD3<Int>) -> Chunk {
 | 
					  public func makeChunk(id chunkID: ChunkID) -> Chunk {
 | 
				
			||||||
    let chunkOrigin = chunkID &<< Chunk.shift
 | 
					    let chunkOrigin = chunkID.getPosition()
 | 
				
			||||||
    var chunk = Chunk(position: chunkOrigin)
 | 
					    var chunk = Chunk(position: chunkOrigin)
 | 
				
			||||||
    chunk.fill(allBy: { position in
 | 
					    chunk.fill(allBy: { position in
 | 
				
			||||||
      let fpos = SIMD3<Float>(chunkOrigin &+ position)
 | 
					      let fpos = SIMD3<Float>(chunkOrigin &+ position)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
public protocol WorldGenerator {
 | 
					public protocol WorldGenerator {
 | 
				
			||||||
  mutating func reset(seed: UInt64)
 | 
					  mutating func reset(seed: UInt64)
 | 
				
			||||||
  func makeChunk(id: SIMD3<Int>) -> Chunk
 | 
					  func makeChunk(id: ChunkID) -> Chunk
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal extension RandomProvider where Output == UInt64, Self: RandomSeedable, SeedType == UInt64 {
 | 
					internal extension RandomProvider where Output == UInt64, Self: RandomSeedable, SeedType == UInt64 {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,6 @@
 | 
				
			|||||||
import Foundation
 | 
					import Foundation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class World {
 | 
					public class World {
 | 
				
			||||||
  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 _chunks: Dictionary<ChunkID, Chunk>
 | 
				
			||||||
  private var _chunkDamage: Set<ChunkID>
 | 
					  private var _chunkDamage: Set<ChunkID>
 | 
				
			||||||
  private var _generator: any WorldGenerator
 | 
					  private var _generator: any WorldGenerator
 | 
				
			||||||
@ -21,24 +15,24 @@ public class World {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  func getBlock(at position: SIMD3<Int>) -> Block {
 | 
					  func getBlock(at position: SIMD3<Int>) -> Block {
 | 
				
			||||||
    return if let chunk = self._chunks[position &>> Chunk.shift] {
 | 
					    if let chunk = self._chunks[ChunkID(fromPosition: position)] {
 | 
				
			||||||
      chunk.getBlock(at: position)
 | 
					      chunk.getBlock(at: position)
 | 
				
			||||||
    } else { Block(.air) }
 | 
					    } else { Block(.air) }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  func setBlock(at position: SIMD3<Int>, type: BlockType) {
 | 
					  func setBlock(at position: SIMD3<Int>, type: BlockType) {
 | 
				
			||||||
    // Find the chunk containing the block position
 | 
					    // Find the chunk containing the block position
 | 
				
			||||||
    let chunkID = position &>> Chunk.shift
 | 
					    let chunkID = ChunkID(fromPosition: position)
 | 
				
			||||||
    if let idx = self._chunks.index(forKey: chunkID) {
 | 
					    if let idx = self._chunks.index(forKey: chunkID) {
 | 
				
			||||||
      // Set the block and mark the containing chunk for render update
 | 
					      // Set the block and mark the containing chunk for render update
 | 
				
			||||||
      self._chunks.values[idx].setBlock(at: position, type: type)
 | 
					      self._chunks.values[idx].setBlock(at: position, type: type)
 | 
				
			||||||
      self._chunkDamage.insert(chunkID)
 | 
					      self._chunkDamage.insert(chunkID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Mark adjacent chunks for render update when placing along the chunk border
 | 
					      // Mark adjacent chunks for render update when placing along the chunk border
 | 
				
			||||||
      let internalPos = position &- chunkID &<< Chunk.shift
 | 
					      let internalPos = position &- chunkID.getPosition()
 | 
				
			||||||
      for (i, ofs) in zip(internalPos.indices, [ SIMD3<Int>.X, .Y, .Z ]) {
 | 
					      for (i, ofs) in zip(internalPos.indices, [ SIMD3<Int>.X, .Y, .Z ]) {
 | 
				
			||||||
        if internalPos[i] == 0 {
 | 
					        if internalPos[i] == 0 {
 | 
				
			||||||
          let id = chunkID &- ofs
 | 
					          let id = chunkID &- ChunkID(id: ofs)
 | 
				
			||||||
          if let other = self._chunks[id],
 | 
					          if let other = self._chunks[id],
 | 
				
			||||||
            // optim: Damage adjacent chunk only if block is touching a solid
 | 
					            // optim: Damage adjacent chunk only if block is touching a solid
 | 
				
			||||||
            case .solid = other.getBlock(internal: (internalPos &- ofs) & Chunk.mask).type
 | 
					            case .solid = other.getBlock(internal: (internalPos &- ofs) & Chunk.mask).type
 | 
				
			||||||
@ -46,7 +40,7 @@ public class World {
 | 
				
			|||||||
            self._chunkDamage.insert(id)
 | 
					            self._chunkDamage.insert(id)
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        } else if internalPos[i] == Chunk.size - 1 {
 | 
					        } else if internalPos[i] == Chunk.size - 1 {
 | 
				
			||||||
          let id = chunkID &+ ofs
 | 
					          let id = chunkID &+ ChunkID(id: ofs)
 | 
				
			||||||
          if let other = self._chunks[id],
 | 
					          if let other = self._chunks[id],
 | 
				
			||||||
            // optim: Damage adjacent chunk only if block is touching a solid
 | 
					            // optim: Damage adjacent chunk only if block is touching a solid
 | 
				
			||||||
            case .solid = other.getBlock(internal: (internalPos &+ ofs) & Chunk.mask).type
 | 
					            case .solid = other.getBlock(internal: (internalPos &+ ofs) & Chunk.mask).type
 | 
				
			||||||
@ -62,7 +56,7 @@ public class World {
 | 
				
			|||||||
    self._chunks[chunkID]
 | 
					    self._chunks[chunkID]
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public func forEachChunk(_ body: @escaping (_ id: SIMD3<Int>, _ chunk: Chunk) throws -> Void) rethrows {
 | 
					  public func forEachChunk(_ body: @escaping (_ id: ChunkID, _ chunk: Chunk) throws -> Void) rethrows {
 | 
				
			||||||
    for i in self._chunks {
 | 
					    for i in self._chunks {
 | 
				
			||||||
      try body(i.key, i.value)
 | 
					      try body(i.key, i.value)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -80,14 +74,14 @@ public class World {
 | 
				
			|||||||
    for z in 0..<depth {
 | 
					    for z in 0..<depth {
 | 
				
			||||||
      for y in 0..<height {
 | 
					      for y in 0..<height {
 | 
				
			||||||
        for x in 0..<width {
 | 
					        for x in 0..<width {
 | 
				
			||||||
          let chunkID = SIMD3(x, y, z) &- orig
 | 
					          let chunkID = ChunkID(id: SIMD3(x, y, z) &- orig)
 | 
				
			||||||
          self._chunkGeneration.generate(chunkID: chunkID)
 | 
					          self._chunkGeneration.generate(chunkID: chunkID)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  func generateSingleChunkUncommitted(chunkID: SIMD3<Int>) -> Chunk {
 | 
					  func generateSingleChunkUncommitted(id chunkID: ChunkID) -> Chunk {
 | 
				
			||||||
    self._generator.makeChunk(id: chunkID)
 | 
					    self._generator.makeChunk(id: chunkID)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -95,10 +89,10 @@ public class World {
 | 
				
			|||||||
    self._chunkGeneration.generateAdjacentIfNeeded(position: position)
 | 
					    self._chunkGeneration.generateAdjacentIfNeeded(position: position)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public func addChunk(chunkID: ChunkID, chunk: Chunk) {
 | 
					  public func addChunk(id chunkID: ChunkID, chunk: Chunk) {
 | 
				
			||||||
    self._chunks[chunkID] = chunk
 | 
					    self._chunks[chunkID] = chunk
 | 
				
			||||||
    self._chunkDamage.insert(chunkID)
 | 
					    self._chunkDamage.insert(chunkID)
 | 
				
			||||||
    for i: ChunkID in [ .X, .Y, .Z ] {
 | 
					    for i in ChunkID.axes {
 | 
				
			||||||
      for otherID in [ chunkID &- i, chunkID &+ i ] {
 | 
					      for otherID in [ chunkID &- i, chunkID &+ i ] {
 | 
				
			||||||
        if self._chunks.keys.contains(otherID) {
 | 
					        if self._chunks.keys.contains(otherID) {
 | 
				
			||||||
          self._chunkDamage.insert(otherID)
 | 
					          self._chunkDamage.insert(otherID)
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user