/* 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 . */ use crate::{ packets::{Object, Packet, Resource}, resources::Prefab, }; use glam::Vec3A; use std::collections::{BTreeSet, HashMap}; pub struct SceneTree { pub objects: HashMap, } pub struct ObjectData { pub pos: Vec3A, pub rot: Vec3A, pub parent: Object, pub children: BTreeSet, pub pose: Vec, pub res: Resource, } impl Default for SceneTree { fn default() -> Self { Self { objects: Default::default(), } } } impl SceneTree { pub fn packet(&mut self, p: &Packet) { match p { Packet::Add(object, res) => { self.objects.insert(*object, ObjectData { parent: Object(0), pos: Vec3A::ZERO, rot: Vec3A::ZERO, pose: Vec::new(), res: res.clone(), children: BTreeSet::new(), }); } Packet::Remove(object) => { if let Some(o) = self.objects.remove(&object) { for c in o.children { self.reparent(o.parent, c); } } } Packet::Position(object, pos, rot) => { if let Some(o) = self.objects.get_mut(&object) { o.pos = *pos; o.rot = *rot; } } Packet::Pose(object, pose) => { if let Some(o) = self.objects.get_mut(&object) { o.pose = pose.to_vec(); } } Packet::Parent(parent, child) => { self.reparent(*parent, *child); } _ => (), } } pub fn reparent(&mut self, parent: Object, child: Object) { if !self.objects.contains_key(&parent) || !self.objects.contains_key(&child) { return; } if let Some(co) = self.objects.get(&child) { let old_parent = co.parent; if let Some(po) = self.objects.get_mut(&old_parent) { po.children.remove(&child); } } if let Some(po) = self.objects.get_mut(&parent) { po.children.insert(child); } if let Some(co) = self.objects.get_mut(&child) { co.parent = parent; } } pub fn prime_client(&self) -> impl Iterator { self.objects .iter() .map(|(object, data)| { [ Packet::Add(*object, data.res.clone()), Packet::Parent(*object, data.parent), Packet::Position(*object, data.pos, data.rot), ] .into_iter() .chain(if data.pose.is_empty() { None } else { Some(Packet::Pose(*object, data.pose.clone())) }) }) .flatten() } }