use crate::math::Vector;
use bytemuck::{Pod, Zeroable};
use slang_hal::{BufferUsages, backend::Backend};
use stensor::tensor::{GpuScalar, GpuTensor};
#[derive(Copy, Clone, PartialEq, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct SimulationParams {
pub gravity: Vector,
#[cfg(feature = "dim2")]
pub padding: f32,
pub dt: f32,
}
#[derive(Copy, Clone, PartialEq, Debug, Default, Pod, Zeroable)]
#[repr(C)]
pub struct IntegratorFlags {
pub implicit: u32,
pub padding0: u32,
pub padding1: u32,
pub padding2: u32,
}
pub struct GpuSimulationParams<B: Backend> {
pub params: GpuScalar<SimulationParams, B>,
pub integrator_flags: GpuScalar<IntegratorFlags, B>,
implicit: bool,
}
impl<B: Backend> GpuSimulationParams<B> {
pub fn new(backend: &B, params: SimulationParams) -> Result<Self, B::Error> {
Ok(Self {
params: GpuTensor::scalar(
backend,
params,
BufferUsages::UNIFORM | BufferUsages::COPY_DST,
)?,
integrator_flags: GpuTensor::scalar(
backend,
IntegratorFlags::default(),
BufferUsages::UNIFORM | BufferUsages::COPY_DST,
)?,
implicit: false,
})
}
pub fn set_implicit(&mut self, backend: &B, implicit: bool) -> Result<(), B::Error> {
if implicit != self.implicit {
self.implicit = implicit;
let flags = IntegratorFlags {
implicit: implicit as u32,
..Default::default()
};
backend.write_buffer(self.integrator_flags.buffer_mut(), 0, &[flags])?;
}
Ok(())
}
pub fn implicit(&self) -> bool {
self.implicit
}
}