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
use crate::{Mesh3D, ToMesh3D};
use rfw_backend::Mesh3dFlags;
use rfw_math::*;
pub struct Quad3D {
pub normal: Vec3,
pub position: Vec3,
pub width: f32,
pub height: f32,
pub material_id: u32,
vertices: [Vec3; 6],
normals: [Vec3; 6],
uvs: [Vec2; 6],
material_ids: [u32; 2],
}
#[allow(dead_code)]
impl Quad3D {
pub fn new<T: Into<[f32; 3]>>(
normal: T,
position: T,
width: f32,
height: f32,
material_id: u32,
) -> Quad3D {
let material_id = material_id.max(0);
let uvs = [vec2(0.0, 0.0); 6];
let material_ids = [material_id as u32; 2];
let normal = Vec3::from(normal.into());
let position = Vec3::from(position.into());
let (vertices, normals) = Quad3D::generate_render_data(position, normal, width, height);
Quad3D {
normal,
position,
width,
height,
material_id,
vertices,
normals,
uvs,
material_ids,
}
}
fn generate_render_data(pos: Vec3, n: Vec3, width: f32, height: f32) -> ([Vec3; 6], [Vec3; 6]) {
let normal = n.normalize();
let tmp = if normal.x > 0.9 {
Vec3::new(0.0, 1.0, 0.0)
} else {
Vec3::new(1.0, 0.0, 0.0)
};
let tangent: Vec3 = 0.5 * width * normal.cross(tmp).normalize();
let bi_tangent: Vec3 = 0.5 * height * tangent.normalize().cross(normal);
let vertices: [Vec3; 6] = [
pos - bi_tangent - tangent,
pos + bi_tangent - tangent,
pos - bi_tangent + tangent,
pos + bi_tangent - tangent,
pos + bi_tangent + tangent,
pos - bi_tangent + tangent,
];
let normals = [normal.clone(); 6];
(vertices, normals)
}
}
impl ToMesh3D for Quad3D {
fn into_mesh_3d(self) -> Mesh3D {
Mesh3D::new(
self.vertices.to_vec(),
self.normals.to_vec(),
Vec::new(),
Vec::new(),
self.uvs.to_vec(),
self.material_ids.to_vec(),
Mesh3dFlags::default(),
Some("quad"),
)
}
}