1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use crate::resources::Vertex;
use pill_engine::game::TransformComponent;
#[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct Instance {
pub(crate) model_matrix: [[f32; 4]; 4],
pub(crate) normal_matrix: [[f32; 3]; 3],
}
impl Instance {
pub fn new(transform_component: &TransformComponent) -> Instance {
Instance {
model_matrix: cgmath::Matrix4::model(transform_component.position, transform_component.rotation, transform_component.scale).into(),
normal_matrix: cgmath::Matrix3::from_euler_angles(transform_component.rotation).into(),
}
}
}
impl Vertex for Instance {
fn data_layout_descriptor<'a>() -> wgpu::VertexBufferLayout<'a> {
use std::mem;
wgpu::VertexBufferLayout {
array_stride: mem::size_of::<Instance>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &[
wgpu::VertexAttribute {
offset: 0,
shader_location: 5,
format: wgpu::VertexFormat::Float32x4,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
shader_location: 6,
format: wgpu::VertexFormat::Float32x4,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
shader_location: 7,
format: wgpu::VertexFormat::Float32x4,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress,
shader_location: 8,
format: wgpu::VertexFormat::Float32x4,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 16]>() as wgpu::BufferAddress,
shader_location: 9,
format: wgpu::VertexFormat::Float32x3,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 19]>() as wgpu::BufferAddress,
shader_location: 10,
format: wgpu::VertexFormat::Float32x3,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 22]>() as wgpu::BufferAddress,
shader_location: 11,
format: wgpu::VertexFormat::Float32x3,
},
],
}
}
}
pub trait MatrixAngleExt<S: cgmath::BaseFloat> {
fn from_euler_angles(v: cgmath::Vector3<S>) -> Self;
}
pub trait MatrixModelExt<S: cgmath::BaseFloat> {
fn model(position: cgmath::Vector3<S>, rotation: cgmath::Vector3<S>, scale: cgmath::Vector3<S>) -> Self;
}
impl<S: cgmath::BaseFloat> MatrixAngleExt<S> for cgmath::Matrix4<S> {
fn from_euler_angles(v: cgmath::Vector3<S>) -> Self {
#[cfg_attr(rustfmt, rustfmt_skip)]
cgmath::Matrix4::<S>::from(
cgmath::Matrix3::from_angle_z(cgmath::Deg(v.z)) *
cgmath::Matrix3::from_angle_y(cgmath::Deg(v.y)) *
cgmath::Matrix3::from_angle_x(cgmath::Deg(v.x)))
}
}
impl<S: cgmath::BaseFloat> MatrixModelExt<S> for cgmath::Matrix4<S> {
fn model(position: cgmath::Vector3<S>, rotation: cgmath::Vector3<S>, scale: cgmath::Vector3<S>) -> Self {
cgmath::Matrix4::from_translation(position) *
cgmath::Matrix4::from_euler_angles(rotation) *
cgmath::Matrix4::from_nonuniform_scale(scale.x, scale.y, scale.z)
}
}
impl<S: cgmath::BaseFloat> MatrixAngleExt<S> for cgmath::Matrix3<S> {
fn from_euler_angles(v: cgmath::Vector3<S>) -> Self {
cgmath::Matrix3::from_angle_z(cgmath::Deg(v.z)) *
cgmath::Matrix3::from_angle_y(cgmath::Deg(v.y)) *
cgmath::Matrix3::from_angle_x(cgmath::Deg(v.x))
}
}