-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathrun.py
116 lines (90 loc) · 7.6 KB
/
run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#
# Copyright(c) 2022 Intel. Licensed under the MIT License <http://opensource.org/licenses/MIT>.
#
# Before running this file, rename user_config.yaml.example -> user_config.yaml and modify it with appropriate paths for your system.
import cv2
import math
import os
import spear
if __name__ == "__main__":
# create instance
config = spear.get_config(user_config_files=[os.path.realpath(os.path.join(os.path.dirname(__file__), "user_config.yaml"))])
spear.configure_system(config=config)
instance = spear.Instance(config=config)
# initialize actors and components
with instance.begin_frame():
# find functions
actor_static_class = instance.unreal_service.get_static_class(class_name="AActor")
set_actor_location_func = instance.unreal_service.find_function_by_name(uclass=actor_static_class, function_name="K2_SetActorLocation")
set_actor_rotation_func = instance.unreal_service.find_function_by_name(uclass=actor_static_class, function_name="K2_SetActorRotation")
sp_scene_capture_component_2d_static_class = instance.unreal_service.get_static_class(class_name="USpSceneCaptureComponent2D")
initialize_func = instance.unreal_service.find_function_by_name(uclass=sp_scene_capture_component_2d_static_class, function_name="Initialize")
terminate_func = instance.unreal_service.find_function_by_name(uclass=sp_scene_capture_component_2d_static_class, function_name="Terminate")
gameplay_statics_static_class = instance.unreal_service.get_static_class(class_name="UGameplayStatics")
get_player_controller_func = instance.unreal_service.find_function_by_name(uclass=gameplay_statics_static_class, function_name="GetPlayerController")
# get UGameplayStatics default object
gameplay_statics_default_object = instance.unreal_service.get_default_object(uclass=gameplay_statics_static_class, create_if_needed=False)
# spawn camera sensor and get the final_tone_curve_hdr component
bp_camera_sensor_uclass = instance.unreal_service.load_object(class_name="UClass", outer=0, name="/SpComponents/Blueprints/BP_Camera_Sensor.BP_Camera_Sensor_C")
bp_camera_sensor_actor = instance.unreal_service.spawn_actor_from_class(uclass=bp_camera_sensor_uclass)
final_tone_curve_hdr_component = instance.unreal_service.get_component_by_name(class_name="USceneComponent", actor=bp_camera_sensor_actor, component_name="DefaultSceneRoot.final_tone_curve_hdr")
# configure the final_tone_curve_hdr component to match the viewport (width, height, FOV, post-processing settings, etc)
post_process_volume = instance.unreal_service.find_actor_by_type(class_name="APostProcessVolume")
return_values = instance.unreal_service.call_function(uobject=gameplay_statics_default_object, ufunction=get_player_controller_func, args={"PlayerIndex": 0})
player_controller = spear.to_handle(string=return_values["ReturnValue"])
player_camera_manager_desc = instance.unreal_service.find_property_by_name_on_object(uobject=player_controller, property_name="PlayerCameraManager")
player_camera_manager_string = instance.unreal_service.get_property_value(property_desc=player_camera_manager_desc)
player_camera_manager = spear.to_handle(string=player_camera_manager_string)
viewport_size = instance.engine_service.get_viewport_size()
viewport_x = viewport_size[0]
viewport_y = viewport_size[1]
viewport_aspect_ratio = viewport_x/viewport_y # see Engine/Source/Editor/UnrealEd/Private/EditorViewportClient.cpp:2130 for evidence that Unreal's aspect ratio convention is x/y
view_target_pov_desc = instance.unreal_service.find_property_by_name_on_object(uobject=player_camera_manager, property_name="ViewTarget.POV")
view_target_pov = instance.unreal_service.get_property_value(property_desc=view_target_pov_desc)
fov = view_target_pov["fOV"]*math.pi/180.0 # this adjustment is necessary to compute an FOV value that matches the game viewport
half_fov = fov/2.0
half_fov_adjusted = math.atan(math.tan(half_fov)*viewport_aspect_ratio/view_target_pov["aspectRatio"])
fov_adjusted = half_fov_adjusted*2.0
fov_adjusted_degrees = fov_adjusted*180.0/math.pi
volume_settings_desc = instance.unreal_service.find_property_by_name_on_object(uobject=post_process_volume, property_name="Settings")
volume_settings = instance.unreal_service.get_property_value(property_desc=volume_settings_desc)
instance.unreal_service.call_function(uobject=bp_camera_sensor_actor, ufunction=set_actor_location_func, args={"NewLocation": view_target_pov["location"]})
instance.unreal_service.call_function(uobject=bp_camera_sensor_actor, ufunction=set_actor_rotation_func, args={"NewRotation": view_target_pov["rotation"]})
width_desc = instance.unreal_service.find_property_by_name_on_object(uobject=final_tone_curve_hdr_component, property_name="Width")
height_desc = instance.unreal_service.find_property_by_name_on_object(uobject=final_tone_curve_hdr_component, property_name="Height")
fov_angle_desc = instance.unreal_service.find_property_by_name_on_object(uobject=final_tone_curve_hdr_component, property_name="FOVAngle")
component_settings_desc = instance.unreal_service.find_property_by_name_on_object(uobject=final_tone_curve_hdr_component, property_name="PostProcessSettings")
instance.unreal_service.set_property_value(property_desc=width_desc, property_value=viewport_x)
instance.unreal_service.set_property_value(property_desc=height_desc, property_value=viewport_y)
instance.unreal_service.set_property_value(property_desc=fov_angle_desc, property_value=fov_adjusted_degrees)
instance.unreal_service.set_property_value(property_desc=component_settings_desc, property_value=volume_settings)
# now that the final_tone_curve_hdr component is fully configured, initialize it and get handles to its shared memory
instance.unreal_service.call_function(uobject=final_tone_curve_hdr_component, ufunction=initialize_func)
final_tone_curve_hdr_component_shared_memory_handles = instance.sp_func_service.create_shared_memory_handles_for_object(uobject=final_tone_curve_hdr_component)
with instance.end_frame():
pass # we could get rendered data here, but the rendered image will look better if we let temporal anti-aliasing etc accumulate additional information across frames
# # let temporal anti-aliasing etc accumulate additional information across multiple frames
# for i in range(1):
# with instance.begin_frame():
# pass
# with instance.end_frame():
# pass
# get rendered frame
with instance.begin_frame():
pass
with instance.end_frame():
return_values = instance.sp_func_service.call_function(
uobject=final_tone_curve_hdr_component,
function_name="read_pixels",
uobject_shared_memory_handles=final_tone_curve_hdr_component_shared_memory_handles)
# show rendered frame now that we're outside of with instance.end_frame()
cv2.imshow("final_tone_curve_hdr", return_values["arrays"]["data"])
cv2.waitKey(0)
# terminate actors and components
with instance.begin_frame():
pass
with instance.end_frame():
instance.sp_func_service.destroy_shared_memory_handles_for_object(shared_memory_handles=final_tone_curve_hdr_component_shared_memory_handles)
instance.unreal_service.call_function(uobject=final_tone_curve_hdr_component, ufunction=terminate_func)
instance.unreal_service.destroy_actor(actor=bp_camera_sensor_actor)
spear.log("Done.")