Create mjpDecoder, mj_parse, and mju_decodeResource

- plugin system similar to mjpResourceProvider, but instead of loading a resource it converts an existing mjResource into an mjSpec.
  - The returned spec is then composed into the referencing spec.
  - This enables different file types to generate arbitrary specs, and allows us to separate format parsing from compilation code.

Follow up CLs will move some of the logic in src/engine for PNG, USD, KTX, OBJ loading into decoders.

The mj_parse function MjSpec from a given file, it's a more generic version of mj_parseXML.

In it's implementation, mj_parse as opposed to mj_parseXML will look for any registered decoder and
not assume we are striclty dealing with MJCF.

PiperOrigin-RevId: 826149497
Change-Id: I0ece26904280cb94bd5ded6dd5a565c539d60254
This commit is contained in:
Sam Haves
2025-10-30 12:53:40 -07:00
committed by Copybara-Service
parent f2badc05ac
commit 57f7145806
16 changed files with 2063 additions and 1555 deletions
+17
View File
@@ -24,7 +24,9 @@
#include <cstring>
#include <ctime>
#include <string>
#include <string_view>
#include <vector>
#include <mujoco/mujoco.h>
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
#include <unistd.h>
@@ -262,3 +264,18 @@ int mju_isModifiedResource(const mjResource* resource, const char* timestamp) {
// fallback to OS filesystem
return FileModified(resource, timestamp);
}
mjSpec* mju_decodeResource(mjResource* resource, const char* content_type) {
const mjpDecoder* decoder = nullptr;
if (content_type) {
decoder = mjp_findDecoder(resource, content_type);
} else {
decoder = mjp_findDecoder(resource, mjuu_extToContentType(resource->name).c_str());
}
if (!decoder) {
mju_error("Could not find decoder for resource '%s'", resource->name);
}
return decoder->decode(resource);
}