mirror of
				https://github.com/GayPizzaSpecifications/voxelotl-engine.git
				synced 2025-11-04 10:59:39 +00:00 
			
		
		
		
	model batch untz untz untz
This commit is contained in:
		@ -1,5 +1,4 @@
 | 
			
		||||
 | 
			
		||||
public struct Material {
 | 
			
		||||
public struct Material: Hashable {
 | 
			
		||||
  public var ambient: Color<Float>
 | 
			
		||||
  public var diffuse: Color<Float>
 | 
			
		||||
  public var specular: Color<Float>
 | 
			
		||||
 | 
			
		||||
@ -5,35 +5,67 @@ public struct ModelBatch {
 | 
			
		||||
  private var _active = false
 | 
			
		||||
  private var _cam: Camera!
 | 
			
		||||
  private var _env: Environment!
 | 
			
		||||
  private var _prev: ModelInstance!
 | 
			
		||||
  private var _instances: [Instance]
 | 
			
		||||
 | 
			
		||||
  internal init(_ renderer: Renderer) {
 | 
			
		||||
    self._renderer = renderer
 | 
			
		||||
    self._instances = Array()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //TODO: Sort, Blend
 | 
			
		||||
  mutating func begin(camera: Camera, environment: Environment) {
 | 
			
		||||
  public mutating func begin(camera: Camera, environment: Environment) {
 | 
			
		||||
    self._active = true
 | 
			
		||||
    self._cam = camera
 | 
			
		||||
    self._env = environment
 | 
			
		||||
    self._prev = nil
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  mutating func end() {
 | 
			
		||||
  private mutating func flush() {
 | 
			
		||||
    assert(self._instances.count > 0)
 | 
			
		||||
    if self._instances.count == 1 {
 | 
			
		||||
      let instance = self._instances.first!
 | 
			
		||||
      self._renderer.draw(
 | 
			
		||||
        model:       instance.world,
 | 
			
		||||
        color:       instance.color,
 | 
			
		||||
        mesh:        self._prev.mesh,
 | 
			
		||||
        material:    self._prev.material,
 | 
			
		||||
        environment: self._env,
 | 
			
		||||
        camera:      self._cam)
 | 
			
		||||
    } else {
 | 
			
		||||
      self._renderer.batch(
 | 
			
		||||
        instances:   self._instances,
 | 
			
		||||
        mesh:        self._prev.mesh,
 | 
			
		||||
        material:    self._prev.material,
 | 
			
		||||
        environment: self._env,
 | 
			
		||||
        camera:      self._cam)
 | 
			
		||||
    }
 | 
			
		||||
    self._instances.removeAll(keepingCapacity: true)
 | 
			
		||||
    self._prev = nil
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public mutating func end() {
 | 
			
		||||
    if !self._instances.isEmpty {
 | 
			
		||||
      self.flush()
 | 
			
		||||
    }
 | 
			
		||||
    self._cam    = nil
 | 
			
		||||
    self._env    = nil
 | 
			
		||||
    self._active = false
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  mutating func draw(_ model: ModelInstance, position: SIMD3<Float>, color: Color<Float> = .white
 | 
			
		||||
  public mutating func draw(_ model: ModelInstance, position: SIMD3<Float>, color: Color<Float> = .white
 | 
			
		||||
  ) {
 | 
			
		||||
    self.draw(model, world: .translate(position), color: color)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  mutating func draw(_ model: ModelInstance,
 | 
			
		||||
  public mutating func draw(_ model: ModelInstance,
 | 
			
		||||
    position: SIMD3<Float>, scale: Float, rotation: simd_quatf,
 | 
			
		||||
    color: Color<Float> = .white
 | 
			
		||||
  ) {
 | 
			
		||||
    self.draw(model, position: position, scale: .init(repeating: scale), rotation: rotation, color: color)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  mutating func draw(_ model: ModelInstance,
 | 
			
		||||
  public mutating func draw(_ model: ModelInstance,
 | 
			
		||||
    position: SIMD3<Float>, scale: SIMD3<Float>, rotation: simd_quatf,
 | 
			
		||||
    color: Color<Float> = .white
 | 
			
		||||
  ) {
 | 
			
		||||
@ -44,30 +76,33 @@ public struct ModelBatch {
 | 
			
		||||
    self.draw(model, world: world, color: color)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  mutating func draw(_ model: ModelInstance, world: simd_float4x4, color: Color<Float> = .white) {
 | 
			
		||||
  public mutating func draw(_ model: ModelInstance, world: simd_float4x4, color: Color<Float> = .white) {
 | 
			
		||||
    assert(self._active)
 | 
			
		||||
    self._renderer.draw(
 | 
			
		||||
      model: world,
 | 
			
		||||
      color: color.linear,
 | 
			
		||||
      mesh: model.mesh,
 | 
			
		||||
      material: model.material,
 | 
			
		||||
      environment: self._env,
 | 
			
		||||
      camera: self._cam)
 | 
			
		||||
    if self._prev == nil {
 | 
			
		||||
      self._prev = model
 | 
			
		||||
    } else if model != self._prev {
 | 
			
		||||
      self.flush()
 | 
			
		||||
      self._prev = model
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    self._instances.append(.init(
 | 
			
		||||
      world: world,
 | 
			
		||||
      color: color.linear))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  internal struct Instance {
 | 
			
		||||
    let model: simd_float4x4
 | 
			
		||||
    let world: simd_float4x4
 | 
			
		||||
    let color: Color<Float>
 | 
			
		||||
 | 
			
		||||
    init(model: simd_float4x4, color: Color<Float> = .white) {
 | 
			
		||||
      self.model = model
 | 
			
		||||
    init(world: simd_float4x4, color: Color<Float> = .white) {
 | 
			
		||||
      self.world = world
 | 
			
		||||
      self.color = color
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//TODO: delet
 | 
			
		||||
public struct ModelInstance {
 | 
			
		||||
public struct ModelInstance: Hashable {
 | 
			
		||||
  let mesh: RendererMesh
 | 
			
		||||
  let material: Material
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -452,8 +452,8 @@ public class Renderer {
 | 
			
		||||
      for i in 0..<numInstances {
 | 
			
		||||
        let instance = instances[i]
 | 
			
		||||
        data[i] = VertexShaderInstance(
 | 
			
		||||
          model: instance.model,
 | 
			
		||||
          normalModel: instance.model.inverse.transpose,
 | 
			
		||||
          model: instance.world,
 | 
			
		||||
          normalModel: instance.world.inverse.transpose,
 | 
			
		||||
          color: SIMD4(instance.color))
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -487,10 +487,21 @@ public class Renderer {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public struct RendererMesh {
 | 
			
		||||
  fileprivate let _vertBuf: MTLBuffer
 | 
			
		||||
  fileprivate let _idxBuf: MTLBuffer
 | 
			
		||||
public struct RendererMesh: Hashable {
 | 
			
		||||
  fileprivate let _vertBuf: MTLBuffer, _idxBuf: MTLBuffer
 | 
			
		||||
  public let numIndices: Int
 | 
			
		||||
 | 
			
		||||
  public static func == (lhs: Self, rhs: Self) -> Bool {
 | 
			
		||||
    lhs._vertBuf.gpuAddress == rhs._vertBuf.gpuAddress && lhs._vertBuf.length == rhs._vertBuf.length &&
 | 
			
		||||
    lhs._vertBuf.gpuAddress == rhs._vertBuf.gpuAddress && lhs._vertBuf.length == rhs._vertBuf.length &&
 | 
			
		||||
    lhs.numIndices == rhs.numIndices
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public func hash(into hasher: inout Hasher) {
 | 
			
		||||
    hasher.combine(self._vertBuf.hash)
 | 
			
		||||
    hasher.combine(self._idxBuf.hash)
 | 
			
		||||
    hasher.combine(self.numIndices)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extension MTLClearColor {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user