summaryrefslogtreecommitdiff
path: root/client/src/meshops.rs
blob: e76e02abb7ed924515c357eadeafcf25bb85a1b7 (plain)
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
use glam::{Vec2, Vec3, Vec3A};

pub fn generate_normals(index: &[[u32; 3]], position: &[Vec3]) -> Vec<Vec3> {
    let mut normal_denom = vec![0; position.len()];
    let mut normal = vec![Vec3::ZERO; position.len()];

    for &[a, b, c] in index {
        let pos_a = position[a as usize];
        let pos_b = position[b as usize];
        let pos_c = position[c as usize];

        // TODO is this right?
        let norm = (pos_b - pos_a).cross(pos_c - pos_a).normalize();

        normal[a as usize] += norm;
        normal[b as usize] += norm;
        normal[c as usize] += norm;
        normal_denom[a as usize] += 1;
        normal_denom[b as usize] += 1;
        normal_denom[c as usize] += 1;
    }
    for (denom, tang) in normal_denom.iter().zip(normal.iter_mut()) {
        *tang /= *denom as f32;
    }

    normal
}

pub fn generate_tangents(index: &[[u32; 3]], position: &[Vec3], texcoord: &[Vec2]) -> Vec<Vec3> {
    let mut tangent_denom = vec![0; position.len()];
    let mut tangent = vec![Vec3::ZERO; position.len()];

    for &[a, b, c] in index {
        let (pos_a, uv_a) = (position[a as usize], texcoord[a as usize]);
        let (pos_b, uv_b) = (position[b as usize], texcoord[b as usize]);
        let (pos_c, uv_c) = (position[c as usize], texcoord[c as usize]);

        let pd_ba = pos_b - pos_a;
        let pd_ca = pos_c - pos_a;
        let td_ba = uv_b - uv_a;
        let td_ca = uv_c - uv_a;

        let face_tangent =
            (pd_ba * td_ca.y - pd_ca * td_ba.y) * (td_ba.x * td_ca.y - td_ba.y * td_ca.x);

        tangent[a as usize] += face_tangent;
        tangent[b as usize] += face_tangent;
        tangent[c as usize] += face_tangent;
        tangent_denom[a as usize] += 1;
        tangent_denom[b as usize] += 1;
        tangent_denom[c as usize] += 1;
    }
    for (denom, tang) in tangent_denom.iter().zip(tangent.iter_mut()) {
        *tang /= *denom as f32;
    }

    tangent
}

pub fn generate_texcoords(index: &[[u32; 3]], position: &[Vec3A]) -> Vec<Vec2> {
    let _ = (index, position);
    // TODO implement equirectangular projection
    todo!()
}