Skip to content

Latest commit

 

History

History
158 lines (121 loc) · 6.26 KB

File metadata and controls

158 lines (121 loc) · 6.26 KB
Scene Setup (Low-Level APIs)

Bounds output data

As noted earlier, the object position returned by Transforms output data is the bottom-center of the object. To get the center of the object, you need to request Bounds output data with the send_bounds command:

from tdw.controller import Controller
from tdw.tdw_utils import TDWUtils
from tdw.output_data import OutputData, Bounds

c = Controller()
object_id = c.get_unique_id()

# Create the scene. Add an object. Request Bounds output data.
resp = c.communicate([TDWUtils.create_empty_room(12, 12),
                      c.get_add_object(model_name="small_table_green_marble",
                                       position={"x": 0, "y": 0, "z": 0},
                                       object_id=object_id),
                      {"$type": "send_bounds",
                       "frequency": "once"}])

# Get the center of the object.
for i in range(len(resp) - 1):
    r_id = OutputData.get_data_type_id(resp[i])
    if r_id == "boun":
        bounds = Bounds(resp[i])
        for j in range(bounds.get_num()):
            if bounds.get_id(j) == object_id:
                print(object_id, bounds.get_center(j))
c.communicate({"$type": "terminate"})

The bounds data also includes the top, bottom, left, right, front, and back of each object. In this example, we'll use the top of the bounds to place another object on the table:

from tdw.controller import Controller
from tdw.tdw_utils import TDWUtils
from tdw.output_data import OutputData, Bounds
from tdw.add_ons.third_person_camera import ThirdPersonCamera
from tdw.add_ons.image_capture import ImageCapture
from tdw.backend.paths import EXAMPLE_CONTROLLER_OUTPUT_PATH

c = Controller()
object_id = c.get_unique_id()

# Add a camera and enable image capture.
cam = ThirdPersonCamera(position={"x": 2.478, "y": 1.602, "z": 1.412},
                        look_at={"x": 0, "y": 0.5, "z": 0},)
output_directory = EXAMPLE_CONTROLLER_OUTPUT_PATH.joinpath("bounds")
print(f"Images will be saved to: {output_directory.resolve()}")
c.add_ons.append(cam)
cap = ImageCapture(path=output_directory, avatar_ids=[cam.avatar_id], pass_masks=["_img"])
c.add_ons.append(cap)
# Create the scene. Add a table. Request Bounds output data.
resp = c.communicate([TDWUtils.create_empty_room(12, 12),
                      c.get_add_object(model_name="small_table_green_marble",
                                       position={"x": 0, "y": 0, "z": 0},
                                       object_id=object_id),
                      {"$type": "send_bounds",
                       "frequency": "once"}])

# Get the top of the table.
top = (0, 0, 0)
for i in range(len(resp) - 1):
    r_id = OutputData.get_data_type_id(resp[i])
    if r_id == "boun":
        bounds = Bounds(resp[i])
        for j in range(bounds.get_num()):
            if bounds.get_id(j) == object_id:
                top = bounds.get_top(j)
                break
# Put an object on top of the table.
c.communicate(c.get_add_object(model_name="jug01",
                               position=TDWUtils.array_to_vector3(top),
                               object_id=c.get_unique_id()))
c.communicate({"$type": "terminate"})

Result:

The ObjectManager add-on

We've seen the ObjectManager add-on in the Core Concepts documentation. If you need to frequently use bounds data, you can use the ObjectManager which will conveniently sort all bounds data by object per frame.

Note that:

  • In this example, the ObjectManager will include data for the table but not for the object on the table because that object didn't exist when the ObjectManager was initialized.
  • Bounds data is returned by the build as (x, y, z) tuples but in ObjectManager data those tuples are automatically converted into numpy arrays.

This controller does the exact same thing as the previous example but uses an ObjectManager:

from tdw.controller import Controller
from tdw.tdw_utils import TDWUtils
from tdw.add_ons.third_person_camera import ThirdPersonCamera
from tdw.add_ons.image_capture import ImageCapture
from tdw.backend.paths import EXAMPLE_CONTROLLER_OUTPUT_PATH
from tdw.add_ons.object_manager import ObjectManager

c = Controller()
object_id = c.get_unique_id()

# Add a camera and enable image capture.
cam = ThirdPersonCamera(position={"x": 2.478, "y": 1.602, "z": 1.412},
                        look_at={"x": 0, "y": 0.5, "z": 0},)
output_directory = EXAMPLE_CONTROLLER_OUTPUT_PATH.joinpath("bounds")
print(f"Images will be saved to: {output_directory.resolve()}")
c.add_ons.append(cam)
cap = ImageCapture(path=output_directory, avatar_ids=[cam.avatar_id], pass_masks=["_img"])
c.add_ons.append(cap)

# Add an ObjectManager.
om = ObjectManager(transforms=False, bounds=True, rigidbodies=True)
c.add_ons.append(om)

# Create the scene. Add a table. Request Bounds output data.
resp = c.communicate([TDWUtils.create_empty_room(12, 12),
                      c.get_add_object(model_name="small_table_green_marble",
                                       position={"x": 0, "y": 0, "z": 0},
                                       object_id=object_id)])

# Get the top of the table.
top = om.bounds[object_id].top
# Put an object on top of the table.
c.communicate(c.get_add_object(model_name="jug01",
                               position=TDWUtils.array_to_vector3(top),
                               object_id=c.get_unique_id()))
c.communicate({"$type": "terminate"})

Next: Materials, textures, and colors

Return to the README


Example controllers:

Python API:

Command API:

Output Data API: