Skip to content

Commit

Permalink
Closes #687. Checkboxes and layer property assaignment now complete
Browse files Browse the repository at this point in the history
  • Loading branch information
tngreene committed Jan 24, 2022
1 parent 30a93ab commit 61f1484
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 7 deletions.
57 changes: 52 additions & 5 deletions io_xplane2blender/importer/xplane_imp_cmd_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import pathlib
import random
import re
from collections import namedtuple
from dataclasses import dataclass, field
from itertools import islice, tee
from pathlib import Path
Expand Down Expand Up @@ -238,6 +239,9 @@ def is_valid_post_optimization(self)-> bool:
"""


LODRange = namedtuple("LODRange", ["near", "far"], defaults=[0, 0])


@dataclass
class IntermediateDatablock:

Expand All @@ -260,6 +264,10 @@ class IntermediateDatablock:
# and their animations which isn't data a DatablockInfo has
children: List["IntermediateDatablock"] = field(default_factory=list)

bins: Tuple[bool, bool, bool, bool] = field(
default_factory=lambda: (False, False, False, False)
)

def build_mesh(self, vt_table: "VTTable") -> bpy.types.Mesh:
"""
Builds a mesh from the OBJ's VT Table, raises ValueError if
Expand Down Expand Up @@ -310,6 +318,10 @@ def chunk(it, size):
self.datablock_info,
mesh_src=me,
)
ob.xplane.override_lods = any(self.bins)
if ob.xplane.override_lods:
for i, enabled in enumerate(self.bins):
ob.xplane.lod[i] = enabled

return ob
else:
Expand Down Expand Up @@ -425,6 +437,9 @@ def __init__(self, filepath: Path):
)

self.root_collection.xplane.is_exportable_collection = True

# If ATTR_LOD is used this becomes the LOD sub collections
self.parent_collection = self.root_collection
self.vt_table = VTTable([], [])
self.texture: Optional[Path] = None
# self.texture_lit:Optional[Path] = Path()
Expand All @@ -435,7 +450,7 @@ def __init__(self, filepath: Path):
datablock_info=DatablockInfo(
datablock_type="EMPTY",
name="INTER_ROOT",
collection=self.root_collection,
collection=self.parent_collection,
),
start_idx=None,
count=None,
Expand All @@ -444,6 +459,11 @@ def __init__(self, filepath: Path):
bake_matrix=Matrix.Identity(4),
)

# --- LODS -------------------------------------------------------------
self.lod_mode: Optional[None] = None
self.current_bins = (False, False, False, False)
self.encountered_ranges: List[LODRange] = []
# ---------------------------------------------------------------------
# --- Animation Builder States ----------------------------------------
# Instead of build at separate parent/child relationship in Datablock info, we just save everything we make here
self._blocks: List[IntermediateDatablock] = [self.root_intermediate_datablock]
Expand Down Expand Up @@ -475,13 +495,15 @@ def begin_new_frame() -> None:
"EMPTY",
name=name_hint or self._next_empty_name(),
parent_info=ParentInfo(parent.datablock_info.name),
collection=self.root_collection,
collection=self.parent_collection,
),
start_idx=None,
count=None,
transform_animation=None,
show_hide_animations=[],
bake_matrix=self._bake_matrix_stack[-1].copy(),
children=[],
bins=tuple(self.current_bins),
)
self._blocks.append(empty)
parent.children.append(empty)
Expand Down Expand Up @@ -516,16 +538,41 @@ def begin_new_frame() -> None:
name=name_hint or self._next_object_name(),
# How do we keep track of this
parent_info=ParentInfo(parent.datablock_info.name),
collection=self.root_collection,
collection=self.parent_collection,
),
start_idx=start_idx,
count=count,
transform_animation=None,
show_hide_animations=[],
bake_matrix=self._bake_matrix_stack[-1].copy(),
children=[],
bins=tuple(self.current_bins),
)
self._blocks.append(intermediate_datablock)
parent.children.append(intermediate_datablock)
elif directive == "ATTR_LOD":
near, far = args[:2]
self.parent_collection = test_creation_helpers.create_datablock_collection(
f"LOD_{near}_{far}", parent=self.root_collection
)
if self.lod_mode == None:
# TODO: X-Plane default?
self.lod_mode = "selective"
if not self.encountered_ranges:
self.current_bins = [True, False, False, False]
elif near == self.encountered_ranges[-1].far:
self.lod_mode = "selective"
# TODO: too many ranges bug
self.current_bins = [False, False, False, False]
self.current_bins[len(self.encountered_ranges)] = True
elif self.encountered_ranges[-1].near == 0:
self.lod_mode = "additive"
# TODO : too many ranges bug still
self.current_bins = ([True] * (len(self.encountered_ranges) + 1)) + (
[False] * (4 - len(self.encountered_ranges) - 1)
)
assert len(self.current_bins) == 4, f"{self.current_bins}"
self.encountered_ranges.append(LODRange(near, far))

