Closed rwang15 closed 12 months ago
Please use my implementation above and address the following TODO
items in the code.
# TODO: parse command-line args
# TODO: get level name programmatically
# TODO: use args to decide whether or not to use selected actors
We can address the other TODO
items in subsequent PRs.
Finally, add a path/to/spear/tools/validate_scene_kujiale.py
script that invokes the Unreal Editor programmatically and runs path/to/SpearSim/Content/Python/validate_scene_kujiale.py
for a given scene. Make the code in this script as similar as possible to the existing code in the rest of our tools.
UPDATE: This step is no longer necessary because I figured out how to pip install
packages into the Unreal Python environment. See above.
My code makes use of spear.log
for improved logging functionality. To access, add the following to path/to/SpearSim/Content/Python/spear
__init__.py
:
#
# Copyright(c) 2022 Intel. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
#
__version__ = "0.3.0"
from spear.log import log
log.py
#
# Copyright(c) 2022 Intel. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
#
import inspect
import os
def log(*args):
current_frame = inspect.currentframe()
print(_log_get_prefix(current_frame) + "".join([str(arg) for arg in args]))
def _log_get_prefix(current_frame):
return "[SPEAR | " + _get_current_file_abbreviated(current_frame) + ":" + _get_current_line(current_frame) + "] "
def _get_current_file_abbreviated(current_frame):
outer_frames = inspect.getouterframes(current_frame)
return os.path.basename(outer_frames[1].filename)
def _get_current_line(current_frame):
outer_frames = inspect.getouterframes(current_frame)
return str(outer_frames[1].lineno)
Update: I included a check that validates each actor's pivot location, and changed the order of functions in my implementation to proceed from high-level to low-level to make it easier to read. See above.
Update: I modified the pivot validation check to ignore SM_dummy
components.
# ignore components from bounds computation if they don't have a mesh assigned, or if their assigned mesh is SM_Dummy
ignore_components = [
c for c in actor.get_components_by_class(unreal.StaticMeshComponent) if
c.get_editor_property("static_mesh") is None or
c.get_editor_property("static_mesh").get_path_name() == "/Game/Common/Meshes/SM_Dummy.SM_Dummy" ]
# for each ignored component, cache "use_default_collision" and "collision_enabled" properties
ignore_use_default_collision = {
c.get_name(): c.get_editor_property("use_default_collision") for c in ignore_components }
ignore_collision_enabled = {
c.get_name(): c.get_editor_property("body_instance").get_editor_property("collision_enabled") for c in ignore_components }
# disable collision on each ignored component
for c in ignore_components:
c.set_editor_property("use_default_collision", False)
c.get_editor_property("body_instance").set_editor_property("collision_enabled", unreal.CollisionEnabled.NO_COLLISION)
# compute bounds
bounds_origin, bounds_half_extent = actor.get_actor_bounds(only_colliding_components=True, include_from_child_actors=False)
# for each ignored component, restore "use_default_collision" and "collision_enabled" properties
for c in ignore_components:
c.set_editor_property("use_default_collision", ignore_use_default_collision[c.get_name()])
c.get_editor_property("body_instance").set_editor_property("collision_enabled", ignore_collision_enabled[c.get_name()])
# check pivot location against computed bounds
eps = 0.000001
bounds_origin = vector_to_numpy(bounds_origin)
bounds_half_extent = vector_to_numpy(bounds_half_extent)
pivot_desired = np.array([bounds_origin[0], bounds_origin[1], bounds_origin[2] - bounds_half_extent[2]])
pivot_actual = vector_to_numpy(actor.get_actor_location())
if np.linalg.norm(pivot_desired - pivot_actual) > eps:
np.set_printoptions(suppress=True)
spear.log(
"WARNING: Unexpected pivot: ", get_debug_string_actor(actor),
" (desired=", pivot_desired, ", actual=", pivot_actual, ")")
return
TODO
comment for every rule that is in the content guidelines doc that is not yet validated in code.kujiale
conventions. Since the number of non-Kujiale scenes is growing slowly, we can worry about how to factor into general-purpose and Kujiale-specific functionality in a subsequent PR.numpy
and ourspear
Python module into Unreal's Python environment. I did so by running the following commands. We can create a tool to do this step in a subsequent PR.