When exporting, if an object has a parent bone with the same name, add its geometry to the parent bone's model and discard the object itself.

This commit is contained in:
William Herald Snyder 2022-09-29 15:18:58 -04:00
parent 7cfa101d42
commit 5692a60907
2 changed files with 69 additions and 41 deletions

View File

@ -24,24 +24,36 @@ def gather_models(apply_modifiers: bool, export_target: str, skeleton_only: bool
models_list: List[Model] = [] models_list: List[Model] = []
armature_found = None # Composite bones are bones which have geometry.
# If a child object has the same name, it will take said child's geometry.
for uneval_obj in select_objects(export_target): # Pure bones are just bones and after all objects are explored the only
if uneval_obj.type in SKIPPED_OBJECT_TYPES and uneval_obj.name not in parents: # entries remaining in this dict will be bones without geometry.
pure_bones_from_armature = {}
objects_to_export = select_objects(export_target)
for uneval_obj in objects_to_export:
if uneval_obj.type == "ARMATURE":
armature_found = uneval_obj.evaluated_get(depsgraph) if apply_modifiers else uneval_obj
pure_bones_from_armature = expand_armature(armature_found)
break
for uneval_obj in objects_to_export:
if uneval_obj.type == "ARMATURE" or (uneval_obj.type in SKIPPED_OBJECT_TYPES and uneval_obj.name not in parents):
continue continue
if apply_modifiers: obj = uneval_obj.evaluated_get(depsgraph) if apply_modifiers else uneval_obj
obj = uneval_obj.evaluated_get(depsgraph)
else:
obj = uneval_obj
check_for_bad_lod_suffix(obj) check_for_bad_lod_suffix(obj)
if obj.type == "ARMATURE": # Test for a mesh object that is actually a BONE (shares name with bone_parent)
models_list += expand_armature(obj) # If so, we inject geometry into the BONE while not modifying it's transform/name
armature_found = obj if obj.parent_bone and obj.parent_bone in pure_bones_from_armature:
continue model = pure_bones_from_armature[obj.parent_bone]
# Since we found a composite bone, removed it from the dict of pure bones
pure_bones_from_armature.pop(obj.parent_bone)
else:
model = Model() model = Model()
model.name = obj.name model.name = obj.name
model.model_type = get_model_type(obj, skeleton_only) model.model_type = get_model_type(obj, skeleton_only)
@ -92,9 +104,11 @@ def gather_models(apply_modifiers: bool, export_target: str, skeleton_only: bool
if get_is_collision_primitive(obj): if get_is_collision_primitive(obj):
model.collisionprimitive = get_collision_primitive(obj) model.collisionprimitive = get_collision_primitive(obj)
models_list.append(model) models_list.append(model)
# We removed all composite bones after looking through the objects,
# so the bones left are all pure and we add them all here.
models_list += pure_bones_from_armature.values()
return (models_list, armature_found) return (models_list, armature_found)
@ -371,11 +385,17 @@ def select_objects(export_target: str) -> List[bpy.types.Object]:
def expand_armature(armature: bpy.types.Object) -> List[Model]:
def expand_armature(armature: bpy.types.Object) -> Dict[str, Model]:
proper_BONES = get_real_BONES(armature) proper_BONES = get_real_BONES(armature)
bones: List[Model] = [] bones: Dict[str, Model] = {}
for bone in armature.data.bones: for bone in armature.data.bones:
model = Model() model = Model()
@ -390,7 +410,7 @@ def expand_armature(armature: bpy.types.Object) -> List[Model]:
# set model parent to armature parent if there is one # set model parent to armature parent if there is one
else: else:
bone_world_matrix = armature.matrix_world @ transform bone_world_matrix = get_bone_world_matrix(armature, bone.name)
parent_obj = None parent_obj = None
for child_obj in armature.original.children: for child_obj in armature.original.children:
@ -418,6 +438,6 @@ def expand_armature(armature: bpy.types.Object) -> List[Model]:
model.transform.rotation = convert_rotation_space(local_rotation) model.transform.rotation = convert_rotation_space(local_rotation)
model.transform.translation = convert_vector_space(local_translation) model.transform.translation = convert_vector_space(local_translation)
bones.append(model) bones[bone.name] = model
return bones return bones

View File

@ -12,6 +12,14 @@ from .msh_model_utilities import *
from .crc import * from .crc import *
def get_bone_world_matrix(armature: bpy.types.Object, bone_name: str) -> Matrix:
if bone_name in armature.data.bones:
return armature.matrix_world @ armature.data.bones[bone_name].matrix_local
else:
return None
def has_preserved_skeleton(armature : bpy.types.Armature): def has_preserved_skeleton(armature : bpy.types.Armature):
return len(armature.data.swbf_msh_skel) > 0 return len(armature.data.swbf_msh_skel) > 0