Skip to content

Commit

Permalink
review tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
Baezon committed Sep 27, 2023
1 parent 71216b8 commit f4e3ba0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 80 deletions.
9 changes: 2 additions & 7 deletions pof/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,13 +450,6 @@ impl<R: Read + Seek> Parser<R> {
// now that all the subobjects shouldve have been slotted in, assert that they all exist
let mut sub_objects = ObjVec(sub_objects.into_iter().map(|subobj_opt| subobj_opt.unwrap()).collect());

for i in 0..sub_objects.len() {
if let Some(parent) = sub_objects.0[i].parent {
let id = sub_objects.0[i].obj_id;
sub_objects[parent].children.push(id);
}
}

debris_objs.retain(|id| {
if id.0 < sub_objects.len() as u32 {
sub_objects[*id].is_debris_model = true;
Expand Down Expand Up @@ -512,6 +505,8 @@ impl<R: Read + Seek> Parser<R> {
warnings: Default::default(),
errors: Default::default(),
};

model.recalc_all_children_ids();
model.recheck_warnings(Set::All);
model.recheck_errors(Set::All);
model.recalc_semantic_name_links();
Expand Down
112 changes: 51 additions & 61 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(crate) parent: Option<ObjectId>,
pub parent: Option<ObjectId>,
pub offset: Vec3d,
pub geo_center: Vec3d,
pub bbox: BoundingBox,
Expand Down Expand Up @@ -1492,29 +1492,6 @@ 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 Expand Up @@ -2553,45 +2530,16 @@ impl Model {
}
}

pub fn clean_up(&mut self) {
if let Some(shield) = &mut self.shield_data {
if shield.collision_tree.is_none() {
shield.collision_tree = Some(ShieldData::recalculate_tree(&shield.verts, &shield.polygons));
}
}
}

pub fn make_orphan(&mut self, would_be_orphan: ObjectId) {
if let Some(parent_id) = self.sub_objects[would_be_orphan].parent {
// maintain it's current relative position to the whole model
self.sub_objects[would_be_orphan].offset = self.get_total_subobj_offset(would_be_orphan);

let parent_children = &mut self.sub_objects[parent_id].children;
parent_children.remove(parent_children.iter().position(|child_id| *child_id == would_be_orphan).unwrap());
}
self.sub_objects[would_be_orphan].parent = None;
}

pub fn make_parent(&mut self, new_parent: ObjectId, new_child: ObjectId) -> Option<()> {
if !self.is_obj_id_ancestor(new_parent, new_child) {
self.sub_objects[new_parent].children.push(new_child);
self.sub_objects[new_child].parent = Some(new_parent);

// maintain it's current relative position to the whole model
let offset_from_parents = self.get_total_subobj_offset(new_child) - self.sub_objects[new_child].offset;
self.sub_objects[new_child].offset -= offset_from_parents;

Some(())
} else {
None
pub fn recalc_all_children_ids(&mut self) {
for subobj in self.sub_objects.iter_mut() {
subobj.children.clear();
}
}

pub fn max_verts_norms_per_subobj(&self) -> usize {
if self.version >= Version::V23_00 {
u32::MAX as usize
} else {
u16::MAX as usize
for i in 0..self.sub_objects.len() {
if let Some(parent) = self.sub_objects.0[i].parent {
let id = self.sub_objects.0[i].obj_id;
self.sub_objects[parent].children.push(id);
}
}
}

Expand Down Expand Up @@ -2637,6 +2585,48 @@ impl Model {
}
}

pub fn clean_up(&mut self) {
if let Some(shield) = &mut self.shield_data {
if shield.collision_tree.is_none() {
shield.collision_tree = Some(ShieldData::recalculate_tree(&shield.verts, &shield.polygons));
}
}
}

pub fn make_orphan(&mut self, would_be_orphan: ObjectId) {
if let Some(parent_id) = self.sub_objects[would_be_orphan].parent {
// maintain it's current relative position to the whole model
self.sub_objects[would_be_orphan].offset = self.get_total_subobj_offset(would_be_orphan);

let parent_children = &mut self.sub_objects[parent_id].children;
parent_children.remove(parent_children.iter().position(|child_id| *child_id == would_be_orphan).unwrap());
}
self.sub_objects[would_be_orphan].parent = None;
}

pub fn make_parent(&mut self, new_parent: ObjectId, new_child: ObjectId) -> Option<()> {
if !self.is_obj_id_ancestor(new_parent, new_child) {
self.sub_objects[new_parent].children.push(new_child);
self.sub_objects[new_child].parent = Some(new_parent);

// maintain it's current relative position to the whole model
let offset_from_parents = self.get_total_subobj_offset(new_child) - self.sub_objects[new_child].offset;
self.sub_objects[new_child].offset -= offset_from_parents;

Some(())
} else {
None
}
}

pub fn max_verts_norms_per_subobj(&self) -> usize {
if self.version >= Version::V23_00 {
u32::MAX as usize
} else {
u16::MAX as usize
}
}

pub fn global_import(&mut self, mut import_model: Box<Model>) {
self.header.mass = import_model.header.mass;
self.header.moment_of_inertia = import_model.header.moment_of_inertia;
Expand Down
28 changes: 16 additions & 12 deletions src/ui_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1425,25 +1425,26 @@ impl PofToolsGui {
poly.texture = tex_id_map[&poly.texture];
}

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 import_subobj = &mut import_model.sub_objects[id];
import_subobj.obj_id = obj_id_map[&id];

let new_id = import_obj.obj_id;
// make da swap (or addition)
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 import_subobj.obj_id.0 as usize >= old_subobj_len {
if let Some(parent_id) = import_subobj.parent {
import_subobj.parent = obj_id_map.get(&parent_id).copied();
}

self.model.sub_objects.push(std::mem::take(import_obj));
self.model.sub_objects.push(std::mem::take(import_subobj));
self.model.header.num_subobjects += 1;
} else {
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);
let target_subobj = &mut self.model.sub_objects[import_subobj.obj_id];
// if you're replacing a subobj, you inherit the parent of what you've replaced
import_subobj.parent = target_subobj.parent;

// also inherit position
import_obj.offset = target_obj.offset;
import_subobj.offset = target_subobj.offset;

*target_obj = std::mem::take(import_obj);
*target_subobj = std::mem::take(import_subobj);
}
}
TreeValue::Weapons(WeaponTreeValue::PriBank(idx)) => {
Expand Down Expand Up @@ -1501,5 +1502,8 @@ impl PofToolsGui {
_ => (),
}
}

self.model.recalc_semantic_name_links();
self.model.recalc_all_children_ids();
}
}

0 comments on commit f4e3ba0

Please sign in to comment.