Skip to content

Commit

Permalink
move parent/child manipulation to pof crate
Browse files Browse the repository at this point in the history
  • Loading branch information
digama0 committed Sep 26, 2023
1 parent d5be672 commit 71216b8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 44 deletions.
27 changes: 25 additions & 2 deletions pof/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,7 @@ pub enum NameLink {
pub struct SubObject {
pub obj_id: ObjectId,
pub radius: f32,
pub parent: Option<ObjectId>,
pub(crate) parent: Option<ObjectId>,
pub offset: Vec3d,
pub geo_center: Vec3d,
pub bbox: BoundingBox,
Expand All @@ -1420,7 +1420,7 @@ pub struct SubObject {
pub bsp_data: BspData,

// the following fields are derived information
pub children: Vec<ObjectId>,
pub(crate) children: Vec<ObjectId>,
pub is_debris_model: bool,

// "semantic name links", fields derived specifically from their names
Expand Down Expand Up @@ -1492,6 +1492,29 @@ impl SubObject {
pub fn is_subsystem(&self) -> bool {
properties_get_field(&self.properties, "$special") == Some("subsystem")
}

pub fn map_ids(&mut self, map: impl Fn(ObjectId) -> Option<ObjectId>, retain: impl Fn(ObjectId) -> bool) {
// map children and filter out any that werent imported and added
self.children.retain_mut(|id| match map(*id) {
Some(new_id) if retain(*id) => {
*id = new_id;
true
}
_ => false,
});

self.obj_id = map(self.obj_id).unwrap();

if let Some(parent_id) = self.parent {
// if youre adding a subobj, you lose parentage if the parent wasn't imported in some way
self.parent = map(parent_id);
}
}

pub fn inherit_parent_and_children_from(&mut self, other: &Self) {
self.parent = other.parent;
self.children.extend(other.children.iter());
}
}

fn parse_uvec_fvec(props: &str) -> Option<(Vec3d, Vec3d)> {
Expand Down
62 changes: 20 additions & 42 deletions src/ui_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
};

use std::{
collections::{BTreeSet, HashMap},
collections::{hash_map::Entry, BTreeSet, HashMap},
path::PathBuf,
};

Expand Down Expand Up @@ -1409,63 +1409,41 @@ impl PofToolsGui {
// translate old texure ids to new one
let mut tex_id_map = HashMap::new();
for (_, poly) in import_model.pof_model.sub_objects[id].bsp_data.collision_tree.leaves_mut() {
if !tex_id_map.contains_key(&poly.texture) {
'get_a_slot: {
// see if this texture already exists
for (i, tex_name) in self.model.textures.iter().enumerate() {
if import_model.pof_model.textures[poly.texture.0 as usize] == *tex_name {
tex_id_map.insert(poly.texture, TextureId(i as u32));
break 'get_a_slot;
}
}
if let Entry::Vacant(e) = tex_id_map.entry(poly.texture) {
// see if this texture already exists
if let Some(i) = (self.model.textures.iter())
.position(|tex_name| import_model.pof_model.textures[poly.texture.0 as usize] == *tex_name)
{
e.insert(TextureId(i as u32));
} else {
// still here, gotta add a slot i guess
tex_id_map.insert(poly.texture, TextureId(self.model.textures.len() as u32));
e.insert(TextureId(self.model.textures.len() as u32));
self.model.textures.push(import_model.pof_model.textures[poly.texture.0 as usize].clone());
}
}

poly.texture = tex_id_map[&poly.texture];
}

// map children and filter out any that werent imported and added
import_model.sub_objects[id].children.retain_mut(|id| {
// id >= old_subobj_len means it was added, replaced subobjects will inherit their relations regardless
if obj_id_map.contains_key(id) && id.0 as usize >= old_subobj_len {
*id = obj_id_map[id];
true
} else {
false
}
});
let import_obj = &mut import_model.sub_objects[id];
// id >= old_subobj_len means it was added, replaced subobjects will inherit their relations regardless
import_obj.map_ids(|id| obj_id_map.get(&id).copied(), |id| id.0 as usize >= old_subobj_len);

let new_id = import_obj.obj_id;
// make da swap (or addition)
if obj_id_map[&id].0 as usize >= self.model.sub_objects.len() {
if new_id.0 as usize >= self.model.sub_objects.len() {
//assert!(obj_id_map[&id].0 as usize == self.model.sub_objects.len());

if let Some(parent_id) = import_model.sub_objects[id].parent {
if !obj_id_map.contains_key(&parent_id) {
// if youre adding a subobj, you lose parentage if the parent wasn't imported in some way
import_model.sub_objects[id].parent = None;
} else {
import_model.sub_objects[id].parent = Some(obj_id_map[&parent_id]);
}
}

import_model.sub_objects[id].obj_id = obj_id_map[&id];
self.model.sub_objects.push(std::mem::take(&mut import_model.sub_objects[id]));
self.model.sub_objects.push(std::mem::take(import_obj));
self.model.header.num_subobjects += 1;
} else {
// if you're replacing a subobj, you inherit the parent if what you've replaced
import_model.sub_objects[id].parent = self.model.sub_objects[obj_id_map[&id]].parent;
// also inherit children
import_model.sub_objects[id]
.children
.extend(self.model.sub_objects[obj_id_map[&id]].children.iter());
let target_obj = &mut self.model.sub_objects[new_id];
// if you're replacing a subobj, you inherit the parent/children if what you've replaced
import_obj.inherit_parent_and_children_from(target_obj);
// also inherit position
import_model.sub_objects[id].offset = self.model.sub_objects[obj_id_map[&id]].offset;
import_obj.offset = target_obj.offset;

import_model.sub_objects[id].obj_id = obj_id_map[&id];
self.model.sub_objects[obj_id_map[&id]] = std::mem::take(&mut import_model.sub_objects[id]);
*target_obj = std::mem::take(import_obj);
}
}
TreeValue::Weapons(WeaponTreeValue::PriBank(idx)) => {
Expand Down

0 comments on commit 71216b8

Please sign in to comment.