From 7b9f5c9cfbb785ea0f364e57197a7a2f548548ef Mon Sep 17 00:00:00 2001 From: Will Snyder Date: Thu, 6 Oct 2022 10:23:13 -0700 Subject: [PATCH] Prune segments with empty triangle strips. ZE and most versions of ZETools require triangle strips. --- .../io_scene_swbf_msh/msh_model_utilities.py | 19 +++++++++++++++++++ .../io_scene_swbf_msh/msh_scene_utilities.py | 16 +++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/addons/io_scene_swbf_msh/msh_model_utilities.py b/addons/io_scene_swbf_msh/msh_model_utilities.py index fb73a40..bf98ecf 100644 --- a/addons/io_scene_swbf_msh/msh_model_utilities.py +++ b/addons/io_scene_swbf_msh/msh_model_utilities.py @@ -8,6 +8,25 @@ import math from mathutils import Vector, Matrix + +# Convert model with geometry to null. +# Currently not used, but could be necessary in the future. +def make_null(model : Model): + model.model_type = ModelType.NULL + bone_map = None + geometry = None + + +# I think this is all we need to check for to avoid +# common ZE/ZETools crashes... +def validate_geometry_segment(segment : GeometrySegment) -> bool: + if not segment.positions or not segment.triangle_strips: + return False + else: + return True + + + def inject_dummy_data(model : Model): """ Adds a triangle and material to the model (scene root). Needed to export zenasst-compatible skeletons. """ model.hidden = True diff --git a/addons/io_scene_swbf_msh/msh_scene_utilities.py b/addons/io_scene_swbf_msh/msh_scene_utilities.py index fbd22de..79ce3fa 100644 --- a/addons/io_scene_swbf_msh/msh_scene_utilities.py +++ b/addons/io_scene_swbf_msh/msh_scene_utilities.py @@ -9,7 +9,7 @@ from mathutils import Vector from .msh_model import Model, Animation, ModelType from .msh_scene import Scene, SceneAABB from .msh_model_gather import gather_models -from .msh_model_utilities import sort_by_parent, has_multiple_root_models, reparent_model_roots, get_model_world_matrix, inject_dummy_data +from .msh_model_utilities import make_null, validate_geometry_segment, sort_by_parent, has_multiple_root_models, reparent_model_roots, get_model_world_matrix, inject_dummy_data from .msh_model_triangle_strips import create_models_triangle_strips from .msh_material import * from .msh_material_gather import gather_materials @@ -53,6 +53,20 @@ def create_scene(generate_triangle_strips: bool, apply_modifiers: bool, export_t for segment in model.geometry: segment.triangle_strips = segment.triangles + # After generating triangle strips we must prune any segments that don't have + # them, or else ZE and most versions of ZETools will crash. + + # We could also make models with no valid segments nulls, since they might as well be, + # but that could have unforseeable consequences further down the modding pipeline + # and is not necessary to avoid the aforementioned crashes... + for model in scene.models: + if model.geometry is not None: + # Doing this in msh_model_gather would be messy and the presence/absence + # of triangle strips is required for a validity check. + model.geometry = [segment for segment in model.geometry if validate_geometry_segment(segment)] + #if not model.geometry: + # make_null(model) + if has_multiple_root_models(scene.models): scene.models = reparent_model_roots(scene.models)