Allow passing glam vector types as vertex attributes (#6442)

Allow passing `Vec`s of glam vector types as vertex attributes.
Alternative to #4548 and #2719

Also used some macros to cut down on all the repetition.

# Migration Guide
Implementations of `From<Vec<[u16; 4]>>` and `From<Vec<[u8; 4]>>` for `VertexAttributeValues` have been removed.
I you're passing either `Vec<[u16; 4]>` or `Vec<[u8; 4]>` into `Mesh::insert_attribute` it will now require wrapping it with right the `VertexAttributeValues` enum variant. 

Co-authored-by: devil-ira <justthecooldude@gmail.com>
This commit is contained in:
ira 2022-11-04 03:45:17 +00:00
parent 97f7a1a99c
commit 2c5d072e76
3 changed files with 230 additions and 311 deletions

View File

@ -25,6 +25,7 @@
//! ``` //! ```
use crate::mesh::VertexAttributeValues; use crate::mesh::VertexAttributeValues;
use bevy_math::{IVec2, IVec3, IVec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4};
use thiserror::Error; use thiserror::Error;
#[derive(Debug, Clone, Error)] #[derive(Debug, Clone, Error)]
@ -45,328 +46,125 @@ impl FromVertexAttributeError {
} }
} }
impl From<Vec<f32>> for VertexAttributeValues { macro_rules! impl_from {
fn from(vec: Vec<f32>) -> Self { ($from:ty, $variant:tt) => {
VertexAttributeValues::Float32(vec) impl From<Vec<$from>> for VertexAttributeValues {
} fn from(vec: Vec<$from>) -> Self {
} VertexAttributeValues::$variant(vec)
impl From<Vec<i32>> for VertexAttributeValues {
fn from(vec: Vec<i32>) -> Self {
VertexAttributeValues::Sint32(vec)
}
}
impl From<Vec<u32>> for VertexAttributeValues {
fn from(vec: Vec<u32>) -> Self {
VertexAttributeValues::Uint32(vec)
}
}
impl From<Vec<[f32; 2]>> for VertexAttributeValues {
fn from(vec: Vec<[f32; 2]>) -> Self {
VertexAttributeValues::Float32x2(vec)
}
}
impl From<Vec<[i32; 2]>> for VertexAttributeValues {
fn from(vec: Vec<[i32; 2]>) -> Self {
VertexAttributeValues::Sint32x2(vec)
}
}
impl From<Vec<[u32; 2]>> for VertexAttributeValues {
fn from(vec: Vec<[u32; 2]>) -> Self {
VertexAttributeValues::Uint32x2(vec)
}
}
impl From<Vec<[f32; 3]>> for VertexAttributeValues {
fn from(vec: Vec<[f32; 3]>) -> Self {
VertexAttributeValues::Float32x3(vec)
}
}
impl From<Vec<[i32; 3]>> for VertexAttributeValues {
fn from(vec: Vec<[i32; 3]>) -> Self {
VertexAttributeValues::Sint32x3(vec)
}
}
impl From<Vec<[u32; 3]>> for VertexAttributeValues {
fn from(vec: Vec<[u32; 3]>) -> Self {
VertexAttributeValues::Uint32x3(vec)
}
}
impl From<Vec<[f32; 4]>> for VertexAttributeValues {
fn from(vec: Vec<[f32; 4]>) -> Self {
VertexAttributeValues::Float32x4(vec)
}
}
impl From<Vec<[i32; 4]>> for VertexAttributeValues {
fn from(vec: Vec<[i32; 4]>) -> Self {
VertexAttributeValues::Sint32x4(vec)
}
}
impl From<Vec<[u32; 4]>> for VertexAttributeValues {
fn from(vec: Vec<[u32; 4]>) -> Self {
VertexAttributeValues::Uint32x4(vec)
}
}
impl From<Vec<[u16; 4]>> for VertexAttributeValues {
fn from(vec: Vec<[u16; 4]>) -> Self {
VertexAttributeValues::Uint16x4(vec)
}
}
impl From<Vec<[u8; 4]>> for VertexAttributeValues {
fn from(vec: Vec<[u8; 4]>) -> Self {
VertexAttributeValues::Unorm8x4(vec)
}
}
impl TryFrom<VertexAttributeValues> for Vec<[u8; 4]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Uint8x4(value) | VertexAttributeValues::Unorm8x4(value) => {
Ok(value)
} }
_ => Err(FromVertexAttributeError::new::<Self>(value)),
} }
} };
} }
impl TryFrom<VertexAttributeValues> for Vec<[i8; 4]> { macro_rules! impl_from_into {
type Error = FromVertexAttributeError; ($from:ty, $variant:tt) => {
impl From<Vec<$from>> for VertexAttributeValues {
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> { fn from(vec: Vec<$from>) -> Self {
match value { let vec: Vec<_> = vec.into_iter().map(|t| t.into()).collect();
VertexAttributeValues::Sint8x4(value) | VertexAttributeValues::Snorm8x4(value) => { VertexAttributeValues::$variant(vec)
Ok(value)
} }
_ => Err(FromVertexAttributeError::new::<Self>(value)),
} }
} };
} }
impl TryFrom<VertexAttributeValues> for Vec<[u8; 2]> { impl_from!(f32, Float32);
type Error = FromVertexAttributeError; impl_from!([f32; 2], Float32x2);
impl_from_into!(Vec2, Float32x2);
impl_from!([f32; 3], Float32x3);
impl_from_into!(Vec3, Float32x3);
impl_from_into!(Vec3A, Float32x3);
impl_from!([f32; 4], Float32x4);
impl_from_into!(Vec4, Float32x4);
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> { impl_from!(i32, Sint32);
match value { impl_from!([i32; 2], Sint32x2);
VertexAttributeValues::Uint8x2(value) | VertexAttributeValues::Unorm8x2(value) => { impl_from_into!(IVec2, Sint32x2);
Ok(value) impl_from!([i32; 3], Sint32x3);
impl_from_into!(IVec3, Sint32x3);
impl_from!([i32; 4], Sint32x4);
impl_from_into!(IVec4, Sint32x4);
impl_from!(u32, Uint32);
impl_from!([u32; 2], Uint32x2);
impl_from_into!(UVec2, Uint32x2);
impl_from!([u32; 3], Uint32x3);
impl_from_into!(UVec3, Uint32x3);
impl_from!([u32; 4], Uint32x4);
impl_from_into!(UVec4, Uint32x4);
macro_rules! impl_try_from {
($into:ty, $($variant:tt), +) => {
impl TryFrom<VertexAttributeValues> for Vec<$into> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
$(VertexAttributeValues::$variant(value)) |+ => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
} }
_ => Err(FromVertexAttributeError::new::<Self>(value)),
} }
} };
} }
impl TryFrom<VertexAttributeValues> for Vec<[i8; 2]> { macro_rules! impl_try_from_into {
type Error = FromVertexAttributeError; ($into:ty, $($variant:tt), +) => {
impl TryFrom<VertexAttributeValues> for Vec<$into> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> { fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value { match value {
VertexAttributeValues::Sint8x2(value) | VertexAttributeValues::Snorm8x2(value) => { $(VertexAttributeValues::$variant(value)) |+ => {
Ok(value) Ok(value.into_iter().map(|t| t.into()).collect())
}
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
} }
_ => Err(FromVertexAttributeError::new::<Self>(value)),
} }
} };
} }
impl TryFrom<VertexAttributeValues> for Vec<[i16; 4]> { impl_try_from!(f32, Float32);
type Error = FromVertexAttributeError; impl_try_from!([f32; 2], Float32x2);
impl_try_from_into!(Vec2, Float32x2);
impl_try_from!([f32; 3], Float32x3);
impl_try_from_into!(Vec3, Float32x3);
impl_try_from_into!(Vec3A, Float32x3);
impl_try_from!([f32; 4], Float32x4);
impl_try_from_into!(Vec4, Float32x4);
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> { impl_try_from!(i32, Sint32);
match value { impl_try_from!([i32; 2], Sint32x2);
VertexAttributeValues::Sint16x4(value) | VertexAttributeValues::Snorm16x4(value) => { impl_try_from_into!(IVec2, Sint32x2);
Ok(value) impl_try_from!([i32; 3], Sint32x3);
} impl_try_from_into!(IVec3, Sint32x3);
_ => Err(FromVertexAttributeError::new::<Self>(value)), impl_try_from!([i32; 4], Sint32x4);
} impl_try_from_into!(IVec4, Sint32x4);
}
}
impl TryFrom<VertexAttributeValues> for Vec<[u16; 4]> { impl_try_from!(u32, Uint32);
type Error = FromVertexAttributeError; impl_try_from!([u32; 2], Uint32x2);
impl_try_from_into!(UVec2, Uint32x2);
impl_try_from!([u32; 3], Uint32x3);
impl_try_from_into!(UVec3, Uint32x3);
impl_try_from!([u32; 4], Uint32x4);
impl_try_from_into!(UVec4, Uint32x4);
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> { impl_try_from!([i8; 2], Sint8x2, Snorm8x2);
match value { impl_try_from!([i8; 4], Sint8x4, Snorm8x4);
VertexAttributeValues::Uint16x4(value) | VertexAttributeValues::Unorm16x4(value) => {
Ok(value)
}
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[u16; 2]> { impl_try_from!([u8; 2], Uint8x2, Unorm8x2);
type Error = FromVertexAttributeError; impl_try_from!([u8; 4], Uint8x4, Unorm8x4);
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> { impl_try_from!([i16; 2], Sint16x2, Snorm16x2);
match value { impl_try_from!([i16; 4], Sint16x4, Snorm16x4);
VertexAttributeValues::Uint16x2(value) | VertexAttributeValues::Unorm16x2(value) => {
Ok(value)
}
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[i16; 2]> { impl_try_from!([u16; 2], Uint16x2, Unorm16x2);
type Error = FromVertexAttributeError; impl_try_from!([u16; 4], Uint16x4, Unorm16x4);
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Sint16x2(value) | VertexAttributeValues::Snorm16x2(value) => {
Ok(value)
}
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[u32; 4]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Uint32x4(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[i32; 4]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Sint32x4(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[f32; 4]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Float32x4(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[u32; 3]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Uint32x3(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[i32; 3]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Sint32x3(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[f32; 3]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Float32x3(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[u32; 2]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Uint32x2(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[i32; 2]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Sint32x2(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<[f32; 2]> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Float32x2(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<u32> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Uint32(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<i32> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Sint32(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
impl TryFrom<VertexAttributeValues> for Vec<f32> {
type Error = FromVertexAttributeError;
fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
match value {
VertexAttributeValues::Float32(value) => Ok(value),
_ => Err(FromVertexAttributeError::new::<Self>(value)),
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use bevy_math::{IVec2, IVec3, IVec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4};
use super::VertexAttributeValues; use super::VertexAttributeValues;
#[test] #[test]
fn f32() { fn f32() {
@ -416,6 +214,19 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn vec2() {
let buffer = vec![Vec2::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Float32x2(_)));
let result_into: Vec<Vec2> = values.clone().try_into().unwrap();
let result_from: Vec<Vec2> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn i32_2() { fn i32_2() {
let buffer = vec![[0; 2]; 10]; let buffer = vec![[0; 2]; 10];
@ -428,6 +239,19 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn ivec2() {
let buffer = vec![IVec2::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Sint32x2(_)));
let result_into: Vec<IVec2> = values.clone().try_into().unwrap();
let result_from: Vec<IVec2> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn u32_2() { fn u32_2() {
let buffer = vec![[0_u32; 2]; 10]; let buffer = vec![[0_u32; 2]; 10];
@ -440,6 +264,19 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn uvec2() {
let buffer = vec![UVec2::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Uint32x2(_)));
let result_into: Vec<UVec2> = values.clone().try_into().unwrap();
let result_from: Vec<UVec2> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn f32_3() { fn f32_3() {
let buffer = vec![[0.0; 3]; 10]; let buffer = vec![[0.0; 3]; 10];
@ -452,6 +289,32 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn vec3() {
let buffer = vec![Vec3::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Float32x3(_)));
let result_into: Vec<Vec3> = values.clone().try_into().unwrap();
let result_from: Vec<Vec3> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test]
fn vec3a() {
let buffer = vec![Vec3A::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Float32x3(_)));
let result_into: Vec<Vec3A> = values.clone().try_into().unwrap();
let result_from: Vec<Vec3A> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn i32_3() { fn i32_3() {
let buffer = vec![[0; 3]; 10]; let buffer = vec![[0; 3]; 10];
@ -464,6 +327,19 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn ivec3() {
let buffer = vec![IVec3::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Sint32x3(_)));
let result_into: Vec<IVec3> = values.clone().try_into().unwrap();
let result_from: Vec<IVec3> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn u32_3() { fn u32_3() {
let buffer = vec![[0_u32; 3]; 10]; let buffer = vec![[0_u32; 3]; 10];
@ -476,6 +352,19 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn uvec3() {
let buffer = vec![UVec3::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Uint32x3(_)));
let result_into: Vec<UVec3> = values.clone().try_into().unwrap();
let result_from: Vec<UVec3> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn f32_4() { fn f32_4() {
let buffer = vec![[0.0; 4]; 10]; let buffer = vec![[0.0; 4]; 10];
@ -488,6 +377,19 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn vec4() {
let buffer = vec![Vec4::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Float32x4(_)));
let result_into: Vec<Vec4> = values.clone().try_into().unwrap();
let result_from: Vec<Vec4> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn i32_4() { fn i32_4() {
let buffer = vec![[0; 4]; 10]; let buffer = vec![[0; 4]; 10];
@ -500,6 +402,19 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn ivec4() {
let buffer = vec![IVec4::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Sint32x4(_)));
let result_into: Vec<IVec4> = values.clone().try_into().unwrap();
let result_from: Vec<IVec4> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn u32_4() { fn u32_4() {
let buffer = vec![[0_u32; 4]; 10]; let buffer = vec![[0_u32; 4]; 10];
@ -512,6 +427,19 @@ mod tests {
assert!(error.is_err()); assert!(error.is_err());
} }
#[test]
fn uvec4() {
let buffer = vec![UVec4::ZERO; 10];
let values = VertexAttributeValues::from(buffer.clone());
assert!(matches!(values, VertexAttributeValues::Uint32x4(_)));
let result_into: Vec<UVec4> = values.clone().try_into().unwrap();
let result_from: Vec<UVec4> = Vec::try_from(values.clone()).unwrap();
let error: Result<Vec<u32>, _> = values.try_into();
assert_eq!(buffer, result_into);
assert_eq!(buffer, result_from);
assert!(error.is_err());
}
#[test] #[test]
fn correct_message() { fn correct_message() {
let buffer = vec![[0_u32; 4]; 3]; let buffer = vec![[0_u32; 4]; 3];

View File

@ -94,16 +94,11 @@ pub struct LineList {
impl From<LineList> for Mesh { impl From<LineList> for Mesh {
fn from(line: LineList) -> Self { fn from(line: LineList) -> Self {
let mut vertices = vec![];
for (start, end) in line.lines {
vertices.push(start.to_array());
vertices.push(end.to_array());
}
// This tells wgpu that the positions are list of lines // This tells wgpu that the positions are list of lines
// where every pair is a start and end point // where every pair is a start and end point
let mut mesh = Mesh::new(PrimitiveTopology::LineList); let mut mesh = Mesh::new(PrimitiveTopology::LineList);
let vertices: Vec<_> = line.lines.into_iter().flat_map(|(a, b)| [a, b]).collect();
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices); mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices);
mesh mesh
} }
@ -117,16 +112,11 @@ pub struct LineStrip {
impl From<LineStrip> for Mesh { impl From<LineStrip> for Mesh {
fn from(line: LineStrip) -> Self { fn from(line: LineStrip) -> Self {
let mut vertices = vec![];
for pos in line.points {
vertices.push(pos.to_array());
}
// This tells wgpu that the positions are a list of points // This tells wgpu that the positions are a list of points
// where a line will be drawn between each consecutive point // where a line will be drawn between each consecutive point
let mut mesh = Mesh::new(PrimitiveTopology::LineStrip); let mut mesh = Mesh::new(PrimitiveTopology::LineStrip);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices); mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, line.points);
mesh mesh
} }
} }

View File

@ -8,7 +8,7 @@ use bevy::{
prelude::*, prelude::*,
render::mesh::{ render::mesh::{
skinning::{SkinnedMesh, SkinnedMeshInverseBindposes}, skinning::{SkinnedMesh, SkinnedMeshInverseBindposes},
Indices, PrimitiveTopology, Indices, PrimitiveTopology, VertexAttributeValues,
}, },
}; };
use rand::Rng; use rand::Rng;
@ -77,8 +77,9 @@ fn setup(
// This means that a maximum of 4 joints can affect a single vertex. // This means that a maximum of 4 joints can affect a single vertex.
mesh.insert_attribute( mesh.insert_attribute(
Mesh::ATTRIBUTE_JOINT_INDEX, Mesh::ATTRIBUTE_JOINT_INDEX,
vec![ // Need to be explicit here as [u16; 4] could be either Uint16x4 or Unorm16x4.
[0u16, 0, 0, 0], VertexAttributeValues::Uint16x4(vec![
[0, 0, 0, 0],
[0, 0, 0, 0], [0, 0, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
@ -88,7 +89,7 @@ fn setup(
[0, 1, 0, 0], [0, 1, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
], ]),
); );
// Set mesh vertex joint weights for mesh skinning. // Set mesh vertex joint weights for mesh skinning.
// Each vertex gets 4 joint weights corresponding to the 4 joint indices assigned to it. // Each vertex gets 4 joint weights corresponding to the 4 joint indices assigned to it.