Object Instructions

As mentioned before, properties can be modified via instructions that affect objects according to the three.js documentation.

All objects share a common set of basic properties described in the following, while additional properties specific to certain object types are described in their respective sections.

Note

Instructions sent with update are only applied to objects and materials that currently exist in the scene. Sending one for a deleted or never created target has no effect: the server discards it and names it in the response, while the call itself still succeeds. The Python client turns that into a LiveInstructionWarning, the Rust client logs it. This keeps an instruction from outliving its target and being inherited by the next object created under the same identifier. For the same reason an identifier must not be empty and must not contain a tab or a newline; the server refuses to create such an object or material. Anchor instructions are exempt from both, since they are defined ahead of the objects they address, and they are also kept when their target is deleted.

Basic properties

All objects have a set of basic properties that can be updated via instructions:

  • position: The new absolute position of the object with respect to the world origin or its parent.

  • rotation: The new absolute rotation (Euler XYZ in radians) of the object with respect to the world origin or its parent.

  • quaternion: The new absolute quaternion (XYZW) of the object with respect to the world origin or its parent.

  • scale: The absolute scale of the object.

  • visible: The visibility of the object.

  • parent: Attaches an object to a parent. Setting the parent to None detaches the object from its current parent.

Note

All objects also have a material property that can be updated dynamically. However, material characteristics depend on the object type, therefore material instructions are described in the respective object sections.

Position

This instruction updates the position of the object.

The Cartesian position values x, y and z can be updated individually or all together (xyz).

Example:

 1    visu = Visu(voraus_3d_visu, clear_all=True)
 2    box1 = visu.add_model(box_glb, position=[0, 0, 0.1])
 3    box2 = visu.add_model(box_glb, position=[0, 0, 0.1])
 4    box3 = visu.add_model(box_glb, position=[0, 0, 0.1])
 5    box4 = visu.add_model(box_glb, position=[0, 0, 0.1])
 6
 7    with visu.connection():
 8        visu.update(
 9            box1.position.x(1),
10            box2.position.y(1),
11            box3.position.z(0.3),
12            box4.position.xyz(1, 1, 0.3),
13        )
 1let mut visu = Visu::new(url, false, false, true, None)?;
 2let box1 = add_model(&visu, box_glb, [0.0, 0.0, 0.1])?;
 3let box2 = add_model(&visu, box_glb, [0.0, 0.0, 0.1])?;
 4let box3 = add_model(&visu, box_glb, [0.0, 0.0, 0.1])?;
 5let box4 = add_model(&visu, box_glb, [0.0, 0.0, 0.1])?;
 6
 7let mut connection = visu.connection()?;
 8connection.update(vec![
 9    box1.position().x(1.0),
10    box2.position().y(1.0),
11    box3.position().z(0.3),
12    box4.position().xyz(1.0, 1.0, 0.3),
13])?;
Result of position example

Fig. 7 Result of position example

Rotation

This instruction updates the rotation of the object.

The Cartesian rotation values x, y and z can be updated individually or all together (xyz).

Rotations are defined by Euler(XYZ).

Example:

 1    visu = Visu(voraus_3d_visu, clear_all=True)
 2    box1 = visu.add_model(box_glb, position=[0, -0.75, 0])
 3    box2 = visu.add_model(box_glb, position=[0, -0.25, 0])
 4    box3 = visu.add_model(box_glb, position=[0, 0.25, 0])
 5    box4 = visu.add_model(box_glb, position=[0, 0.75, 0])
 6
 7    with visu.connection():
 8        visu.update(
 9            box1.rotation.x(1.57),
10            box2.rotation.y(1.57),
11            box3.rotation.z(1.57),
12            box4.rotation.xyz(1, 1, 1),
13        )
 1let mut visu = Visu::new(url, false, false, true, None)?;
 2let box1 = add_model(&visu, box_glb, [0.0, -0.75, 0.0])?;
 3let box2 = add_model(&visu, box_glb, [0.0, -0.25, 0.0])?;
 4let box3 = add_model(&visu, box_glb, [0.0, 0.25, 0.0])?;
 5let box4 = add_model(&visu, box_glb, [0.0, 0.75, 0.0])?;
 6
 7let mut connection = visu.connection()?;
 8connection.update(vec![
 9    box1.rotation().x(1.57),
10    box2.rotation().y(1.57),
11    box3.rotation().z(1.57),
12    box4.rotation().xyz(1.0, 1.0, 1.0),
13])?;
Result of the rotation example