elif directive == "ANIM_begin":
self._anim_count.append(0)
Expand Down Expand Up @@ -1202,14 +1249,14 @@ def _next_empty_name(self) -> str:
return (
f"ImpEmpty."
f"{sum(1 for block in self._blocks if block.datablock_type == 'EMPTY'):03}"
f"_{hex(hash(self.root_collection.name))[2:6]}"
f"_{hex(hash(self.parent_collection.name))[2:6]}"
f"_{random.randint(0,100000)}"
)

def _next_object_name(self) -> str:
return (
f"ImpMesh."
f"{sum(1 for block in self._blocks if block.datablock_type == 'MESH'):03}"
f"_{hex(hash(self.root_collection.name))[2:6]}"
f"_{hex(hash(self.parent_collection.name))[2:6]}"
f"_{random.randint(0,100000)}"
)
12 changes: 12 additions & 0 deletions io_xplane2blender/importer/xplane_imp_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def import_obj(filepath: Union[pathlib.Path, str]) -> str:
"IDX",
"IDX10",
"TRIS",
"ATTR_LOD",
"ANIM_begin",
"ANIM_end",
"ANIM_trans_begin",
Expand Down Expand Up @@ -183,6 +184,10 @@ def scan_float(s_itr:iter)
count = int(components[1])
builder.build_cmd(directive, start_idx, count, name_hint=name_hint)
name_hint = ""
elif directive == "ATTR_LOD":
near = int(components[0])
far = int(components[1])
builder.build_cmd(directive, near, far)

elif directive == "ANIM_begin":
builder.build_cmd("ANIM_begin", name_hint=name_hint)
Expand Down Expand Up @@ -247,4 +252,11 @@ def scan_float(s_itr:iter)
pass

builder.finalize_intermediate_blocks()
if builder.encountered_ranges:
root_layer = builder.root_collection.xplane.layer
root_layer.lods = str(len(builder.encountered_ranges))

