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