Add a warning in user_model.cc if a flex is not rigid and has no edge equality constraints or passive forces (edge stiffness, edge damping, or vertex damping). Such flexes would not affect the simulation. A test case is added to verify the warning.
PiperOrigin-RevId: 889215981
Change-Id: I481128e1456921b632719547c676d201fdfbe931
Add a new mjpEncoder plugin type mirroring the existing mjpDecoder pattern.
Encoders serialize an mjSpec + mjModel to an mjResource for a given format.
New API functions:
- mjp_registerEncoder: globally register an encoder
- mjp_defaultEncoder: zero-initialize an encoder struct
- mjp_findEncoder: look up an encoder by filename extension or content type
The mjfEncode callback takes (mjSpec*, mjModel*, mjVFS*, mjResource*) and
returns 0 on success. Writing to mjResource keeps symmetry with the decoder
reading from mjResource and leaves the door open for writable resource providers.
PiperOrigin-RevId: 889187898
Change-Id: I180771b2255b91dea188ac5e2cdc3a8f0fb85364
The `vertcollide` attribute in flex and flexcomp contact specifications has been removed since the next mjWarp release will support flex collisions. This attribute was previously used to enable vertex-based collisions by adding sphere geoms at flex vertices. The functionality associated with this attribute has been deprecated and removed from the XML parser, documentation, and internal data structures. Affected example XML files have also been updated.
PiperOrigin-RevId: 885595503
Change-Id: I6a78975f1bc540c09ea8b5306ff3be0962b7ab24
Repro instructions (note compiler cache and threading must be enabled):
Assume we have a cube.stl mesh containing face data and the following XML:
<mujoco>
<asset>
<mesh name="cube" file="cube.stl"/>
<mesh name="unused" file="cube.stl"/>
</asset>
<worldbody>
<geom type="mesh" mesh="cube"/>
</worldbody>
</mujoco>
Suppose Thread A processes "cube" and Thread B processes "unused". Thread A will generate the mesh hull and will generate polygon data from faces from qhull. Thread B will NOT generate the mesh hull and will generate polygon data from faces coming from mesh file. Thread A beats Thread B to caching the mesh.
When "unused" is later pulled from the cache it gets the polygon data that was generated from "cube" which is not the same that was generated from "unused".
PiperOrigin-RevId: 878336494
Change-Id: I275b09b44490c54b2a5f09d91d0cc047026090f2
The `mjCOctree::ComputeSdfCoeffs` function has been replaced by `mjCOctree::ComputeSdf`. The new implementation removes the dependency on the `triangle_mesh_distance` library. Instead, it uses a provided `mjCBoundingVolumeHierarchy` to perform closest point queries on the mesh. The signed distance is computed by finding the closest triangle face via the BVH and determining the sign based on the dot product of the vector from the closest point on the triangle to the octree vertex and the triangle's normal.
Optional Laplacian smoothing has been added to the SDF coefficients. This helps smooth out potential discontinuities at octree level boundaries.
PiperOrigin-RevId: 875093374
Change-Id: I6fa53243a2dda107ccf255bc6b876ca5a4554d4f
This change introduces methods to cache and load the computed stiffness matrix and nodal masses for flex elements. The cache key is generated based on material properties (Young's modulus, Poisson's ratio), interpolation order, and the bounding box of the flex. This avoids redundant expensive computations when compiling models with identical flex definitions.
PiperOrigin-RevId: 874689771
Change-Id: I6d1e299baf294a984b507e2a2602b2c068610536
The logic for computing Signed Distance Function (SDF) coefficients using TriangleMeshDistance is moved from `mjCPlugin::Make` in `user_mesh.cc` to a new method `mjCOctree::ComputeSdfCoeffs` in `user_objects.cc`. This encapsulates the SDF computation within the octree class.
PiperOrigin-RevId: 874572414
Change-Id: Ia2365c9c4527a252ff1d1bb43fe2c2593761e471
Root cause: resources and default mount stored pointers tied to the public mjVFS object address. If mjVFS was moved after initialization, resource close/read paths could dereference stale pointers and crash.\n\nThis change stores a stable internal mjVFS handle inside VFS and points resources/default mount to that stable handle. It also tracks the current public owner pointer and rebinds it in Upcast so lifecycle operations (including self-destruct cleanup) target the current mjVFS address after moves.\n\nAdds regression test UserVfsTest.MoveVfsAfterOpenResource, which opens a resource, moves mjVFS, then reads/closes/deletes successfully.
- Guard #define stat _stat with !defined(__MINGW32__) to avoid conflicts with MinGW's own POSIX-compliant stat implementation
- Replace _MSC_VER check with defined(_WIN32) for localtime_s to allow all Windows compilers including MinGW to use the secure function
Fixes#3038, #3037
FuseStatic deletes static (joint-less) bodies and reassigns their
children to the parent body. Geoms and sites were reassigned, but
cameras and lights were not, leaving dangling body pointers that
crash in mjCCamera::Compile() / mjCLight::Compile().
Add camera and light reassignment in FuseStatic and FuseReindex.
Fix a crash and dimension mismatch issue in user_flexcomp when dealing with interpolated="true" meshes that contain unused vertices. Previously, vertbody would correspond only to used vertices while vert included all vertices, leading to assertions or out-of-bounds access. Also enable node pinning for interpolated meshes.
PiperOrigin-RevId: 865881995
Change-Id: Id150f00f22b5f48896ffbffddf03c57b252de8c0
Otherwise, if you try to open a random file in studio, it will crash.
PiperOrigin-RevId: 865372002
Change-Id: I96d3121b6de792daaff53155ea2436ac3f6668db
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.
This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.
PiperOrigin-RevId: 863248779
Change-Id: I8bcbd5445814ba1e72c6d7b80ad6a054f5f1df57
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.
This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.
PiperOrigin-RevId: 861550939
Change-Id: I070eb4bcc2982466c8f368f7918005538baa5185