Scatter assets randomly

../_images/spawnzone.gif

Learn how to declare object positions quickly using SpawnZone.

bbi.SpawnZone

Random scattering of assets within a defined zone.

SpawnZone provides a quick and easy way to scatter assets randomly within a specified area, without having to go through the tedious process of manually handcrafting each object’s position and rotation.

Creating a SpawnZone object can be driven by two types of geometries, Polygon and Spline. These geometries define the line or area on/in which the assets will be scattered.

Scatter assets randomly in an area

Scattering assets in an area is useful for quickly placing larger amounts of distractors or background objects. Below, we scatter 10 harbor launch boats within a polygon formed from points we pick from the viewport.

Tip

To create Polygons faster, use the Coordinate Picker viewport tool to pick coordinates from the viewport, which will copy them to your clipboard.

Pass these coordinates to Vector3 points to create a Polygon.

Scattering in an area or volume
 1from bbi import *
 2
 3world = World("lake")
 4
 5# Set the camera to the desired position
 6world.camera.set_transform(
 7    Transform(
 8        position=Vector3(0, 0, 10),
 9        rotation=Vector3(0, 3, 175),
10    ),
11)
12
13# Use the picker to select SpawnZone boundary points
14poly = Polygon(
15    node_id="my_poly",
16    points=[
17        Vector3(-47.4, 34.95, 0),
18        Vector3(-19.95, 16.03, 0),
19        Vector3(-21.03, -12.97, 0),
20        Vector3(-70.03, -50.12, 0),
21        Vector3(-115.83, -39.97, 0),
22        Vector3(-85.21, 22.47, 0),
23    ],
24)
25world.add(poly)
26
27zone = SpawnZone(
28    node_id="my_zone",
29    asset_names=[
30        "Ivory MT",
31        "Grimmershorn",
32        "USCG Auxiliary Boat",
33        "CoastGuard Ship Singapore B",
34        "CoastGuard Ship Singapore A"
35    ],
36    quantity=15,
37    geometry=poly,
38    asset_type=Asset, # or BuoyantAsset
39    yaw_range=(0, 360),
40    asset_weights=[1, 1, 1, 1, 1],
41    force_respawn=True,
42)
43world.add(zone)
44
45scenario = world.new_scenario(num_frames=5)
46scenario.preview_animation()

First, we create a Polygon object using the coordinate picker tool.

Next, we create a SpawnZone object and specify the following:

Argument

Functionality

node_id

A unqiue ID for the SpawnZone.

asset_names

A list of asset names to spawn.

Select assets from Bifrost’s asset library by clicking on the Asset tab on the bottom drawer at the top of the notebook.

quantity

The maximum number of assets to spawn.

The actual number of assets spawned might be less than this number if there isn’t sufficient space in the geometry.

geometry

The defined geometry to spawn the assets in.

asset_type (optional)

The type of asset to spawn. Defaults to Asset.

Either BuoyantAsset or Asset.

yaw_range (optional)

The max and min yaw in degrees of the spawned assets. Defaults to (0, 360).

For splines, the rotation would be the tangent to the spline at the spawn point.

asset_weights (optional)

The relative weight of spawning each asset in the asset_names list.

The weights will be normalized to a probability internally.

force_respawn (optional)

Forcibly respawn assets in scenarios at each keyframe. Defaults to False.

If the SpawnZone parameters change between frames, assets will be respawned regardless of this value.

Finally, we add the SpawnZone to the world and create the scenario and the assets will be scattered within the bounds of the specified geometry.

Attention

When two or more SpawnZones overlap, the zone that was added first will take precedence, spawning its assets first. Subsequent zones will look for available space to avoid collisions with existing assets.

Example: creating additional overlapping SpawnZones
poly2 = Polygon(
    node_id="my_poly_2",
    points=[
        Vector3(-36.45, 37.98, 0),
        Vector3(-41.17, 23.14, 0),
        Vector3(-18.62, 9.87, 0),
        Vector3(-18.15, 19.91, 0),
    ],
)
world.add(poly2)
zone2 = SpawnZone(
    node_id="my_zone_2",
    asset_names=["Irwin 38"],
    quantity=10,
    geometry=poly2,
)
world.add(zone2) # Added second. Will avoid assets spawned by zone1.
../_images/spawnzone-overlap.jpg

Defining or using existing geometries in the world

Using World geometries

Some worlds are shipped with prebuilt geometry that can be used to drive SpawnZones.

Access a list of available geometries using:

Example: listing available geometries
world.get_cuboids() # returns a list of Cuboid geometries
world.get_splines() # returns a list of Spline geometries

Define your own geometries

Alternatively, define your own shapes using Geometry. You can create multiple SpawnZones using the same geometry, which is useful for spawning specific quantities of assets in the same area.

You can use the following geometries to define your SpawnZones:

bbi.Polygon

A 3D polygon defined by a list of Vector3 points.

bbi.Spline

A curved spline constructed using a list of Vector3 positions, and optionally a list of Vector3 tangents.

Note

It is optional to add the geometries to the world. Add them if you want to visualize them with the “Show guide geometry” option at the top left of the viewport.

Adding the geometries to the world
world.add(area1)
world.add(area2)