mod3d_base/example_objects/
example_vertices.rs

1//a Imports
2use std::cell::RefCell;
3
4use crate::{
5    BufferData, BufferDataAccessor, BufferElementType, BufferIndexAccessor, ByteBuffer, Renderable,
6    ShortIndex, VertexAttr, Vertices,
7};
8
9//a ExampleBuffers
10//tp ExampleBuffers
11/// This is a monotonically increasing [Vec] of buffers, which are immutable once added to the struct
12///
13/// It allows the buffers to be borrowed (immutably) for the lifetime
14/// of the structure, even if later more buffers are added to the Vec
15///
16/// Can remove the RefCell?
17pub struct Buffers<'buffers> {
18    buffers: RefCell<Vec<Box<dyn ByteBuffer + 'buffers>>>,
19}
20
21//ip Buffers
22impl<'buffers> Buffers<'buffers> {
23    //fp new
24    /// Create a new empty [Buffers]
25    pub fn new() -> Self {
26        let buffers = Vec::new().into();
27        Self { buffers }
28    }
29
30    //mp push
31    /// Push a new [ByteBuffer] implementation and return its index
32    pub fn push(&self, buffer: Box<dyn ByteBuffer>) -> usize {
33        let mut buffers = self.buffers.borrow_mut();
34        let n = buffers.len();
35        buffers.push(buffer);
36        n
37    }
38
39    //ap Borrow a buffer
40    /// Create a new [BufferAccessor] on a particular [ByteBuffer] instance that has already been pushed
41    pub fn buffer(&self, n: usize) -> &'buffers dyn ByteBuffer {
42        let buffers = self.buffers.borrow();
43        assert!(n < buffers.len(), "Buffer index out of range");
44        let buffer = buffers[n].as_ref();
45        unsafe { std::mem::transmute::<&'_ dyn ByteBuffer, &'buffers dyn ByteBuffer>(buffer) }
46    }
47}
48
49//a DataAccessors
50//tp DataAccessors
51/// This structure helps for objects; the data is
52pub struct DataAccessors<'buffers, R: Renderable> {
53    // data might be pinned, but the usage model here is to not permit
54    // data to change once accessors have started to be created, so
55    // the borrowed data (in accessors) cannot be modified once there
56    // are referernces to it.
57    data: Vec<Box<BufferData<'buffers, R>>>,
58    index_accessors: Vec<Box<BufferIndexAccessor<'buffers, R>>>,
59    data_accessors: Vec<Box<BufferDataAccessor<'buffers, R>>>,
60}
61
62//ip DataAccessors
63impl<'buffers, R: Renderable> DataAccessors<'buffers, R> {
64    //fp new
65    /// Create a new [DataAccessors]
66    pub fn new() -> Self {
67        let data = Vec::new();
68        let index_accessors = Vec::new();
69        let data_accessors = Vec::new();
70        Self {
71            data,
72            data_accessors,
73            index_accessors,
74        }
75    }
76
77    //fp push_buffer_data
78    /// Push a new [BufferData] that is a portion of a Buffer
79    pub fn push_buffer_data(
80        &mut self,
81        buffers: &Buffers<'buffers>,
82        buffer_n: usize,
83        byte_offset: u32,
84        byte_length: u32,
85    ) -> usize {
86        let n = self.data.len();
87        let b = buffers.buffer(buffer_n);
88        let data = Box::new(BufferData::new(b, byte_offset, byte_length));
89        self.data.push(data);
90        n
91    }
92
93    //fp push_index_accessor
94    /// Create a new [BufferIndexAccessor] on a particular [BufferData] instance that has already been pushed
95    pub fn push_index_accessor(
96        &mut self,
97        data: usize,
98        num: u32,
99        et: BufferElementType,
100        ofs: u32,
101    ) -> usize {
102        let n = self.index_accessors.len();
103        let d = unsafe {
104            std::mem::transmute::<&BufferData<'_, R>, &'buffers BufferData<'buffers, R>>(
105                &self.data[data],
106            )
107        };
108        let accessor = Box::new(BufferIndexAccessor::new(d, num, et, ofs));
109        self.index_accessors.push(accessor);
110        n
111    }
112
113    //fp push_data_accessor
114    /// Create a new [BufferAccessor] on a particular [BufferData] instance that has already been pushed
115    pub fn push_data_accessor(
116        &mut self,
117        data: usize,
118        num: u32,
119        et: BufferElementType,
120        ofs: u32,
121        stride: u32,
122    ) -> usize {
123        let n = self.data_accessors.len();
124        let d = unsafe {
125            std::mem::transmute::<&BufferData<'_, R>, &'buffers BufferData<'buffers, R>>(
126                &self.data[data],
127            )
128        };
129        let accessor = Box::new(BufferDataAccessor::new(d, num, et, ofs, stride));
130        self.data_accessors.push(accessor);
131        n
132    }
133
134    //ap indices
135    /// Get a buffer-lifetime reference to a buffer-lifetime [BufferIndexAccessor]
136    pub fn indices(&self, n: Option<usize>) -> Option<&'buffers BufferIndexAccessor<'buffers, R>> {
137        if let Some(n) = n {
138            let buffer = self.index_accessors[n].as_ref();
139            Some(unsafe {
140                std::mem::transmute::<
141                    &BufferIndexAccessor<'_, R>,
142                    &'buffers BufferIndexAccessor<'buffers, R>,
143                >(buffer)
144            })
145        } else {
146            None
147        }
148    }
149    //ap data_accessor
150    /// Get a buffer-lifetime reference to a buffer-lifetime [BufferDataAccessor]
151    pub fn data_accessor(&self, n: usize) -> &'buffers BufferDataAccessor<'buffers, R> {
152        assert!(
153            n < self.data_accessors.len(),
154            "Data accessor index out of range"
155        );
156        let buffer = self.data_accessors[n].as_ref();
157        unsafe {
158            std::mem::transmute::<
159                &BufferDataAccessor<'_, R>,
160                &'buffers BufferDataAccessor<'buffers, R>,
161            >(buffer)
162        }
163    }
164}
165
166//a ExampleVertices
167//tp ExampleVertices
168/// This structure provides for creating example objects, particularly with regard to their vertices
169///
170/// It uses arrays of [Pin]ned data structures so that the data can be safely self-referential
171pub struct ExampleVertices<'buffers, R: Renderable> {
172    buffers: Buffers<'buffers>,
173    accessors: DataAccessors<'buffers, R>,
174    vertices: Vec<Vertices<'buffers, R>>,
175}
176
177//ip Default for ExampleVertices
178impl<'a, R: Renderable> Default for ExampleVertices<'a, R> {
179    fn default() -> Self {
180        Self::new()
181    }
182}
183
184//ip ExampleVertices
185impl<'a, R: Renderable> ExampleVertices<'a, R> {
186    //fp new
187    /// Create a new [ExampleVertices]
188    ///
189    /// This should probably not be Pin<Box<>>
190    pub fn new() -> Self {
191        let buffers = Buffers::new();
192        let accessors = DataAccessors::new();
193        let vertices = Vec::new();
194        Self {
195            buffers,
196            accessors,
197            vertices,
198        }
199    }
200
201    //fp push_byte_buffer
202    /// Push a new [ByteBuffer] implementation and return its index
203    pub fn push_byte_buffer(&mut self, buffer: Box<dyn ByteBuffer>) -> usize {
204        let buffer_n = self.buffers.push(buffer);
205        self.accessors
206            .push_buffer_data(&self.buffers, buffer_n, 0, 0)
207    }
208
209    //fp push_index_accessor
210    /// Create a new [BufferAccessor] on a particular [ByteBuffer] instance that has already been pushed
211    pub fn push_index_accessor(
212        &mut self,
213        data: usize,
214        num: u32,
215        et: BufferElementType,
216        ofs: u32,
217    ) -> usize {
218        self.accessors.push_index_accessor(data, num, et, ofs)
219    }
220
221    //fp push_data_accessor
222    /// Create a new [BufferAccessor] on a particular [ByteBuffer] instance that has already been pushed
223    pub fn push_data_accessor(
224        &mut self,
225        data: usize,
226        num: u32,
227        et: BufferElementType,
228        ofs: u32,
229        stride: u32,
230    ) -> usize {
231        self.accessors
232            .push_data_accessor(data, num, et, ofs, stride)
233    }
234
235    //fp push_vertices
236    /// Create a new [Vertices] using a set of indices and positions
237    ///
238    /// This extends the life of the BufferAccessor to that of the ExampleVertices
239    ///
240    /// This is safe as the BufferAccessor's are in the Vec for ExampleVertices
241    pub fn push_vertices(
242        &mut self,
243        indices: Option<usize>,
244        positions: usize,
245        attrs: &[(VertexAttr, usize)],
246    ) -> ShortIndex {
247        let n = self.vertices.len();
248        let i = self.accessors.indices(indices);
249        let v = self.accessors.data_accessor(positions);
250        let mut vertices = Vertices::new(i, v);
251        for (attr, view_id) in attrs {
252            let v = self.accessors.data_accessor(*view_id);
253            vertices.add_attr(*attr, v);
254        }
255        self.vertices.push(vertices);
256        n.into()
257    }
258
259    //fp borrow_vertices
260    /// Borrow a set of vertices; this would allow (if mut!) the vertices to have attributes added
261    pub fn borrow_vertices(&self, vertices: ShortIndex) -> &Vertices<R> {
262        &self.vertices[vertices.as_usize()]
263    }
264}