From d5fd3b9976d2fa567c235217dd45b154ba53fad3 Mon Sep 17 00:00:00 2001 From: Five-Damned-Dollarz <79036198+Five-Damned-Dollarz@users.noreply.github.com> Date: Tue, 16 Feb 2021 21:22:52 +1100 Subject: [PATCH] Improved exported bounding boxes, still not perfect but definitely reasonable --- src/abc.py | 6 +++++- src/builder.py | 14 ++++++++++++-- src/reader_abc_v6_pc.py | 10 +++++----- src/writer_abc_v6_pc.py | 16 ++++++++-------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/abc.py b/src/abc.py index c5553d6..4f8b57c 100644 --- a/src/abc.py +++ b/src/abc.py @@ -141,6 +141,9 @@ def __init__(self): self.child_count = 0 # Version 6 specific + self.bounds_min=Vector() + self.bounds_max=Vector() + self.md_vert_count = 0 self.md_vert_list = [] @@ -200,7 +203,8 @@ def __init__(self): self.node_keyframe_transforms = [] # Version 6 specific - + self.bounds_min=Vector() + self.bounds_max=Vector() # Note this should line up with md_vert_list, and go on for md_vert_count * keyframe_count # List of 3 chars (verts) self.vertex_deformations = [] diff --git a/src/builder.py b/src/builder.py index 2955cbc..3e918cf 100644 --- a/src/builder.py +++ b/src/builder.py @@ -154,6 +154,15 @@ def from_armature(armature_object): node.bind_matrix = matrix + # ABC v6 specific + # FIXME: disgusting, can this be done better? + for piece in model.pieces: + for lod in piece.lods: + for vertex in lod.vertices: + if vertex.weights[0].node_index==bone_index: + node.bounds_min=Vector((min(node.bounds_min.x, vertex.location.x), min(node.bounds_min.y, vertex.location.y), min(node.bounds_min.z, vertex.location.z))) + node.bounds_max=Vector((max(node.bounds_min.x, vertex.location.x), max(node.bounds_min.y, vertex.location.y), max(node.bounds_min.z, vertex.location.z))) + #print("Processed", node.name, node.bind_matrix) node.child_count = len(bone.children) model.nodes.append(node) @@ -189,7 +198,8 @@ def from_armature(armature_object): print("Processing animation %s" % action.name) animation = Animation() animation.name = action.name - animation.extents = mesh_object.dimensions # TODO: actually calculate the bounds of each animation; mesh/armature_object.bound_box[0]/[-1] maybe? + animation.bounds_min=Vector(mesh_object.bound_box[0]) # will using mesh_object here break if there's multiple mesh + animation.bounds_max=Vector(mesh_object.bound_box[6]) # objects using the same armature as a parent? DON'T DO THAT armature_object.animation_data.action = action @@ -284,7 +294,7 @@ def from_armature(armature_object): ''' AnimBindings ''' anim_binding = AnimBinding() anim_binding.name = 'base' - animation.extents = Vector((10, 10, 10)) + anim_binding.extents = Vector((10, 10, 10)) model.anim_bindings.append(anim_binding) return model \ No newline at end of file diff --git a/src/reader_abc_v6_pc.py b/src/reader_abc_v6_pc.py index e6eb86d..6dee035 100644 --- a/src/reader_abc_v6_pc.py +++ b/src/reader_abc_v6_pc.py @@ -153,8 +153,8 @@ def _read_node(self, f): node = Node() # These may be needed to calculate the position... - bounds_min = self._read_vector(f) - bounds_max = self._read_vector(f) + node.bounds_min = self._read_vector(f) + node.bounds_max = self._read_vector(f) # Bind matrix is set after we read in animations! @@ -204,11 +204,11 @@ def _read_animation(self, f): animation = Animation() animation.name = self._read_string(f) animation_length = unpack('I', f)[0] - bounds_min = self._read_vector(f) - bounds_max = self._read_vector(f) + animation.bounds_min = self._read_vector(f) + animation.bounds_max = self._read_vector(f) # ? - animation.extents = bounds_max + animation.extents = animation.bounds_max animation.keyframe_count = unpack('I', f)[0] animation.keyframes = [self._read_keyframe(f) for _ in range(animation.keyframe_count)] diff --git a/src/writer_abc_v6_pc.py b/src/writer_abc_v6_pc.py index 3e14302..98f3aff 100644 --- a/src/writer_abc_v6_pc.py +++ b/src/writer_abc_v6_pc.py @@ -97,7 +97,7 @@ def __init__(self, name, data): normal=vertex.normal.normalized()*127 buffer.extend(struct.pack('3b', int(normal.x), int(-normal.y), int(normal.z))) buffer.extend(struct.pack('B', vertex.weights[0].node_index)) # TODO: error out on more than a single weight? - buffer.extend(struct.pack('2H', 0, 0)) # TODO: lod related, I think? + buffer.extend(struct.pack('2H', 0, 0)) # TODO: lod related, I think? sections.append(Section('Geometry', bytes(buffer))) @@ -114,8 +114,8 @@ def __init__(self, name, data): node.flags=self._flag_tris break - buffer.extend(self._vector_to_bytes(Vector((-10, -10, -10)))) # TODO: min bounds - buffer.extend(self._vector_to_bytes(Vector((10, 10, 10)))) # TODO: max bounds + buffer.extend(self._vector_to_bytes(node.bounds_min)) + buffer.extend(self._vector_to_bytes(node.bounds_max)) buffer.extend(self._string_to_bytes(node.name)) buffer.extend(struct.pack('H', node.index)) buffer.extend(struct.pack('B', node.flags)) @@ -133,13 +133,13 @@ def __init__(self, name, data): for anim in model.animations: buffer.extend(self._string_to_bytes(anim.name)) buffer.extend(struct.pack('I', int(anim.keyframes[-1].time))) # final keyframe time; playing past final keyframe's time seems unpredictable - buffer.extend(self._vector_to_bytes(-anim.extents/2)) # TODO: min bounds - buffer.extend(self._vector_to_bytes(anim.extents/2)) # TODO: max bounds + buffer.extend(self._vector_to_bytes(anim.bounds_min)) + buffer.extend(self._vector_to_bytes(anim.bounds_max)) buffer.extend(struct.pack('I', len(anim.keyframes))) for keyframe in anim.keyframes: buffer.extend(struct.pack('I', int(keyframe.time))) - buffer.extend(self._vector_to_bytes(-anim.extents/2)) # TODO: min bounds - buffer.extend(self._vector_to_bytes(anim.extents/2)) # TODO: max bounds + buffer.extend(self._vector_to_bytes(anim.bounds_min)) # TODO: actual keyframe bounding boxes + buffer.extend(self._vector_to_bytes(anim.bounds_max)) buffer.extend(self._string_to_bytes(keyframe.string)) for node_transform_list in anim.node_keyframe_transforms: @@ -159,7 +159,7 @@ def __init__(self, name, data): buffer=bytearray() for anim in model.animations: - buffer.extend(self._vector_to_bytes(anim.extents)) + buffer.extend(self._vector_to_bytes(-anim.bounds_min+anim.bounds_max)) sections.append(Section('AnimDims', bytes(buffer)))