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:
committed by
Copybara-Service
parent
f2badc05ac
commit
57f7145806
@@ -31,6 +31,7 @@
|
||||
#include "user/user_cache.h"
|
||||
#include "user/user_model.h"
|
||||
#include "user/user_objects.h"
|
||||
#include "user/user_resource.h"
|
||||
#include "user/user_util.h"
|
||||
|
||||
namespace {
|
||||
@@ -63,7 +64,24 @@ mjSpec* mj_copySpec(const mjSpec* s) {
|
||||
return &modelC->spec;
|
||||
}
|
||||
|
||||
// parse file into spec
|
||||
mjSpec* mj_parse(const char* filename, const char* content_type,
|
||||
const mjVFS* vfs, char* error, int error_sz) {
|
||||
// early exit for existing XML workflow
|
||||
auto filepath = mujoco::user::FilePath(filename);
|
||||
if (filepath.Ext() == ".xml" || (content_type && std::strcmp(content_type, "text/xml") == 0)) {
|
||||
return mj_parseXML(filename, vfs, error, error_sz);
|
||||
}
|
||||
|
||||
mjResource* resource = mju_openResource("", filename, vfs, error, error_sz);
|
||||
if (!resource) {
|
||||
mju_error("Could not load resource %s", filename);
|
||||
}
|
||||
|
||||
mjSpec* spec = mju_decodeResource(resource, content_type);
|
||||
mju_closeResource(resource);
|
||||
return spec;
|
||||
}
|
||||
|
||||
// compile model
|
||||
mjModel* mj_compile(mjSpec* s, const mjVFS* vfs) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@ MJAPI void mju_getResourceDir(mjResource* resource, const char** dir, int* ndir)
|
||||
// return < 0 if the resource is older than the given timestamp
|
||||
MJAPI int mju_isModifiedResource(const mjResource* resource, const char* timestamp);
|
||||
|
||||
// given a resource, find its decoder and return the decoded spec
|
||||
// the caller takes ownership of the spec and is responsible for cleaning it up
|
||||
MJAPI mjSpec* mju_decodeResource(mjResource* resource, const char* content_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user