for i, lod_range in enumerate(builder.encountered_ranges):
r = root_layer.lod[i]
r.near, r.far = lod_range
return "FINISHED"
7 changes: 5 additions & 2 deletions io_xplane2blender/tests/test_creation_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,12 @@ def create_datablock_collection(
scene: bpy.types.Scene = bpy.data.scenes[scene]
except (KeyError, TypeError): # scene is str and not found or is None
scene: bpy.types.Scene = bpy.context.scene

try:
parent: bpy.types.Collection = bpy.data.collections[parent]
except (KeyError, TypeError): # parent is str and not found or is Collection
parent: bpy.types.Collection = bpy.data.collections[
parent.name if isinstance(parent, bpy.types.Collection) else parent
]
except (KeyError, TypeError): # parent is None or not found
parent: bpy.types.Collection = scene.collection

if coll.name not in parent.children:
Expand Down
22 changes: 22 additions & 0 deletions tests/importer/directives/fixtures/attr_lod_good_additive_1.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
I
800
OBJ

GLOBAL_cockpit_lit
POINT_COUNTS 3 0 0 3

VT 1 0 1 -0 -1 -0 0.625 1
VT 1 0 -1 -0 -1 -0 0.625 0.75
VT -1 0 1 -0 -1 -0 0.375 1

IDX 0
IDX 1
IDX 2

# Unit Test Overview
# This tests that a basic use of 3 additive LODs works
# Having tests 3 and 4 shows we don't ever accidentally simply select all and pass
ATTR_LOD 0 200
TRIS 0 3

# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.1.0-beta.1+101.NO_BUILD_NUMBR
26 changes: 26 additions & 0 deletions tests/importer/directives/fixtures/attr_lod_good_additive_3.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
I
800
OBJ

GLOBAL_cockpit_lit
POINT_COUNTS 3 0 0 3

VT 1 0 1 -0 -1 -0 0.625 1
VT 1 0 -1 -0 -1 -0 0.625 0.75
VT -1 0 1 -0 -1 -0 0.375 1

IDX 0
IDX 1
IDX 2

# Unit Test Overview
# This tests that a basic use of 3 additive LODs works
# Having tests 3 and 4 shows we don't ever accidentally simply select all and pass
ATTR_LOD 0 200
TRIS 0 3
ATTR_LOD 0 400
TRIS 0 3
ATTR_LOD 0 600
TRIS 0 3

# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.1.0-beta.1+101.NO_BUILD_NUMBR
28 changes: 28 additions & 0 deletions tests/importer/directives/fixtures/attr_lod_good_additive_4.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
I
800
OBJ

GLOBAL_cockpit_lit
POINT_COUNTS 3 0 0 3

VT 1 0 1 -0 -1 -0 0.625 1
VT 1 0 -1 -0 -1 -0 0.625 0.75
VT -1 0 1 -0 -1 -0 0.375 1

IDX 0
IDX 1
IDX 2

# Unit Test Overview
# This tests that a basic use of 4 additive LODs works
#
ATTR_LOD 0 200
TRIS 0 3
ATTR_LOD 0 400
TRIS 0 3
ATTR_LOD 0 600
TRIS 0 3
ATTR_LOD 0 800
TRIS 0 3

# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.1.0-beta.1+101.NO_BUILD_NUMBR
21 changes: 21 additions & 0 deletions tests/importer/directives/fixtures/attr_lod_good_selective_1.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
I
800
OBJ

GLOBAL_cockpit_lit
POINT_COUNTS 3 0 0 3

VT 1 0 1 -0 -1 -0 0.625 1
VT 1 0 -1 -0 -1 -0 0.625 0.75
VT -1 0 1 -0 -1 -0 0.375 1

IDX 0
IDX 1
IDX 2

# Unit Test Overview
# This tests that a basic use of 3 selective LODs works.
ATTR_LOD 200 400
TRIS 0 3

# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.1.0-beta.1+101.NO_BUILD_NUMBR
26 changes: 26 additions & 0 deletions tests/importer/directives/fixtures/attr_lod_good_selective_3.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
I
800
OBJ

GLOBAL_cockpit_lit
POINT_COUNTS 3 0 0 3

VT 1 0 1 -0 -1 -0 0.625 1
VT 1 0 -1 -0 -1 -0 0.625 0.75
VT -1 0 1 -0 -1 -0 0.375 1

IDX 0
IDX 1
IDX 2

# Unit Test Overview
# This tests that a basic use of 3 selective LODs works.
# Having 3 tests we don't accidentally just select the 4th
ATTR_LOD 0 200
TRIS 0 3
ATTR_LOD 200 400
TRIS 0 3
ATTR_LOD 400 600
TRIS 0 3

# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.1.0-beta.1+101.NO_BUILD_NUMBR
28 changes: 28 additions & 0 deletions tests/importer/directives/fixtures/attr_lod_good_selective_4.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
I
800
OBJ

GLOBAL_cockpit_lit
POINT_COUNTS 3 0 0 3

VT 1 0 1 -0 -1 -0 0.625 1
VT 1 0 -1 -0 -1 -0 0.625 0.75
VT -1 0 1 -0 -1 -0 0.375 1

IDX 0
IDX 1
IDX 2

# Unit Test Overview
# This tests that a basic use of 4 selective LODs works
#
ATTR_LOD 0 200
TRIS 0 3
ATTR_LOD 200 400
TRIS 0 3
ATTR_LOD 400 600
TRIS 0 3
ATTR_LOD 600 800
TRIS 0 3

# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.1.0-beta.1+101.NO_BUILD_NUMBR

0 comments on commit 61f1484

Please sign in to comment.