Improve ordering of asset documentation, sort by category and usefulness.
- Old: texture, hfield, mesh, skin, material. - New: mesh, hfield, skin, texture, material. Rationale: First 3D assets, then surface assets. Mesh is the most common asset type. Materials reference textures so should come right after. PiperOrigin-RevId: 602075615 Change-Id: I13e4404640184fb0717a442827cd76da31705648
This commit is contained in:
committed by
Copybara-Service
parent
3b0a680fa7
commit
70021a7236
+327
-322
@@ -1138,6 +1138,8 @@ disables the rendering of the corresponding object.
|
||||
:at:`bvactive`: :at-val:`real(4), "1 0 0 0.5"`
|
||||
Color used to render active bounding volumes, if the :ref:`bvactive<visual-global-bvactive>` flag is "true".
|
||||
|
||||
|
||||
|
||||
.. _asset:
|
||||
|
||||
**asset** (*)
|
||||
@@ -1151,6 +1153,331 @@ extension if no ``content_type`` attribute is specified. The content type is ign
|
||||
file.
|
||||
|
||||
|
||||
.. _asset-mesh:
|
||||
|
||||
:el-prefix:`asset/` |-| **mesh** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This element creates a mesh asset, which can then be referenced from geoms. If the referencing geom type is
|
||||
:at-val:`mesh` the mesh is instantiated in the model, otherwise a geometric primitive is automatically fitted to it; see
|
||||
the :ref:`geom <body-geom>` element below.
|
||||
|
||||
MuJoCo works with triangulated meshes. They can be loaded from binary STL files, OBJ files or MSH files with custom
|
||||
format described below, or vertex and face data specified directly in the XML. Software such as MeshLab can be used to
|
||||
convert from other mesh formats to STL or OBJ. While any collection of triangles can be loaded as a mesh and rendered,
|
||||
collision detection works with the convex hull of the mesh as explained in :ref:`Collision`. See also the convexhull
|
||||
attribute of the :ref:`compiler <compiler>` element which controls the automatic generation of convex hulls. The mesh
|
||||
appearance (including texture mapping) is controlled by the :at:`material` and :at:`rgba` attributes of the referencing
|
||||
geom, similarly to height fields.
|
||||
|
||||
Meshes can have explicit texture coordinates instead of relying on the automated texture
|
||||
mapping mechanism. When provided, these explicit coordinates have priority. Note that texture coordinates can be
|
||||
specified with OBJ files and MSH files, as well as explicitly in the XML with the :at:`texcoord` attribute, but not via
|
||||
STL files. These mechanism cannot be mixed. So if you have an STL mesh, the only way to add texture coordinates to it is
|
||||
to convert to one of the other supported formats.
|
||||
|
||||
MSH file format
|
||||
The binary MSH file starts with 4 integers specifying the number of vertex positions (nvertex), vertex normals
|
||||
(nnormal), vertex texture coordinates (ntexcoord), and vertex indices making up the faces (nface), followed by the
|
||||
numeric data. nvertex must be at least 4. nnormal and ntexcoord can be zero (in which case the corresponding data is
|
||||
not defined) or equal to nvertex. nface can also be zero, in which case faces are constructed automatically from the
|
||||
convex hull of the vertex positions. The file size in bytes must be exactly: 16 + 12*(nvertex + nnormal + nface) +
|
||||
8*ntexcoord. The contents of the file must be as follows:
|
||||
|
||||
.. code:: Text
|
||||
|
||||
(int32) nvertex
|
||||
(int32) nnormal
|
||||
(int32) ntexcoord
|
||||
(int32) nface
|
||||
(float) vertex_positions[3*nvertex]
|
||||
(float) vertex_normals[3*nnormal]
|
||||
(float) vertex_texcoords[2*ntexcoord]
|
||||
(int32) face_vertex_indices[3*nface]
|
||||
|
||||
Poorly designed meshes can display rendering artifacts. In particular, the shadow mapping mechanism relies on having
|
||||
some distance between front and back-facing triangle faces. If the faces are repeated, with opposite normals as
|
||||
determined by the vertex order in each triangle, this causes shadow aliasing. The solution is to remove the repeated
|
||||
faces (which can be done in MeshLab) or use a better designed mesh. Flipped faces are checked by MuJoCo for meshes
|
||||
specified as OBJ or XML and an error message is returned.
|
||||
|
||||
The size of the mesh is determined by the 3D coordinates of the vertex data in the mesh file, multiplied by the
|
||||
components of the :at:`scale` attribute below. Scaling is applied separately for each coordinate axis. Note that
|
||||
negative scaling values can be used to flip the mesh; this is a legitimate operation. The size parameters of the
|
||||
referening geoms are ignored, similarly to height fields. We also provide a mechanism to translate and
|
||||
rotate the 3D coordinates, using the attributes :ref:`refpos<asset-mesh-refpos>` and :ref:`refquat<asset-mesh-refquat>`.
|
||||
|
||||
A mesh can also be defined without faces (a point cloud essentially). In that case
|
||||
the convex hull is constructed automatically, even if the compiler attribute convexhull is false. This makes it easy to
|
||||
construct simple shapes directly in the XML. For example, a pyramid can be created as:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<asset>
|
||||
<mesh name="tetrahedron" vertex="0 0 0 1 0 0 0 1 0 0 0 1"/>
|
||||
</asset>
|
||||
|
||||
Positioning and orienting is complicated by the fact that vertex data are often designed relative to coordinate frames
|
||||
whose origin is not inside the mesh. In contrast, MuJoCo expects the origin of a geom's local frame to coincide with the
|
||||
geometric center of the shape. We resolve this discrepancy by pre-processing the mesh in the compiler, so that it is
|
||||
centered around (0,0,0) and its principal axes of inertia are the coordinate axes. We also save the translation and
|
||||
rotation offsets needed to achieve such alignment in :ref:`mjModel.mesh_pos<mjModel>` and
|
||||
:ref:`mjModel.mesh_quat<mjModel>`. These offsets are then applied to the referencing geom's position and orientation; see
|
||||
also :at:`mesh` attribute of :ref:`geom <body-geom>` below. Fortunately most meshes used in robot models are designed in
|
||||
a coordinate frame centered at the joint. This makes the corresponding MJCF model intuitive: we set the body frame at the
|
||||
joint, so that the joint position is (0,0,0) in the body frame, and simply reference the mesh. Below is an MJCF model
|
||||
fragment of a forearm, containing all the information needed to put the mesh where one would expect it to be. The body
|
||||
position is specified relative to the parent body, namely the upper arm (not shown). It is offset by 35 cm which is the
|
||||
typical length of the human upper arm. If the mesh vertex data were not designed in the above convention, we would have
|
||||
to use the geom position and orientation (or the new refpos, refquat mechanism) to compensate, but in practice this is
|
||||
rarely needed.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<asset>
|
||||
<mesh file="forearm.stl"/>
|
||||
</asset>
|
||||
|
||||
<body pos="0 0 0.35"/>
|
||||
<joint type="hinge" axis="1 0 0"/>
|
||||
<geom type="mesh" mesh="forearm"/>
|
||||
</body>
|
||||
|
||||
The inertial computation mentioned above is part of an algorithm used not only to center and align the mesh, but also to
|
||||
infer the mass and inertia of the body to which it is attached. This is done by computing the centroid of the triangle
|
||||
faces, connecting each face with the centroid to form a triangular pyramid, computing the mass and signed inertia of all
|
||||
pyramids (considered solid or hollow if :at:`shellinertia` is true) and accumulating them. The sign ensures that
|
||||
pyramids on the outside of the surfaces are subtracted, as it can occur with concave geometries. This algorithm can be
|
||||
found in section 1.3.8 of Computational Geometry in C (Second Edition) by Joseph O'Rourke.
|
||||
|
||||
The full list of processing steps applied by the compiler to each mesh is as follows:
|
||||
|
||||
#. For STL meshes, remove any repeated vertices and re-index the faces if needed. If the mesh is not STL, we assume that
|
||||
the desired vertices and faces have already been generated and do not apply removal or re-indexing;
|
||||
#. If vertex normals are not provided, generate normals automatically, using a weighted average of the surrounding face
|
||||
normals. If sharp edges are encountered, the renderer uses the face normals to preserve the visual information about
|
||||
the edge, unless smoothnormal is true. Note that normals cannot be provided with STL meshes;
|
||||
#. Scale, translate and rotate the vertices and normals, re-normalize the normals in case of scaling;
|
||||
#. Construct the convex hull if specified;
|
||||
#. Find the centroid of all triangle faces, and construct the union-of-pyramids representation. Triangles whose area is
|
||||
too small (below the :ref:`mjMINVAL <glNumeric>` value of 1E-14) result in compile error;
|
||||
#. Compute the center of mass and inertia matrix of the union-of-pyramids. Use eigenvalue decomposition to find the
|
||||
principal axes of inertia. Center and align the mesh, saving the translational and rotational offsets for subsequent
|
||||
geom-related computations.
|
||||
|
||||
.. _asset-mesh-name:
|
||||
|
||||
:at:`name`: :at-val:`string, optional`
|
||||
Name of the mesh, used for referencing. If omitted, the mesh name equals the file name without the path and
|
||||
extension.
|
||||
|
||||
.. _asset-mesh-class:
|
||||
|
||||
:at:`class`: :at-val:`string, optional`
|
||||
Defaults class for setting unspecified attributes (only scale in this case).
|
||||
|
||||
.. _asset-mesh-content_type:
|
||||
|
||||
:at:`content_type`: :at-val:`string, optional`
|
||||
If the file attribute is specified, then this sets the
|
||||
`Media Type <https://www.iana.org/assignments/media-types/media-types.xhtml>`_ (formerly known as MIME type) of the
|
||||
file to be loaded. Any filename extensions will be overloaded. Currently ``model/vnd.mujoco.msh``, ``model/obj``,
|
||||
and ``model/stl`` are supported.
|
||||
|
||||
.. _asset-mesh-file:
|
||||
|
||||
:at:`file`: :at-val:`string, optional`
|
||||
The file from which the mesh will be loaded. The path is determined as described in the meshdir attribute of
|
||||
:ref:`compiler <compiler>`. The file extension must be "stl", "msh", or "obj" (not case sensitive) specifying the
|
||||
file type. If the file name is omitted, the vertex attribute becomes required.
|
||||
|
||||
.. _asset-mesh-scale:
|
||||
|
||||
:at:`scale`: :at-val:`real(3), "1 1 1"`
|
||||
This attribute specifies the scaling that will be applied to the vertex data along each coordinate axis. Negative
|
||||
values are allowed, resulting in flipping the mesh along the corresponding axis.
|
||||
|
||||
.. _asset-mesh-smoothnormal:
|
||||
|
||||
:at:`smoothnormal`: :at-val:`[false, true], "false"`
|
||||
Controls the automatic generation of vertex normals when normals are not given explicitly. If true, smooth normals
|
||||
are generated by averaging the face normals at each vertex, with weight proportional to the face area. If false,
|
||||
faces at large angles relative to the average normal are excluded from the average. In this way, sharp edges (as in
|
||||
cube edges) are not smoothed.
|
||||
|
||||
.. _asset-mesh-vertex:
|
||||
|
||||
:at:`vertex`: :at-val:`real(3*nvert), optional`
|
||||
Vertex 3D position data. You can specify position data in the XML using this attribute, or using a binary file, but
|
||||
not both.
|
||||
|
||||
.. _asset-mesh-normal:
|
||||
|
||||
:at:`normal`: :at-val:`real(3*nvert), optional`
|
||||
Vertex 3D normal data. If specified, the number of normals must equal the number of vertices. The model compiler
|
||||
normalizes the normals automatically.
|
||||
|
||||
.. _asset-mesh-texcoord:
|
||||
|
||||
:at:`texcoord`: :at-val:`real(2*nvert), optional`
|
||||
Vertex 2D texture coordinates, which are numbers between 0 and 1. If specified, the number of texture coordinate
|
||||
pairs must equal the number of vertices.
|
||||
|
||||
.. _asset-mesh-face:
|
||||
|
||||
:at:`face`: :at-val:`int(3*nface), optional`
|
||||
Faces of the mesh. Each face is a sequence of 3 vertex indices, in counter-clockwise order. The indices must be
|
||||
integers between 0 and nvert-1.
|
||||
|
||||
.. _asset-mesh-refpos:
|
||||
|
||||
:at:`refpos`: :at-val:`real(3), "0 0 0"`
|
||||
Reference position relative to which the 3D vertex coordinates are defined. This vector is subtracted from the
|
||||
positions.
|
||||
|
||||
.. _asset-mesh-refquat:
|
||||
|
||||
:at:`refquat`: :at-val:`real(4), "1 0 0 0"`
|
||||
Reference orientation relative to which the 3D vertex coordinates and normals are defined. The conjugate of this
|
||||
quaternion is used to rotate the positions and normals. The model compiler normalizes the quaternion automatically.
|
||||
|
||||
.. _mesh-plugin:
|
||||
|
||||
:el-prefix:`mesh/` |-| **plugin** (?)
|
||||
'''''''''''''''''''''''''''''''''''''
|
||||
|
||||
Associate this mesh with an :ref:`engine plugin<exPlugin>`. Either :at:`plugin` or :at:`instance` are required.
|
||||
|
||||
.. _mesh-plugin-plugin:
|
||||
|
||||
:at:`plugin`: :at-val:`string, optional`
|
||||
Plugin identifier, used for implicit plugin instantiation.
|
||||
|
||||
.. _mesh-plugin-instance:
|
||||
|
||||
:at:`instance`: :at-val:`string, optional`
|
||||
Instance name, used for explicit plugin instantiation.
|
||||
|
||||
|
||||
|
||||
.. _asset-hfield:
|
||||
|
||||
:el-prefix:`asset/` |-| **hfield** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This element creates a height field asset, which can then be referenced from geoms with type "hfield". A height field,
|
||||
also known as terrain map, is a 2D matrix of elevation data. The data can be specified in one of three ways:
|
||||
|
||||
#. The elevation data can be loaded from a PNG file. The image is converted internally to gray scale, and the intensity
|
||||
of each pixel is used to define elevation; white is high and black is low.
|
||||
|
||||
#. The elevation data can be loaded from a binary file in the custom format described below. As with all other matrices
|
||||
used in MuJoCo, the data ordering is row-major, like pixels in an image. If the data size is nrow-by-ncol, the file
|
||||
must have 4*(2+nrow*ncol) bytes:
|
||||
|
||||
::
|
||||
|
||||
(int32) nrow
|
||||
(int32) ncol
|
||||
(float32) data[nrow*ncol]
|
||||
|
||||
|
||||
#. The elevation data can be left undefined at compile time. This is done by specifying the attributes nrow and ncol.
|
||||
The compiler allocates space for the height field data in mjModel and sets it to 0. The user can then generate a
|
||||
custom height field at runtime, either programmatically or using sensor data.
|
||||
|
||||
| Regardless of which method is used to specify the elevation data, the compiler always normalizes it to the range [0
|
||||
1]. However if the data is left undefined at compile time and generated later at runtime, it is the user's
|
||||
responsibility to normalize it.
|
||||
| The position and orientation of the height field is determined by the geom that references it. The spatial extent on
|
||||
the other hand is specified by the height field asset itself via the size attribute, and cannot be modified by the
|
||||
referencing geom (the geom size parameters are ignored in this case). The same approach is used for meshes below:
|
||||
positioning is done by the geom while sizing is done by the asset. This is because height fields and meshes involve
|
||||
sizing operations that are not common to other geoms.
|
||||
| For collision detection, a height field is treated as a union of triangular prisms. Collisions between height fields
|
||||
and other geoms (except for planes and other height fields which are not supported) are computed by first selecting
|
||||
the sub-grid of prisms that could collide with the geom based on its bounding box, and then using the general convex
|
||||
collider. The number of possible contacts between a height field and a geom is limited to 50
|
||||
(:ref:`mjMAXCONPAIR <glNumeric>`); any contacts beyond that are discarded. To avoid penetration due to discarded
|
||||
contacts, the spatial features of the height field should be large compared to the geoms it collides with.
|
||||
|
||||
.. _asset-hfield-name:
|
||||
|
||||
:at:`name`: :at-val:`string, optional`
|
||||
Name of the height field, used for referencing. If the name is omitted and a file name is specified, the height field
|
||||
name equals the file name without the path and extension.
|
||||
|
||||
.. _asset-hfield-content_type:
|
||||
|
||||
:at:`content_type`: :at-val:`string, optional`
|
||||
If the file attribute is specified, then this sets the
|
||||
`Media Type <https://www.iana.org/assignments/media-types/media-types.xhtml>`__ (formerly known as MIME types) of the
|
||||
file to be loaded. Any filename extensions will be overloaded. Currently ``image/png`` and
|
||||
``image/vnd.mujoco.hfield`` are supported.
|
||||
|
||||
.. _asset-hfield-file:
|
||||
|
||||
:at:`file`: :at-val:`string, optional`
|
||||
If this attribute is specified, the elevation data is loaded from the given file. If the file extension is ".png",
|
||||
not case-sensitive, the file is treated as a PNG file. Otherwise it is treated as a binary file in the above custom
|
||||
format. The number of rows and columns in the data are determined from the file contents. Loading data from a file
|
||||
and setting nrow or ncol below to non-zero values results is compile error, even if these settings are consistent
|
||||
with the file contents.
|
||||
|
||||
.. _asset-hfield-nrow:
|
||||
|
||||
:at:`nrow`: :at-val:`int, "0"`
|
||||
This attribute and the next are used to allocate a height field in mjModel and leave the elevation data undefined
|
||||
(i.e., set to 0). This attribute specifies the number of rows in the elevation data matrix. The default value of 0
|
||||
means that the data will be loaded from a file, which will be used to infer the size of the matrix.
|
||||
|
||||
.. _asset-hfield-ncol:
|
||||
|
||||
:at:`ncol`: :at-val:`int, "0"`
|
||||
This attribute specifies the number of columns in the elevation data matrix.
|
||||
|
||||
.. _asset-hfield-size:
|
||||
|
||||
:at:`size`: :at-val:`real(4), required`
|
||||
.. figure:: images/XMLreference/peaks.png
|
||||
:width: 350px
|
||||
:align: right
|
||||
|
||||
The four numbers here are (radius_x, radius_y, elevation_z, base_z). The height field is centered at the referencing
|
||||
geom's local frame. Elevation is in the +Z direction. The first two numbers specify the X and Y extent (or "radius")
|
||||
of the rectangle over which the height field is defined. This may seem unnatural for rectangles, but it is natural
|
||||
for spheres and other geom types, and we prefer to use the same convention throughout the model. The third number is
|
||||
the maximum elevation; it scales the elevation data which is normalized to [0-1]. Thus the minimum elevation point is
|
||||
at Z=0 and the maximum elevation point is at Z=elevation_z. The last number is the depth of a box in the -Z direction
|
||||
serving as a "base" for the height field. Without this automatically generated box, the height field would have zero
|
||||
thickness at places there the normalized elevation data is zero. Unlike planes which impose global unilateral
|
||||
constraints, height fields are treated as unions of regular geoms, so there is no notion of being "under" the height
|
||||
field. Instead a geom is either inside or outside the height field - which is why the inside part must have non-zero
|
||||
thickness. The example on the right is the MATLAB "peaks" surface saved in our custom height field format, and loaded
|
||||
as an asset with size = "1 1 1 0.1". The horizontal size of the box is 2, the difference between the maximum and
|
||||
minimum elevation is 1, and the depth of the base added below the minimum elevation point is 0.1.
|
||||
|
||||
|
||||
.. _asset-skin:
|
||||
|
||||
:el-prefix:`asset/` |-| **skin** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. _asset-skin-name:
|
||||
.. _asset-skin-file:
|
||||
.. _asset-skin-vertex:
|
||||
.. _asset-skin-texcoord:
|
||||
.. _asset-skin-face:
|
||||
.. _asset-skin-inflate:
|
||||
.. _asset-skin-material:
|
||||
.. _asset-skin-rgba:
|
||||
.. _asset-skin-group:
|
||||
|
||||
:ref:`Skins<deformable-skin>` have been moved under the new grouping element :ref:`deformable<deformable>`. They can
|
||||
still be specified here but this functionality is now deprecated and will be removed in the future.
|
||||
|
||||
|
||||
|
||||
.. _asset-texture:
|
||||
|
||||
:el-prefix:`asset/` |-| **texture** (*)
|
||||
@@ -1363,328 +1690,6 @@ file.
|
||||
If true, images loaded from file are flipped in the vertical direction. Does not affect procedural textures.
|
||||
|
||||
|
||||
.. _asset-hfield:
|
||||
|
||||
:el-prefix:`asset/` |-| **hfield** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This element creates a height field asset, which can then be referenced from geoms with type "hfield". A height field,
|
||||
also known as terrain map, is a 2D matrix of elevation data. The data can be specified in one of three ways:
|
||||
|
||||
#. The elevation data can be loaded from a PNG file. The image is converted internally to gray scale, and the intensity
|
||||
of each pixel is used to define elevation; white is high and black is low.
|
||||
|
||||
#. The elevation data can be loaded from a binary file in the custom format described below. As with all other matrices
|
||||
used in MuJoCo, the data ordering is row-major, like pixels in an image. If the data size is nrow-by-ncol, the file
|
||||
must have 4*(2+nrow*ncol) bytes:
|
||||
|
||||
::
|
||||
|
||||
(int32) nrow
|
||||
(int32) ncol
|
||||
(float32) data[nrow*ncol]
|
||||
|
||||
|
||||
#. The elevation data can be left undefined at compile time. This is done by specifying the attributes nrow and ncol.
|
||||
The compiler allocates space for the height field data in mjModel and sets it to 0. The user can then generate a
|
||||
custom height field at runtime, either programmatically or using sensor data.
|
||||
|
||||
| Regardless of which method is used to specify the elevation data, the compiler always normalizes it to the range [0
|
||||
1]. However if the data is left undefined at compile time and generated later at runtime, it is the user's
|
||||
responsibility to normalize it.
|
||||
| The position and orientation of the height field is determined by the geom that references it. The spatial extent on
|
||||
the other hand is specified by the height field asset itself via the size attribute, and cannot be modified by the
|
||||
referencing geom (the geom size parameters are ignored in this case). The same approach is used for meshes below:
|
||||
positioning is done by the geom while sizing is done by the asset. This is because height fields and meshes involve
|
||||
sizing operations that are not common to other geoms.
|
||||
| For collision detection, a height field is treated as a union of triangular prisms. Collisions between height fields
|
||||
and other geoms (except for planes and other height fields which are not supported) are computed by first selecting
|
||||
the sub-grid of prisms that could collide with the geom based on its bounding box, and then using the general convex
|
||||
collider. The number of possible contacts between a height field and a geom is limited to 50
|
||||
(:ref:`mjMAXCONPAIR <glNumeric>`); any contacts beyond that are discarded. To avoid penetration due to discarded
|
||||
contacts, the spatial features of the height field should be large compared to the geoms it collides with.
|
||||
|
||||
.. _asset-hfield-name:
|
||||
|
||||
:at:`name`: :at-val:`string, optional`
|
||||
Name of the height field, used for referencing. If the name is omitted and a file name is specified, the height field
|
||||
name equals the file name without the path and extension.
|
||||
|
||||
.. _asset-hfield-content_type:
|
||||
|
||||
:at:`content_type`: :at-val:`string, optional`
|
||||
If the file attribute is specified, then this sets the
|
||||
`Media Type <https://www.iana.org/assignments/media-types/media-types.xhtml>`__ (formerly known as MIME types) of the
|
||||
file to be loaded. Any filename extensions will be overloaded. Currently ``image/png`` and
|
||||
``image/vnd.mujoco.hfield`` are supported.
|
||||
|
||||
.. _asset-hfield-file:
|
||||
|
||||
:at:`file`: :at-val:`string, optional`
|
||||
If this attribute is specified, the elevation data is loaded from the given file. If the file extension is ".png",
|
||||
not case-sensitive, the file is treated as a PNG file. Otherwise it is treated as a binary file in the above custom
|
||||
format. The number of rows and columns in the data are determined from the file contents. Loading data from a file
|
||||
and setting nrow or ncol below to non-zero values results is compile error, even if these settings are consistent
|
||||
with the file contents.
|
||||
|
||||
.. _asset-hfield-nrow:
|
||||
|
||||
:at:`nrow`: :at-val:`int, "0"`
|
||||
This attribute and the next are used to allocate a height field in mjModel and leave the elevation data undefined
|
||||
(i.e., set to 0). This attribute specifies the number of rows in the elevation data matrix. The default value of 0
|
||||
means that the data will be loaded from a file, which will be used to infer the size of the matrix.
|
||||
|
||||
.. _asset-hfield-ncol:
|
||||
|
||||
:at:`ncol`: :at-val:`int, "0"`
|
||||
This attribute specifies the number of columns in the elevation data matrix.
|
||||
|
||||
.. _asset-hfield-size:
|
||||
|
||||
:at:`size`: :at-val:`real(4), required`
|
||||
.. figure:: images/XMLreference/peaks.png
|
||||
:width: 350px
|
||||
:align: right
|
||||
|
||||
The four numbers here are (radius_x, radius_y, elevation_z, base_z). The height field is centered at the referencing
|
||||
geom's local frame. Elevation is in the +Z direction. The first two numbers specify the X and Y extent (or "radius")
|
||||
of the rectangle over which the height field is defined. This may seem unnatural for rectangles, but it is natural
|
||||
for spheres and other geom types, and we prefer to use the same convention throughout the model. The third number is
|
||||
the maximum elevation; it scales the elevation data which is normalized to [0-1]. Thus the minimum elevation point is
|
||||
at Z=0 and the maximum elevation point is at Z=elevation_z. The last number is the depth of a box in the -Z direction
|
||||
serving as a "base" for the height field. Without this automatically generated box, the height field would have zero
|
||||
thickness at places there the normalized elevation data is zero. Unlike planes which impose global unilateral
|
||||
constraints, height fields are treated as unions of regular geoms, so there is no notion of being "under" the height
|
||||
field. Instead a geom is either inside or outside the height field - which is why the inside part must have non-zero
|
||||
thickness. The example on the right is the MATLAB "peaks" surface saved in our custom height field format, and loaded
|
||||
as an asset with size = "1 1 1 0.1". The horizontal size of the box is 2, the difference between the maximum and
|
||||
minimum elevation is 1, and the depth of the base added below the minimum elevation point is 0.1.
|
||||
|
||||
|
||||
.. _asset-mesh:
|
||||
|
||||
:el-prefix:`asset/` |-| **mesh** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This element creates a mesh asset, which can then be referenced from geoms. If the referencing geom type is
|
||||
:at-val:`mesh` the mesh is instantiated in the model, otherwise a geometric primitive is automatically fitted to it; see
|
||||
the :ref:`geom <body-geom>` element below.
|
||||
|
||||
MuJoCo works with triangulated meshes. They can be loaded from binary STL files, OBJ files or MSH files with custom
|
||||
format described below, or vertex and face data specified directly in the XML. Software such as MeshLab can be used to
|
||||
convert from other mesh formats to STL or OBJ. While any collection of triangles can be loaded as a mesh and rendered,
|
||||
collision detection works with the convex hull of the mesh as explained in :ref:`Collision`. See also the convexhull
|
||||
attribute of the :ref:`compiler <compiler>` element which controls the automatic generation of convex hulls. The mesh
|
||||
appearance (including texture mapping) is controlled by the :at:`material` and :at:`rgba` attributes of the referencing
|
||||
geom, similarly to height fields.
|
||||
|
||||
Meshes can have explicit texture coordinates instead of relying on the automated texture
|
||||
mapping mechanism. When provided, these explicit coordinates have priority. Note that texture coordinates can be
|
||||
specified with OBJ files and MSH files, as well as explicitly in the XML with the :at:`texcoord` attribute, but not via
|
||||
STL files. These mechanism cannot be mixed. So if you have an STL mesh, the only way to add texture coordinates to it is
|
||||
to convert to one of the other supported formats.
|
||||
|
||||
MSH file format
|
||||
The binary MSH file starts with 4 integers specifying the number of vertex positions (nvertex), vertex normals
|
||||
(nnormal), vertex texture coordinates (ntexcoord), and vertex indices making up the faces (nface), followed by the
|
||||
numeric data. nvertex must be at least 4. nnormal and ntexcoord can be zero (in which case the corresponding data is
|
||||
not defined) or equal to nvertex. nface can also be zero, in which case faces are constructed automatically from the
|
||||
convex hull of the vertex positions. The file size in bytes must be exactly: 16 + 12*(nvertex + nnormal + nface) +
|
||||
8*ntexcoord. The contents of the file must be as follows:
|
||||
|
||||
.. code:: Text
|
||||
|
||||
(int32) nvertex
|
||||
(int32) nnormal
|
||||
(int32) ntexcoord
|
||||
(int32) nface
|
||||
(float) vertex_positions[3*nvertex]
|
||||
(float) vertex_normals[3*nnormal]
|
||||
(float) vertex_texcoords[2*ntexcoord]
|
||||
(int32) face_vertex_indices[3*nface]
|
||||
|
||||
Poorly designed meshes can display rendering artifacts. In particular, the shadow mapping mechanism relies on having
|
||||
some distance between front and back-facing triangle faces. If the faces are repeated, with opposite normals as
|
||||
determined by the vertex order in each triangle, this causes shadow aliasing. The solution is to remove the repeated
|
||||
faces (which can be done in MeshLab) or use a better designed mesh. Flipped faces are checked by MuJoCo for meshes
|
||||
specified as OBJ or XML and an error message is returned.
|
||||
|
||||
The size of the mesh is determined by the 3D coordinates of the vertex data in the mesh file, multiplied by the
|
||||
components of the :at:`scale` attribute below. Scaling is applied separately for each coordinate axis. Note that
|
||||
negative scaling values can be used to flip the mesh; this is a legitimate operation. The size parameters of the
|
||||
referening geoms are ignored, similarly to height fields. We also provide a mechanism to translate and
|
||||
rotate the 3D coordinates, using the attributes :ref:`refpos<asset-mesh-refpos>` and :ref:`refquat<asset-mesh-refquat>`.
|
||||
|
||||
A mesh can also be defined without faces (a point cloud essentially). In that case
|
||||
the convex hull is constructed automatically, even if the compiler attribute convexhull is false. This makes it easy to
|
||||
construct simple shapes directly in the XML. For example, a pyramid can be created as:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<asset>
|
||||
<mesh name="tetrahedron" vertex="0 0 0 1 0 0 0 1 0 0 0 1"/>
|
||||
</asset>
|
||||
|
||||
Positioning and orienting is complicated by the fact that vertex data are often designed relative to coordinate frames
|
||||
whose origin is not inside the mesh. In contrast, MuJoCo expects the origin of a geom's local frame to coincide with the
|
||||
geometric center of the shape. We resolve this discrepancy by pre-processing the mesh in the compiler, so that it is
|
||||
centered around (0,0,0) and its principal axes of inertia are the coordinate axes. We also save the translation and
|
||||
rotation offsets needed to achieve such alignment in :ref:`mjModel.mesh_pos<mjModel>` and
|
||||
:ref:`mjModel.mesh_quat<mjModel>`. These offsets are then applied to the referencing geom's position and orientation; see
|
||||
also :at:`mesh` attribute of :ref:`geom <body-geom>` below. Fortunately most meshes used in robot models are designed in
|
||||
a coordinate frame centered at the joint. This makes the corresponding MJCF model intuitive: we set the body frame at the
|
||||
joint, so that the joint position is (0,0,0) in the body frame, and simply reference the mesh. Below is an MJCF model
|
||||
fragment of a forearm, containing all the information needed to put the mesh where one would expect it to be. The body
|
||||
position is specified relative to the parent body, namely the upper arm (not shown). It is offset by 35 cm which is the
|
||||
typical length of the human upper arm. If the mesh vertex data were not designed in the above convention, we would have
|
||||
to use the geom position and orientation (or the new refpos, refquat mechanism) to compensate, but in practice this is
|
||||
rarely needed.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<asset>
|
||||
<mesh file="forearm.stl"/>
|
||||
</asset>
|
||||
|
||||
<body pos="0 0 0.35"/>
|
||||
<joint type="hinge" axis="1 0 0"/>
|
||||
<geom type="mesh" mesh="forearm"/>
|
||||
</body>
|
||||
|
||||
The inertial computation mentioned above is part of an algorithm used not only to center and align the mesh, but also to
|
||||
infer the mass and inertia of the body to which it is attached. This is done by computing the centroid of the triangle
|
||||
faces, connecting each face with the centroid to form a triangular pyramid, computing the mass and signed inertia of all
|
||||
pyramids (considered solid or hollow if :at:`shellinertia` is true) and accumulating them. The sign ensures that
|
||||
pyramids on the outside of the surfaces are subtracted, as it can occur with concave geometries. This algorithm can be
|
||||
found in section 1.3.8 of Computational Geometry in C (Second Edition) by Joseph O'Rourke.
|
||||
|
||||
The full list of processing steps applied by the compiler to each mesh is as follows:
|
||||
|
||||
#. For STL meshes, remove any repeated vertices and re-index the faces if needed. If the mesh is not STL, we assume that
|
||||
the desired vertices and faces have already been generated and do not apply removal or re-indexing;
|
||||
#. If vertex normals are not provided, generate normals automatically, using a weighted average of the surrounding face
|
||||
normals. If sharp edges are encountered, the renderer uses the face normals to preserve the visual information about
|
||||
the edge, unless smoothnormal is true. Note that normals cannot be provided with STL meshes;
|
||||
#. Scale, translate and rotate the vertices and normals, re-normalize the normals in case of scaling;
|
||||
#. Construct the convex hull if specified;
|
||||
#. Find the centroid of all triangle faces, and construct the union-of-pyramids representation. Triangles whose area is
|
||||
too small (below the :ref:`mjMINVAL <glNumeric>` value of 1E-14) result in compile error;
|
||||
#. Compute the center of mass and inertia matrix of the union-of-pyramids. Use eigenvalue decomposition to find the
|
||||
principal axes of inertia. Center and align the mesh, saving the translational and rotational offsets for subsequent
|
||||
geom-related computations.
|
||||
|
||||
.. _asset-mesh-name:
|
||||
|
||||
:at:`name`: :at-val:`string, optional`
|
||||
Name of the mesh, used for referencing. If omitted, the mesh name equals the file name without the path and
|
||||
extension.
|
||||
|
||||
.. _asset-mesh-class:
|
||||
|
||||
:at:`class`: :at-val:`string, optional`
|
||||
Defaults class for setting unspecified attributes (only scale in this case).
|
||||
|
||||
.. _asset-mesh-content_type:
|
||||
|
||||
:at:`content_type`: :at-val:`string, optional`
|
||||
If the file attribute is specified, then this sets the
|
||||
`Media Type <https://www.iana.org/assignments/media-types/media-types.xhtml>`_ (formerly known as MIME type) of the
|
||||
file to be loaded. Any filename extensions will be overloaded. Currently ``model/vnd.mujoco.msh``, ``model/obj``,
|
||||
and ``model/stl`` are supported.
|
||||
|
||||
.. _asset-mesh-file:
|
||||
|
||||
:at:`file`: :at-val:`string, optional`
|
||||
The file from which the mesh will be loaded. The path is determined as described in the meshdir attribute of
|
||||
:ref:`compiler <compiler>`. The file extension must be "stl", "msh", or "obj" (not case sensitive) specifying the
|
||||
file type. If the file name is omitted, the vertex attribute becomes required.
|
||||
|
||||
.. _asset-mesh-scale:
|
||||
|
||||
:at:`scale`: :at-val:`real(3), "1 1 1"`
|
||||
This attribute specifies the scaling that will be applied to the vertex data along each coordinate axis. Negative
|
||||
values are allowed, resulting in flipping the mesh along the corresponding axis.
|
||||
|
||||
.. _asset-mesh-smoothnormal:
|
||||
|
||||
:at:`smoothnormal`: :at-val:`[false, true], "false"`
|
||||
Controls the automatic generation of vertex normals when normals are not given explicitly. If true, smooth normals
|
||||
are generated by averaging the face normals at each vertex, with weight proportional to the face area. If false,
|
||||
faces at large angles relative to the average normal are excluded from the average. In this way, sharp edges (as in
|
||||
cube edges) are not smoothed.
|
||||
|
||||
.. _asset-mesh-vertex:
|
||||
|
||||
:at:`vertex`: :at-val:`real(3*nvert), optional`
|
||||
Vertex 3D position data. You can specify position data in the XML using this attribute, or using a binary file, but
|
||||
not both.
|
||||
|
||||
.. _asset-mesh-normal:
|
||||
|
||||
:at:`normal`: :at-val:`real(3*nvert), optional`
|
||||
Vertex 3D normal data. If specified, the number of normals must equal the number of vertices. The model compiler
|
||||
normalizes the normals automatically.
|
||||
|
||||
.. _asset-mesh-texcoord:
|
||||
|
||||
:at:`texcoord`: :at-val:`real(2*nvert), optional`
|
||||
Vertex 2D texture coordinates, which are numbers between 0 and 1. If specified, the number of texture coordinate
|
||||
pairs must equal the number of vertices.
|
||||
|
||||
.. _asset-mesh-face:
|
||||
|
||||
:at:`face`: :at-val:`int(3*nface), optional`
|
||||
Faces of the mesh. Each face is a sequence of 3 vertex indices, in counter-clockwise order. The indices must be
|
||||
integers between 0 and nvert-1.
|
||||
|
||||
.. _asset-mesh-refpos:
|
||||
|
||||
:at:`refpos`: :at-val:`real(3), "0 0 0"`
|
||||
Reference position relative to which the 3D vertex coordinates are defined. This vector is subtracted from the
|
||||
positions.
|
||||
|
||||
.. _asset-mesh-refquat:
|
||||
|
||||
:at:`refquat`: :at-val:`real(4), "1 0 0 0"`
|
||||
Reference orientation relative to which the 3D vertex coordinates and normals are defined. The conjugate of this
|
||||
quaternion is used to rotate the positions and normals. The model compiler normalizes the quaternion automatically.
|
||||
|
||||
.. _mesh-plugin:
|
||||
|
||||
:el-prefix:`mesh/` |-| **plugin** (?)
|
||||
'''''''''''''''''''''''''''''''''''''
|
||||
|
||||
Associate this mesh with an :ref:`engine plugin<exPlugin>`. Either :at:`plugin` or :at:`instance` are required.
|
||||
|
||||
.. _mesh-plugin-plugin:
|
||||
|
||||
:at:`plugin`: :at-val:`string, optional`
|
||||
Plugin identifier, used for implicit plugin instantiation.
|
||||
|
||||
.. _mesh-plugin-instance:
|
||||
|
||||
:at:`instance`: :at-val:`string, optional`
|
||||
Instance name, used for explicit plugin instantiation.
|
||||
|
||||
|
||||
.. _asset-skin:
|
||||
|
||||
:el-prefix:`asset/` |-| **skin** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. _asset-skin-name:
|
||||
.. _asset-skin-file:
|
||||
.. _asset-skin-vertex:
|
||||
.. _asset-skin-texcoord:
|
||||
.. _asset-skin-face:
|
||||
.. _asset-skin-inflate:
|
||||
.. _asset-skin-material:
|
||||
.. _asset-skin-rgba:
|
||||
.. _asset-skin-group:
|
||||
|
||||
:ref:`Skins<deformable-skin>` have been moved under the new grouping element :ref:`deformable<deformable>`. They can
|
||||
still be specified here but this functionality is now deprecated and will be removed in the future.
|
||||
|
||||
|
||||
.. _asset-material:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user