import simd public struct ModelBatch { private let _renderer: Renderer 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() } public mutating func begin(camera: Camera, environment: Environment) { self._active = true self._cam = camera self._env = environment self._prev = nil self._renderer.setupBatch(environment: environment, camera: camera) } private mutating func flush() { assert(self._instances.count > 0) self._renderer.submitBatch(mesh: self._prev.mesh, instances: self._instances, material: self._prev.material) 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 } public mutating func draw(_ model: ModelInstance, position: SIMD3, color: Color = .white ) { self.draw(model, world: .translate(position), color: color) } public mutating func draw(_ model: ModelInstance, position: SIMD3, scale: Float, rotation: simd_quatf, color: Color = .white ) { self.draw(model, position: position, scale: .init(repeating: scale), rotation: rotation, color: color) } public mutating func draw(_ model: ModelInstance, position: SIMD3, scale: SIMD3, rotation: simd_quatf, color: Color = .white ) { let world = .translate(position) * simd_float4x4(rotation) * .scale(scale) self.draw(model, world: world, color: color) } public mutating func draw(_ model: ModelInstance, world: simd_float4x4, color: Color = .white) { assert(self._active) 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 world: simd_float4x4 let color: Color init(world: simd_float4x4, color: Color = .white) { self.world = world self.color = color } } } //TODO: delet public struct ModelInstance: Hashable { let mesh: RendererMesh let material: Material }