I commonly have to work with geometric data, in C it was normal for me to do things like this:
struct Vertex { vec2;}
vector<Vertex> triangle = {{-1, 0}, {0,1}, {1, 0}};
Which is fairly convenient, especially if you start having more nested types, like adding more fields to Vertex.
In rust initializers need to be explicit, so i get things like this:
let triangle : [Vertex; 3] = [
Vertex{position : Vec2::new(-0.5, 0.0), color : Vec3::new(1.0, 0.0, 0.0)},
Vertex{position : Vec2::new(0.0, 0.5), color : Vec3::new(0.0, 1.0, 0.0)},
Vertex{position : Vec2::new(0.5, 0.0), color : Vec3::new(0.0, 0.0, 1.0)},
];
This is a little too much, it becomes tedious to specify the same fields over and over again, and this is not even that bad of a scenario, when you have position, normal and uv fields it becomes a mess.
Is there a way to initialise lists in a more compact way?
CodePudding user response:
You can simplify initialization, this is usually done by implementing From trait.
After that your code may look like
let triangle : [Vertex; 3] = [
([-0.5, 0.0], [1.0, 0.0, 0.0]).into(),
([0.0, -0.5], [0.0, 1.0, 0.0]).into(),
([0.0, -1.0], [0.0, 1.0, 1.0]).into(),
];
Other way is to create fn new(x: f32, y: f32, c1: f32, c2: f32, c3: f32) -> Vertex
:
impl Vertex {
fn new(x: f32, y: f32, c1: f32, c2: f32, c3: f32) -> Vertex {
Self {
position: Vec2{x, y},
color: Vec3{x: c1, y: c2, z: c3}
}
}
}
fn main() {
let triangle : [Vertex; 3] = [
Vertex::new(0.0, 0.1, 0.2, 0.3, 0.4),
Vertex::new(0.1, 0.1, 0.2, 0.3, 0.4),
Vertex::new(0.2, 0.1, 0.2, 0.3, 0.4),
];
}
CodePudding user response:
This may not be terse enough for you, but a very Rust-y pattern is the builder pattern. Your code could look like this:
let triangle: [Vertex; 3] = [
Vertex::new().with_position(-0.5, 0.0).with_color(1.0, 0.0, 0.0),
Vertex::new().with_position(0.0, 0.5).with_color(0.0, 1.0, 0.0),
Vertex::new().with_position(0.5, 0.0).with_color(0.0, 0.0, 1.0),
];
Is this a lot shorter? No. Is it more convenient to write? I think so, but it's certainly subjective.