summaryrefslogtreecommitdiff
path: root/client/src/render/scene/meshops.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-23 22:45:35 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-23 22:45:35 +0100
commit3344eb2d678f9c5973c8e38083760254b54c20fc (patch)
tree793678d4230dd012285169ba34005064690c7af0 /client/src/render/scene/meshops.rs
parentdd40803458695abcd4100fffb874cc25a71ea758 (diff)
downloadweareserver-3344eb2d678f9c5973c8e38083760254b54c20fc.tar
weareserver-3344eb2d678f9c5973c8e38083760254b54c20fc.tar.bz2
weareserver-3344eb2d678f9c5973c8e38083760254b54c20fc.tar.zst
split scene_prepare to many files
Diffstat (limited to 'client/src/render/scene/meshops.rs')
-rw-r--r--client/src/render/scene/meshops.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/client/src/render/scene/meshops.rs b/client/src/render/scene/meshops.rs
new file mode 100644
index 0000000..0a3f963
--- /dev/null
+++ b/client/src/render/scene/meshops.rs
@@ -0,0 +1,81 @@
+/*
+ wearechat - generic multiplayer game with voip
+ Copyright (C) 2025 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+use glam::{Vec2, Vec3, vec2};
+
+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, norm) in normal_denom.iter().zip(normal.iter_mut()) {
+ *norm /= *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: &[Vec3]) -> Vec<Vec2> {
+ let _ = (index, position);
+ // TODO implement equirectangular projection or something
+ (0..position.len())
+ .map(|i| vec2(i as f32 * 0.01, 0.))
+ .collect()
+}