use crate::*;
use itertools::*;
impl CreateBuffers for PolygonMesh {
#[inline(always)]
fn buffers(
&self,
vertex_usage: BufferUsages,
index_usage: BufferUsages,
device: &Device,
) -> (BufferHandler, BufferHandler) {
let expanded = self.expands(|attr| AttrVertex {
position: attr.position.cast().unwrap().into(),
uv_coord: attr
.uv_coord
.and_then(|v| Some(v.cast()?.into()))
.unwrap_or([0.0, 0.0]),
normal: attr
.normal
.and_then(|v| Some(v.cast()?.into()))
.unwrap_or([0.0, 0.0, 0.0]),
});
let indices = expanded
.faces()
.triangle_iter()
.flatten()
.map(|x| x as u32)
.collect::<Vec<_>>();
(
BufferHandler::from_slice(expanded.attributes(), device, vertex_usage),
BufferHandler::from_slice(&indices, device, index_usage),
)
}
}
impl Instance for PolygonInstance {
type Shaders = PolygonShaders;
fn standard_shaders(creator: &InstanceCreator) -> PolygonShaders {
creator.polygon_shaders.clone()
}
}
impl ToInstance<PolygonInstance> for PolygonMesh {
type State = PolygonState;
#[inline(always)]
fn to_instance(
&self,
handler: &DeviceHandler,
shaders: &PolygonShaders,
state: &PolygonState,
) -> PolygonInstance {
let (vb, ib) = self.buffers(BufferUsages::VERTEX, BufferUsages::INDEX, handler.device());
PolygonInstance {
polygon: (Arc::new(vb), Arc::new(ib)),
state: state.clone(),
shaders: shaders.clone(),
id: RenderId::generate(),
}
}
}
impl ToInstance<WireFrameInstance> for PolygonMesh {
type State = WireFrameState;
fn to_instance(
&self,
handler: &DeviceHandler,
shaders: &WireShaders,
state: &WireFrameState,
) -> WireFrameInstance {
let device = handler.device();
let positions: Vec<[f32; 3]> = self
.positions()
.iter()
.map(|p| p.cast().unwrap().into())
.collect();
let mut strips = Vec::<u32>::new();
self.faces().face_iter().for_each(|face| {
face.iter().circular_tuple_windows().for_each(|(a, b)| {
strips.extend([a.pos as u32, b.pos as u32]);
});
});
let vb = BufferHandler::from_slice(&positions, device, BufferUsages::VERTEX);
let ib = BufferHandler::from_slice(&strips, device, BufferUsages::INDEX);
WireFrameInstance {
vertices: Arc::new(vb),
strips: Arc::new(ib),
state: state.clone(),
shaders: shaders.clone(),
id: RenderId::generate(),
}
}
}
impl CreateBuffers for StructuredMesh {
#[inline(always)]
fn buffers(
&self,
vertex_usage: BufferUsages,
index_usage: BufferUsages,
device: &Device,
) -> (BufferHandler, BufferHandler) {
let mut vertices = Vec::new();
let (m, n) = (self.positions().len(), self.positions()[0].len());
iproduct!(0..m, 0..n).for_each(|(i, j)| {
vertices.push(AttrVertex {
position: self.positions()[i][j].cast().unwrap().into(),
uv_coord: match self.uv_division() {
Some((udiv, vdiv)) => [udiv[i] as f32, vdiv[j] as f32],
None => [0.0, 0.0],
},
normal: match self.normals() {
Some(normals) => normals[i][j].cast().unwrap().into(),
None => [0.0, 0.0, 0.0],
},
});
});
let mut indices = Vec::<u32>::new();
iproduct!(1..m, 1..n).for_each(|(i, j)| {
indices.extend([
((i - 1) * n + j - 1) as u32,
(i * n + j - 1) as u32,
((i - 1) * n + j) as u32,
((i - 1) * n + j) as u32,
(i * n + j - 1) as u32,
(i * n + j) as u32,
]);
});
(
BufferHandler::from_slice(&vertices, device, vertex_usage),
BufferHandler::from_slice(&indices, device, index_usage),
)
}
}
impl ToInstance<PolygonInstance> for StructuredMesh {
type State = PolygonState;
#[inline(always)]
fn to_instance(
&self,
handler: &DeviceHandler,
shaders: &PolygonShaders,
state: &PolygonState,
) -> PolygonInstance {
let (vb, ib) = self.buffers(BufferUsages::VERTEX, BufferUsages::INDEX, handler.device());
PolygonInstance {
polygon: (Arc::new(vb), Arc::new(ib)),
state: state.clone(),
shaders: shaders.clone(),
id: RenderId::generate(),
}
}
}
impl ToInstance<WireFrameInstance> for StructuredMesh {
type State = WireFrameState;
fn to_instance(
&self,
handler: &DeviceHandler,
shaders: &WireShaders,
state: &WireFrameState,
) -> WireFrameInstance {
let device = handler.device();
let positions: Vec<[f32; 3]> = self
.positions()
.iter()
.flatten()
.map(|p| p.cast().unwrap().into())
.collect();
let mut strips = Vec::<u32>::new();
let len = self.positions()[0].len() as u32;
for i in 1..positions.len() as u32 {
strips.push((i - 1) * len);
strips.push(i * len);
}
for j in 1..len {
strips.push(j - 1);
strips.push(j);
}
for i in 1..self.positions().len() as u32 {
for j in 1..len {
strips.push((i - 1) * len + j);
strips.push(i * len + j);
strips.push(i * len + (j - 1));
strips.push(i * len + j);
}
}
let vb = BufferHandler::from_slice(&positions, device, BufferUsages::VERTEX);
let ib = BufferHandler::from_slice(&strips, device, BufferUsages::INDEX);
WireFrameInstance {
vertices: Arc::new(vb),
strips: Arc::new(ib),
state: state.clone(),
shaders: shaders.clone(),
id: RenderId::generate(),
}
}
}
impl ToInstance<WireFrameInstance> for PolylineCurve<Point3> {
type State = WireFrameState;
fn to_instance(
&self,
handler: &DeviceHandler,
shaders: &WireShaders,
state: &WireFrameState,
) -> WireFrameInstance {
let device = handler.device();
let positions: Vec<[f32; 3]> = self.iter().map(|p| p.cast().unwrap().into()).collect();
let strips: Vec<u32> = (1..positions.len())
.flat_map(|i| vec![i as u32 - 1, i as u32])
.collect();
let vb = BufferHandler::from_slice(&positions, device, BufferUsages::VERTEX);
let ib = BufferHandler::from_slice(&strips, device, BufferUsages::INDEX);
WireFrameInstance {
vertices: Arc::new(vb),
strips: Arc::new(ib),
state: state.clone(),
shaders: shaders.clone(),
id: RenderId::generate(),
}
}
}
impl ToInstance<WireFrameInstance> for Vec<PolylineCurve<Point3>> {
type State = WireFrameState;
fn to_instance(
&self,
handler: &DeviceHandler,
shaders: &WireShaders,
state: &WireFrameState,
) -> WireFrameInstance {
let device = handler.device();
let positions: Vec<[f32; 3]> = self
.iter()
.flat_map(|poly| poly.iter())
.map(|p| p.cast().unwrap().into())
.collect();
let mut counter = 0;
let strips: Vec<u32> = self
.iter()
.flat_map(|poly| {
let len = counter as u32;
counter += poly.len();
(1..poly.len()).flat_map(move |i| vec![len + i as u32 - 1, len + i as u32])
})
.collect();
let vb = BufferHandler::from_slice(&positions, device, BufferUsages::VERTEX);
let ib = BufferHandler::from_slice(&strips, device, BufferUsages::INDEX);
WireFrameInstance {
vertices: Arc::new(vb),
strips: Arc::new(ib),
state: state.clone(),
shaders: shaders.clone(),
id: RenderId::generate(),
}
}
}