wgpu_3dgs_core/buffer/
model_transform.rs

1use glam::*;
2use wgpu::util::DeviceExt;
3
4use crate::{BufferWrapper, FixedSizeBufferWrapper, FixedSizeBufferWrapperError};
5
6/// The model transformation buffer.
7///
8/// This buffer holds the model transformation data, including position, rotation, and scale.
9/// It is used to transform the model from model space to world space.
10#[derive(Debug, Clone)]
11pub struct ModelTransformBuffer(wgpu::Buffer);
12
13impl ModelTransformBuffer {
14    /// Create a new model transformation buffer.
15    pub fn new(device: &wgpu::Device) -> Self {
16        let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
17            label: Some("Model transform Buffer"),
18            contents: bytemuck::bytes_of(&ModelTransformPod::default()),
19            usage: Self::DEFAULT_USAGES,
20        });
21
22        Self(buffer)
23    }
24
25    /// Update the model transformation buffer.
26    pub fn update(&self, queue: &wgpu::Queue, pos: Vec3, rot: Quat, scale: Vec3) {
27        self.update_with_pod(queue, &ModelTransformPod::new(pos, rot, scale));
28    }
29
30    /// Update the model transformation buffer with [`ModelTransformPod`].
31    pub fn update_with_pod(&self, queue: &wgpu::Queue, pod: &ModelTransformPod) {
32        queue.write_buffer(&self.0, 0, bytemuck::bytes_of(pod));
33    }
34}
35
36impl BufferWrapper for ModelTransformBuffer {
37    fn buffer(&self) -> &wgpu::Buffer {
38        &self.0
39    }
40}
41
42impl From<ModelTransformBuffer> for wgpu::Buffer {
43    fn from(wrapper: ModelTransformBuffer) -> Self {
44        wrapper.0
45    }
46}
47
48impl TryFrom<wgpu::Buffer> for ModelTransformBuffer {
49    type Error = FixedSizeBufferWrapperError;
50
51    fn try_from(buffer: wgpu::Buffer) -> Result<Self, Self::Error> {
52        Self::verify_buffer_size(&buffer).map(|()| Self(buffer))
53    }
54}
55
56impl FixedSizeBufferWrapper for ModelTransformBuffer {
57    type Pod = ModelTransformPod;
58}
59
60/// The POD representation of a model transformation.
61#[repr(C)]
62#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
63pub struct ModelTransformPod {
64    pub pos: Vec3A,
65    pub rot: Quat,
66    pub scale: Vec3A,
67}
68
69impl ModelTransformPod {
70    /// Create a new model transformation.
71    pub const fn new(pos: Vec3, rot: Quat, scale: Vec3) -> Self {
72        Self {
73            pos: Vec3A::from_array(pos.to_array()),
74            rot,
75            scale: Vec3A::from_array(scale.to_array()),
76        }
77    }
78}
79
80impl Default for ModelTransformPod {
81    fn default() -> Self {
82        Self::new(Vec3::ZERO, Quat::IDENTITY, Vec3::ONE)
83    }
84}