Fig. 8 Result of the rotation example

Quaternion

This instruction updates the quaternions of the object.

The values x, y, z and w are updated all together.

Example:

1    visu = Visu(voraus_3d_visu, clear_all=True)
2    box = visu.add_model(box_glb, position=[0, 0, 0])
3
4    with visu.connection():
5        visu.update(
6            box.quaternion.xyzw(0.653012, 0.270728, 0.6532274, 0.2712483),
7        )
1let mut visu = Visu::new(url, false, false, true, None)?;
2let box_model = add_model(&visu, box_glb, [0.0, 0.0, 0.0])?;
3
4let mut connection = visu.connection()?;
5connection.update(vec![box_model
6    .quaternion()
7    .xyzw(0.653012, 0.270728, 0.6532274, 0.2712483)])?;
Result of the quaternion example

Fig. 9 Result of the quaternion example

Scale

This instruction updates the scaling of the object.

The Cartesian scaling parameters x, y and z can be updated individually or all together (xyz).

Example:

 1    visu = Visu(voraus_3d_visu, clear_all=True)
 2    box1 = visu.add_model(box_glb, position=[0, -0.75, 0])
 3    box2 = visu.add_model(box_glb, position=[0, -0.25, 0])
 4    box3 = visu.add_model(box_glb, position=[0, 0.25, 0])
 5    box4 = visu.add_model(box_glb, position=[0, 0.75, 0])
 6
 7    with visu.connection():
 8        visu.update(
 9            box1.scale.x(2),
10            box2.scale.y(2),
11            box3.scale.z(2),
12            box4.scale.xyz(2, 2, 2),
13        )
 1let mut visu = Visu::new(url, false, false, true, None)?;
 2let box1 = add_model(&visu, box_glb, [0.0, -0.75, 0.0])?;
 3let box2 = add_model(&visu, box_glb, [0.0, -0.25, 0.0])?;
 4let box3 = add_model(&visu, box_glb, [0.0, 0.25, 0.0])?;
 5let box4 = add_model(&visu, box_glb, [0.0, 0.75, 0.0])?;
 6
 7let mut connection = visu.connection()?;
 8connection.update(vec![
 9    box1.scale().x(2.0),
10    box2.scale().y(2.0),
11    box3.scale().z(2.0),
12    box4.scale().xyz(2.0, 2.0, 2.0),
13])?;
Result of the scale example

Fig. 10 Result of the scale example

Parent

This instruction defines a new parent of the object.

Once coupled, all transformation instructions for a child are applied relative to the origin of the parent object.

Changes to the parent also apply to descending children.

Setting a parent to None decouples a child from its current parent.

The parent has to exist when the instruction is sent, and a child is detached again when its parent object is deleted. Without that, the child would stay inside the removed subtree and would be re-attached to whichever object is created next under the parent’s identifier.

An object also cannot become a child of itself or of anything below it, whether directly or through a chain of parents. Such an instruction is discarded as well, since the browser cannot apply it without dropping the objects involved from the scene.

The instructions of one update call are checked in the order they are given, against the hierarchy as it stands at that point. To move an object below one of its current descendants, detach the descendant first and send the new parent after it, in the same call or a later one. In the other order the new parent is discarded, because it would close a cycle at the moment it is applied.

Example:

