Skip to content
This repository has been archived by the owner on Sep 19, 2023. It is now read-only.

Commit

Permalink
Merge pull request #24 from RaenonX-DL/dev
Browse files Browse the repository at this point in the history
v1.1.0 Release
  • Loading branch information
RaenonX authored Sep 20, 2021
2 parents c1d512d + 0aa1031 commit f4a4e77
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 20 deletions.
1 change: 1 addition & 0 deletions dlasset/config/model/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# List supported types only
UnityType = Literal[
"MonoBehaviour",
"MonoScript",
"GameObject",
"AnimatorController",
"AnimatorOverrideController",
Expand Down
5 changes: 2 additions & 3 deletions dlasset/env/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import TYPE_CHECKING

from dlasset.enums import Locale
from dlasset.utils import export_json

if TYPE_CHECKING:
from dlasset.manifest import ManifestEntryBase
Expand Down Expand Up @@ -73,6 +74,4 @@ def update_index_files(self) -> None:
for locale, data in self._data.items():
file_path = self.get_index_file_path(locale)

with open(file_path, "w+", encoding="utf-8") as f:
# `separators` argument for minify
json.dump(data, f, separators=(",", ":"))
export_json(file_path, data, separators=(",", ":"))
2 changes: 1 addition & 1 deletion dlasset/export/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Implementations for exporting Unity assets."""
from .main import export_asset
from .model import ExportInfo
from .model import ExportInfo, ObjectInfo
from .raw import export_raw_by_task
from .task import export_by_task
from .types import * # noqa
1 change: 1 addition & 0 deletions dlasset/export/functions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Functions to export the asset objects."""
from .game_object import export_game_object
from .image import export_image
from .image_alpha import export_image_alpha
from .image_story import export_image_story
Expand Down
67 changes: 67 additions & 0 deletions dlasset/export/functions/game_object.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Implementations to export ``GameObject`` and its component into a single script."""
import os
from typing import TYPE_CHECKING

from dlasset.export.types import MonoBehaviourTree
from dlasset.log import log
from dlasset.utils import export_json

if TYPE_CHECKING:
from dlasset.export import ExportInfo, ObjectInfo

__all__ = ("export_game_object",)


def export_single_game_obj(export_info: "ExportInfo", game_obj_info: "ObjectInfo") -> None:
"""Export a single game object."""
tree_export: MonoBehaviourTree = {}

object_tree = game_obj_info.obj.read_typetree()

components = [
export_info.get_obj_info(component["component"]["m_PathID"]).obj
for component in object_tree["m_Component"][1:] # 1st component is always a `Transform` which is omitted
]

tree_name = object_tree["m_Name"]
tree_components = []
for component in components:
component_tree = component.read_typetree()

script_path_id = component_tree["m_Script"]["m_PathID"]
if script_path_id:
# Attach script type name if available
attachment = {
"$Script": export_info.get_obj_info(component_tree["m_Script"]["m_PathID"]).obj.name
}
else:
# Otherwise, attach component name
attachment = {"$Name": component_tree["m_Name"]}

tree_components.append(attachment | component_tree)

tree_export["Name"] = tree_name
tree_export["Components"] = tree_components

export_path: str = os.path.join(export_info.get_export_dir_of_obj(game_obj_info), f"{tree_name}.prefab.json")

export_json(export_path, tree_export)


def export_game_object(export_info: "ExportInfo") -> None:
"""Export components in ``export_info`` info a single script for each game object."""
game_obj_info_list = [obj_info for obj_info in export_info.objects if obj_info.obj.type == "GameObject"]

if not game_obj_info_list:
log("WARNING", f"No exportable `GameObject` from {export_info}")
return

for idx, game_obj_info in enumerate(game_obj_info_list):
export_single_game_obj(export_info, game_obj_info)

if idx % 50 == 0:
log(
"INFO",
f"{idx} / {len(game_obj_info_list)} ({idx / len(game_obj_info_list):.2%}) objects exported "
f"- {export_info}"
)
6 changes: 3 additions & 3 deletions dlasset/export/functions/monobehaviour.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Implementations to export ``MonoBehaviour``."""
import json
import os
from typing import TYPE_CHECKING

from dlasset.export.types import MonoBehaviourTree
from dlasset.log import log
from dlasset.utils import export_json

if TYPE_CHECKING:
from dlasset.export import ExportInfo
Expand Down Expand Up @@ -32,8 +32,8 @@ def export_mono_behaviour(export_info: "ExportInfo") -> list[MonoBehaviourTree]:
continue

tree = obj.read_typetree()
with open(export_path, "w+", encoding="utf-8") as f:
f.write(json.dumps(tree, ensure_ascii=False, indent=2))

export_json(export_path, tree)

trees.append(tree)

Expand Down
6 changes: 3 additions & 3 deletions dlasset/export/lookup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Exporting function index."""
from dlasset.config import ExportType, UnityType
from .functions import export_image, export_image_alpha, export_image_story, export_mono_behaviour
from .functions import export_game_object, export_image, export_image_alpha, export_image_story, export_mono_behaviour
from .types import ExportFunction

__all__ = ("EXPORT_FUNCTIONS", "TYPES_TO_INCLUDE")
Expand All @@ -11,7 +11,7 @@
"Texture2D-Alpha": export_image_alpha,
"Texture2D-Story": export_image_story,
"Sprite": export_image,
"GameObject": export_mono_behaviour,
"GameObject": export_game_object,
"AnimatorController": export_mono_behaviour,
"AnimatorOverrideController": export_mono_behaviour,
}
Expand All @@ -22,7 +22,7 @@
"Texture2D-Alpha": ("Texture2D", "Material"),
"Texture2D-Story": ("Texture2D", "Material", "MonoBehaviour"),
"Sprite": ("Sprite",),
"GameObject": ("GameObject",),
"GameObject": ("GameObject", "MonoBehaviour", "MonoScript"),
"AnimatorController": ("AnimatorController",),
"AnimatorOverrideController": ("AnimatorOverrideController",),
}
12 changes: 11 additions & 1 deletion dlasset/export/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,16 @@ def export_objects(
"""
obj_info_to_export: list[ObjectInfo] = []

for obj_info in obj_export:
for idx, obj_info in enumerate(obj_export):
obj = obj_info.read_obj()

if idx > 0 and idx % 500 == 0:
log(
"INFO",
f"Reading {idx} / {len(obj_export)} ({idx / len(obj_export):.2%}) object "
f"of {asset_name} ({container_fallback})..."
)

if (
obj_info.is_from_main
and filters
Expand All @@ -105,6 +112,9 @@ def export_objects(

obj_info_to_export.append(obj_info)

if len(obj_export) > 1000:
log("INFO", f"Read {len(obj_export)} objects and picked {len(obj_info_to_export)} objects to export.")

export_info = ExportInfo(
export_dir=export_dir,
obj_info_list=obj_info_to_export,
Expand Down
11 changes: 2 additions & 9 deletions dlasset/export/types.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
"""Type definitions for exporting the assets."""
from typing import Any, Callable, Union
from typing import Any, Callable, Optional, Union

from .model import ExportInfo

__all__ = ("ExportFunction", "ExportReturn", "MonoBehaviourTree")

MonoBehaviourTree = dict[Any, Any]

MonoBehaviourExportFunction = Callable[[ExportInfo], list[MonoBehaviourTree]]

Texture2DExportFunction = Callable[[ExportInfo], None]

ExportFunction = Union[
MonoBehaviourExportFunction,
Texture2DExportFunction
]
ExportFunction = Callable[[ExportInfo], Optional[list[MonoBehaviourTree]]]

ExportReturn = Union[
MonoBehaviourTree
Expand Down
1 change: 1 addition & 0 deletions dlasset/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Various utility functions."""
from .execution import concurrent_run, concurrent_run_no_return, time_exec
from .export import export_json
from .image import crop_image, merge_y_cb_cr_a
52 changes: 52 additions & 0 deletions dlasset/utils/export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Utility function for exporting."""
import json
from typing import Any, Optional

__all__ = ("export_json",)


def round_floats(obj: Any) -> Any:
"""Round the ``float`` in ``obj``."""
if isinstance(obj, float):
return float(format(obj, ".9g"))

if isinstance(obj, dict):
return {k: round_floats(v) for k, v in obj.items()}

if isinstance(obj, (list, tuple)):
return [round_floats(x) for x in obj]

return obj


def export_json(export_path: str, obj: Any, /, separators: Optional[tuple[str, str]] = None) -> None:
"""
Export the object ``obj`` to ``export_path``.
It was tested that the solutions below are slower:
>>> with open(export_path, "w+", encoding="utf-8") as f:
>>> f.write(json.dumps(
>>> json.loads(
>>> json.dumps(obj),
>>> parse_float=lambda x: f"{float(x):.9g}"
>>> )
>>> ))
The solution above was about on par.
>>> with open(export_path, "w+", encoding="utf-8") as f:
>>> json.dump(round_floats(obj), f)
The solution above is about 3x slower.
>>> with open(export_path, "w+", encoding="utf-8") as f:
>>> json.dump(
>>> json.loads(json.dumps(obj), parse_float=lambda x: f"{float(x):.9g}"),
>>> f,
>>> )
The solution above is about 3x slower.
"""
with open(export_path, "w+", encoding="utf-8") as f:
f.write(json.dumps(round_floats(obj), ensure_ascii=False, indent=2, separators=separators))

0 comments on commit f4a4e77

Please sign in to comment.