def start(c: Controller) -> None: """ Start the controller. :param c: The controller. """ c.start() c.communicate([{ "$type": "simulate_physics", "value": False }, { "$type": "create_empty_environment" }, { "$type": "set_render_quality", "render_quality": 0 }, { "$type": "set_post_process", "value": False }, { "$type": "create_avatar", "id": "a", "type": "A_Img_Caps_Kinematic" }, { "$type": "set_pass_masks", "pass_masks": ["_img"] }])
def run(): # Create the asset bundle and the record. asset_bundle_paths, record_path = AssetBundleCreator( ).create_asset_bundle("cube.fbx", True, 123, "", 1) # Get the name of the bundle for this platform. For example, Windows -> "StandaloneWindows64" bundle = SYSTEM_TO_UNITY[system()] # Get the correct asset bundle path. for p in asset_bundle_paths: # Get the path to the asset bundle. if bundle in str(p.parent.resolve()): url = "file:///" + str(p.resolve()) # Launch the controller. c = Controller() c.start() # Create the environment. # Add the object. commands = [{ "$type": "create_empty_environment" }, { "$type": "add_object", "name": "cube", "url": url, "scale_factor": 1, "id": c.get_unique_id() }] # Create the avatar. commands.extend( TDWUtils.create_avatar(position={ "x": 0, "y": 0, "z": -3.6 })) c.communicate(commands) return
def start(c: Controller) -> None: """ Start the controller. :param c: The controller. """ print(f"Results will be saved to: {MissingMaterials.OUTPUT_FILE}") c.start() c.communicate([{ "$type": "simulate_physics", "value": False }, { "$type": "create_empty_environment" }, { "$type": "set_render_quality", "render_quality": 0 }, { "$type": "set_post_process", "value": False }, { "$type": "create_avatar", "id": "a", "type": "A_Img_Caps_Kinematic" }, { "$type": "set_pass_masks", "pass_masks": ["_img"] }])
def get_random_position_on_nav_mesh( c: Controller, width: float, length: float, x_e=0, z_e=0, bake=True, rng=random.uniform) -> Tuple[float, float, float]: """ Returns a random position on a NavMesh. :param c: The controller. :param width: The width of the environment. :param length: The length of the environment. :param bake: If true, send bake_nav_mesh. :param rng: Random number generator. :param x_e: The x position of the environment. :param z_e: The z position of the environment. :return The coordinates as a tuple `(x, y, z)` """ if bake: c.communicate({'$type': 'bake_nav_mesh'}) # Try to find a valid position on the NavMesh. is_on = False x, y, z = (0, 0, 0) while not is_on: # Get a random position. x = rng(-width / 2, width / 2) + x_e z = rng(-length / 2, length / 2) + z_e resp = c.communicate({ '$type': 'send_is_on_nav_mesh', 'position': { 'x': x, 'y': 0, 'z': z }, 'max_distance': 4.0 }) answer = IsOnNavMesh(resp[0]) is_on = answer.get_is_on() x, y, z = answer.get_position() return x, y, z
def run(c: Controller) -> None: """ Check every model for missing materials. :param c: The controller. """ # Create a new output file. if MissingMaterials.OUTPUT_FILE.exists(): MissingMaterials.OUTPUT_FILE.unlink() MissingMaterials.OUTPUT_FILE = str( MissingMaterials.OUTPUT_FILE.resolve()) MissingMaterials.start(c) print( f"The names of models with missing materials will be saved to: {MissingMaterials.OUTPUT_FILE}" ) for library_path in ModelLibrarian.get_library_filenames(): print(library_path) lib = ModelLibrarian(library=library_path) pbar = tqdm(total=len(lib.records)) for record in lib.records: if record.do_not_use: pbar.update(1) continue pbar.set_description(record.name) # Check for missing materials. if MissingMaterials.materials_are_missing( c, record, record.get_url()): with io.open(MissingMaterials.OUTPUT_FILE, "at") as f: f.write("\n" + record.name) # Cleanup. c.communicate([{ "$type": "destroy_object", "id": MissingMaterials.OBJECT_ID }, { "$type": "unload_asset_bundles" }]) pbar.update(1) pbar.close() c.communicate({"$type": "terminate"})
def _orbit_and_capture_image(c: Controller, x: float, y: float, z: float) -> bool: """ Orbit around an object and check for missing materials. :param c: The controller. :param x: The next x positional coordinate. :param y: The next y positional coordinate. :param z: The next z positional coordinate. :return: True if there is a missing material in the image, False otherwise. """ # Teleport the avatar. # Look at the model. # Receive an image. resp = c.communicate([{ "$type": "teleport_avatar_to", "position": { "x": x, "y": y, "z": z } }, { "$type": "look_at", "object_id": MissingMaterials.OBJECT_ID, "use_centroid": True }]) # Check if there are any pink pixels. images = Images(resp[0]) img = Image.open(BytesIO(images.get_image(0))) for c in img.getcolors(maxcolors=100000): if c[1] == MissingMaterials.HELL_PINK: return True return False
""" Get default audio data for each sub-object of a composite object. """ if __name__ == "__main__": from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument("--model", default="puzzle_box_composite") args = parser.parse_args() c = Controller() c.start() resp = c.communicate([ TDWUtils.create_empty_room(12, 12), c.get_add_object(model_name=args.model, object_id=0), { "$type": "send_composite_objects" }, { "$type": "send_segmentation_colors" } ]) c.communicate({"$type": "terminate"}) # Get the name of each object. colors = get_data(resp=resp, d_type=SegmentationColors) names = dict() for i in range(colors.get_num()): names[colors.get_object_id(i)] = colors.get_object_name(i) # Parse the composite object data. co = get_data(resp=resp, d_type=CompositeObjects) sub_objects = dict() for i in range(co.get_num()):
from tdw.controller import Controller c = Controller() print("Alles ist gut!") c.communicate({"$type": "terminate"})
# 1. Load the scene. # 2. Create an empty room (using a wrapper function) # 3. Add the table. # 4. Request Bounds data. resp = c.communicate([{ "$type": "load_scene", "scene_name": "ProcGenScene" }, TDWUtils.create_empty_room(12, 12), c.get_add_object(model_name=table_record.name, object_id=table_id, position={ "x": 0, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 0, "z": 0 }), { "$type": "send_bounds", "ids": [table_id], "frequency": "once" }]) # Get the top of the table. top_y = 0 for r in resp[:-1]: r_id = OutputData.get_data_type_id(r)
def run(self, c: Controller): """ Run the trial and save the output. :param c: The controller. """ print(f"Images will be saved to: {self.output_dir}") # Initialize the scene. resp = c.communicate(self.init_commands) # Get a map of the segmentation colors. segm = SegmentationColors(resp[0]) for i in range(segm.get_num()): for obj in self.moving_objects: if obj.object_id == segm.get_object_id(i): obj.possibility.segmentation_color = segm.get_object_color( i) # Request scene data and images per frame. frame_data: List[dict] = [] resp = c.communicate([{ "$type": "send_images", "frequency": "always" }, { "$type": "send_transforms", "ids": self.m_ids, "frequency": "always" }, { "$type": "send_rigidbodies", "ids": self.m_ids, "frequency": "always" }]) # Run the trial. for frame in range(self.num_frames): colors: Dict[int, Tuple[int, int, int]] = {} transforms: Dict[int, Tuple[float, float, float]] = {} transform_data = None rigidbody_data = None # Parse the output data. for r in resp[:-1]: r_id = OutputData.get_data_type_id(r) # Record all Transforms data. if r_id == "tran": transform_data = Transforms(r) for i in range(transform_data.get_num()): transforms.update({ transform_data.get_id(i): transform_data.get_position(i) }) # Record all Rigidbodies data. elif r_id == "rigi": rigidbody_data = Rigidbodies(r) # Save the images. elif r_id == "imag": images = Images(r) for p in range(images.get_num_passes()): if images.get_pass_mask(p) == "_id": image_colors = TDWUtils.get_pil_image( images, p).getcolors() for ic in image_colors: color = ic[1] for obj in self.moving_objects: if obj.possibility.segmentation_color == color: colors.update({obj.object_id: color}) TDWUtils.save_images(Images(r), TDWUtils.zero_padding(frame), output_directory=self.output_dir) # Append frame data. frame_data.append( Trial._get_frame_state(transform_data, rigidbody_data, frame)) # Build the frame state. state = State(colors, transforms, frame) # Apply object actions. commands = [] for o in self.occluders: commands.extend(o.get_frame_commands(state)) for mo in self.moving_objects: commands.extend(mo.get_frame_commands(state)) if len(commands) == 0: commands = [{"$type": "do_nothing"}] # Send the commands and update the state. resp = c.communicate(commands) # Cleanup. c.communicate([{ "$type": "destroy_all_objects" }, { "$type": "unload_asset_bundles" }, { "$type": "send_images", "frequency": "never" }, { "$type": "send_transforms", "ids": self.m_ids, "frequency": "never" }, { "$type": "send_rigidbodies", "ids": self.m_ids, "frequency": "never" }]) print("\tGenerated images.") # Output the scene metadata. Path(self.output_dir).joinpath("state.json").write_text( json.dumps({"frames": frame_data}), encoding="utf-8") print("\tWrote state file.") # Get _id passes with randomized colors. self._randomize_segmentation_colors() print("\tCreated random segmentation colors.") # Organize the images. self._organize_output() print("\tOrganized files")
from time import time from tdw.controller import Controller """ This is a minimal controller to test network performance. """ if __name__ == "__main__": num_trials = 50000 sizes = [1, 1000, 10000, 700000] c = Controller(launch_build=False, check_version=False) results = dict() for size in sizes: c.communicate({ "$type": "send_junk", "length": size, "frequency": "always" }) t0 = time() for i in range(num_trials): if i % 200 == 0: print('num_trials=%d' % i) c.communicate({"$type": "do_nothing"}) results[size] = (num_trials / (time() - t0)) c.communicate({"stop": True}) c.socket.close() print("") for size in results: print(size, round(results[size]))
).read_text(encoding="utf-8") c = Controller(launch_build=False) c.start() commands = [TDWUtils.create_empty_room(12, 12)] y = 0 o_id = 0 for line in txt.split("\n")[1:]: line_split = line.split(",") model = line_split[0] scale = float(line_split[1]) commands.extend([ c.get_add_object(model_name=model, object_id=o_id, position={ "x": 0, "y": y, "z": 0 }), { "$type": "scale_object", "scale_factor": { "x": scale, "y": scale, "z": scale }, "id": o_id } ]) o_id += 1 y += scale / 2 c.communicate(commands)
""" Do nothing. Then, do a *lot* of nothing. This script sends the do_nothing command once per frame for a thousand trials. Then, it sends it twice per frame, then four times per frame, etc. This will output the FPS per number of times do_nothing is sent per frame. This way, it is possible to gauge the effect that Command deserialization has on overall speed. """ if __name__ == "__main__": c = Controller(launch_build=False) c.start() c.communicate({"$type": "create_empty_environment"}) quantities = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] cmd = {"$type": "do_nothing"} num_trials = 1000 output = "| Quantity | Size (bytes) | FPS |\n| --- | --- | --- |\n" sizes = [] for quant in quantities: cmds = [] for q in range(quant): cmds.append(cmd)
from time import time from tdw.controller import Controller """ This is a minimal controller to test network performance with the ReqTest application. """ if __name__ == "__main__": num_trials = 1000 c = Controller() cmd = {"$type": "do_nothing"} c.communicate(cmd) t0 = time() for i in range(num_trials): c.communicate(cmd) fps = (num_trials / (time() - t0)) print(round(fps))
if __name__ == "__main__": c = Controller(launch_build=False) c.start() resp = c.communicate([ TDWUtils.create_empty_room(12, 12), c.get_add_object(model_name="rh10", position={ "x": 0, "y": 1, "z": 0 }, object_id=0), c.get_add_object(model_name="rh10", position={ "x": 0, "y": 2, "z": 0 }, object_id=1), { "$type": "send_collisions", "enter": True, "stay": True, "exit": True, "collision_types": ["obj", "env"] } ]) for i in range(200): # Read collision data. collisions = Collisions(resp=resp)
sbd = json.loads(SCENE_BOUNDS_PATH.read_text()) c = Controller() spawn_positions = dict() # Iterate through each floorplan scene. for scene in [1, 2, 4, 5]: print(scene) spawn_positions[scene] = dict() # Get the scene bounds (use this to get the actual (x, z) coordinates). scene_bounds = sbd[str(scene)] # Load the scene and request Environments data. resp = c.communicate([ c.get_add_scene(scene_name=f"floorplan_{scene}a"), { "$type": "send_environments" } ]) envs = get_data(resp=resp, d_type=Environments) # Get the center of each room. centers = [] for i in range(envs.get_num()): centers.append(np.array(envs.get_center(i))) # Get the spawn positions per layout. for layout in [0, 1, 2]: spawn_positions[scene][layout] = list() for center in centers: # Load the occupancy map. occ = np.load(
from getch import getch from tdw.output_data import Transforms from tdw.controller import Controller from tdw.tdw_utils import TDWUtils c = Controller() c.start() c.communicate(TDWUtils.create_empty_room(20, 20)) c.communicate([{ "$type": "set_screen_size", "width": 1280, "height": 962 }, { "$type": "set_render_quality", "render_quality": 2 }]) c.communicate( TDWUtils.create_avatar(avatar_id="avatar", position={ "x": 3, "y": 1.5, "z": 3 }, look_at={ "x": 0, "y": 0, "z": 0 })) o_id = c.add_object(model_name="iron_box", position={ "x": 0,
if __name__ == "__main__": c = Controller(launch_build=False) c.start() robot_id = 0 avatar_id = "a" # Add a Magnebot to the scene. Request static robot data. resp = c.communicate([ TDWUtils.create_empty_room(12, 12), { "$type": "add_magnebot", "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 }, "id": robot_id }, { "$type": "send_static_robots", "frequency": "once" } ]) # Find the static robot data and get the ID of the torso. torso_id = -1 for i in range(len(resp) - 1): r_id = OutputData.get_data_type_id(resp[i]) if r_id == "srob": static_robot = StaticRobot(resp[i])
"frequency": "once" } ] # Add a camera to the scene. commands.extend( TDWUtils.create_avatar(position={ "x": -2.49, "y": 4, "z": 0 }, look_at={ "x": 0, "y": 0, "z": 0 })) resp = c.communicate(commands) wheel_ids = [] for i in range(len(resp) - 1): r_id = OutputData.get_data_type_id(resp[i]) if r_id == "srob": sr = StaticRobot(resp[i]) for j in range(sr.get_num_joints()): joint_id = sr.get_joint_id(j) joint_name = sr.get_joint_name(j) print(joint_name, joint_id) # Find all of the wheels. if "wheel" in joint_name: wheel_ids.append(joint_id) # Move the wheels forward. commands = []
def materials_are_missing(c: Controller, record: ModelRecord, url: str) -> bool: """ Check for missing materials. :param c: The controller. :param record: The model metadata record. :param url: The path to the model. :return: True if the model is missing materials. """ # Disable post-processing. # Disable shadows. # Create the avatar. # Set pass masks. # Send images. # Add the object. # Add the object. # Load the bounds of the model. scale = TDWUtils.get_unit_scale(record) c.communicate([{ "$type": "send_images", "frequency": "always" }, { "$type": "add_object", "name": record.name, "url": url, "scale_factor": record.scale_factor, "id": MissingMaterials.OBJECT_ID }, { "$type": "scale_object", "id": MissingMaterials.OBJECT_ID, "scale_factor": { "x": scale, "y": scale, "z": scale } }]) x = 1.75 y = 0.5 z = 0 # Equatorial orbit. theta = 0 while theta < 360: # Get the new position. rad = radians(theta) x1 = cos(rad) * x - sin(rad) * z z1 = sin(rad) * x + cos(rad) * z if MissingMaterials._orbit_and_capture_image(c, x1, y, z1): return True theta += MissingMaterials.DELTA_THETA # Polar orbit. theta = 0 while theta < 360: # Get the new position. rad = radians(theta) x1 = cos(rad) * x - sin(rad) * z y1 = (sin(rad) * x + cos(rad) * z) + y if MissingMaterials._orbit_and_capture_image(c, x1, y1, z): return True theta += MissingMaterials.DELTA_THETA return False
"x": 0, "y": 0, "z": 0 }, "id": o_id }, { "$type": "rotate_object_to", "rotation": { "w": 1, "x": 0, "y": 0, "z": 0 }, "id": o_id }] c = Controller() c.start() c.communicate([ TDWUtils.create_empty_room(12, 12), c.get_add_object("rh10", object_id=o_id) ]) num_trials = 5000 t0 = time() for i in range(num_trials): c.communicate(cmds) fps = (num_trials / (time() - t0)) print(f"FPS: {round(fps)}") c.communicate({"$type": "terminate"})