1    visu = Visu(voraus_3d_visu, clear_all=True)
2    box1 = visu.add_model(box_glb, position=[0, 0, 0.1])
3    box2 = visu.add_model(box_glb, position=[0, 1, 0.1])
4
5    with visu.connection():
6        visu.update(
7            box2.parent(box1),
8            box1.position.x(2),
9        )
1let mut visu = Visu::new(url, false, false, true, None)?;
2let box1 = add_model(&visu, box_glb, [0.0, 0.0, 0.1])?;
3let box2 = add_model(&visu, box_glb, [0.0, 1.0, 0.1])?;
4
5let mut connection = visu.connection()?;
6connection.update(vec![box2.parent(Some(&box1)), box1.position().x(2.0)])?;
The result of the parent instruction

Fig. 11 Result of the parent example

Visible

This instruction updates the visibility of the object.

Example:

 1    visu = Visu(voraus_3d_visu, clear_all=True)
 2    robot1 = visu.add_model(robot_glb, position=[0, 0, 0])
 3    robot2 = visu.add_model(robot_glb, position=[0, 1, 0])
 4
 5    with visu.connection():
 6        visu.update(
 7            robot1.child("Base").visible(False),
 8            robot1.child("Segment2").visible(False),
 9            robot1.child("Segment4").visible(False),
10            robot1.child("Segment6").visible(False),
11            robot2.visible(False),
12        )
 1let mut visu = Visu::new(url, false, false, true, None)?;
 2let robot1 = add_model(&visu, robot_glb, [0.0, 0.0, 0.0])?;
 3let robot2 = add_model(&visu, robot_glb, [0.0, 1.0, 0.0])?;
 4
 5let mut connection = visu.connection()?;
 6connection.update(vec![
 7    robot1.child("Base").visible(false),
 8    robot1.child("Segment2").visible(false),
 9    robot1.child("Segment4").visible(false),
10    robot1.child("Segment6").visible(false),
11    robot2.visible(false),
12])?;
Result of the visible example

Fig. 12 Result of the visible example

Render Order

This instruction overrides the default draw-order sort. It is mainly relevant for transparent objects, where blending order against other transparent objects (e.g. two overlapping, coplanar objects) should be decided explicitly instead of by depth.

Render order does not cascade to children in the underlying renderer, unlike most other object properties. Use render_order to set it on the object itself, or render_order_recursive to also set it on all descending children.

Example:

 1    visu = Visu(voraus_3d_visu, clear_all=True)
 2    box1 = visu.add_model(box_glb, position=[0, 0, 0.1], unique_material=True)
 3    box2 = visu.add_model(box_glb, position=[0.2, 0, 0.1], unique_material=True)
 4
 5    with visu.connection():
 6        visu.update(
 7            box1.material.color.rgb(1.0, 0.2, 0.2),  # orange
 8            box1.material.transparency(0.6),
 9            box1.material.depth_test(False),
10            box2.material.color.rgb(0.1, 0.4, 1.0),  # blue
11            box2.material.transparency(0.6),
12            box2.material.depth_test(False),
13            box2.render_order(0),
14            box1.render_order(1),
15        )
 1let mut visu = Visu::new(url, false, false, true, None)?;
 2let box1 = add_model_unique(&visu, box_glb, [0.0, 0.0, 0.1], true)?;
 3let box2 = add_model_unique(&visu, box_glb, [0.2, 0.0, 0.1], true)?;
 4
 5let mut connection = visu.connection()?;
 6connection.update(vec![
 7    box1.material()?.color().rgb(1.0, 0.2, 0.2), // orange
 8    box1.material()?.transparency(0.6)?,
 9    box1.material()?.depth_test(false),
10    box2.material()?.color().rgb(0.1, 0.4, 1.0), // blue
11    box2.material()?.transparency(0.6)?,
12    box2.material()?.depth_test(false),
13    box2.render_order(0.0),
14    box1.render_order(1.0),
15])?;
Result of the render_order example

Fig. 13 Result of the render_order example