Add mjmTexture to C API.
PiperOrigin-RevId: 606543622 Change-Id: I2db743c1c40116f0503329fb1d004d9b041e83e7
This commit is contained in:
committed by
Copybara-Service
parent
47bb4a828e
commit
06505f49f9
@@ -137,6 +137,15 @@ mjmFrame* mjm_addFrame(mjmBody* bodyspec, mjmFrame* parentframe) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// add texture to model
|
||||||
|
mjmTexture* mjm_addTexture(void* model) {
|
||||||
|
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||||
|
mjCTexture* texture = modelC->AddTexture();
|
||||||
|
return &texture->spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// add material to model
|
// add material to model
|
||||||
mjmMaterial* mjm_addMaterial(void* model, void* defspec) {
|
mjmMaterial* mjm_addMaterial(void* model, void* defspec) {
|
||||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||||
@@ -312,6 +321,19 @@ void mjm_setString(mjString dest, const char* text) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set specific entry in destination string vector.
|
||||||
|
mjtByte mjm_setInStringVec(mjStringVec dest, int i, const char* text) {
|
||||||
|
std::vector<std::string>* v = reinterpret_cast<std::vector<std::string>*>(dest);
|
||||||
|
if (v->size() <= i) {
|
||||||
|
mju_error("Requested index in mjm_setInStringVec is out of bounds");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
v->at(i) = std::string(text);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// split text and copy into string array
|
// split text and copy into string array
|
||||||
void mjm_setStringVec(mjStringVec dest, const char* text) {
|
void mjm_setStringVec(mjStringVec dest, const char* text) {
|
||||||
std::vector<std::string>* v = reinterpret_cast<std::vector<std::string>*>(dest);
|
std::vector<std::string>* v = reinterpret_cast<std::vector<std::string>*>(dest);
|
||||||
|
|||||||
+62
-3
@@ -38,12 +38,28 @@ typedef struct _mjFloatVec* mjFloatVec;
|
|||||||
|
|
||||||
//---------------------------------- enum types (mjt) ----------------------------------------------
|
//---------------------------------- enum types (mjt) ----------------------------------------------
|
||||||
|
|
||||||
typedef enum _mjtGeomInertia { // type of inertia inference
|
typedef enum _mjtGeomInertia { // type of inertia inference
|
||||||
mjINERTIA_VOLUME, // mass distributed in the volume
|
mjINERTIA_VOLUME, // mass distributed in the volume
|
||||||
mjINERTIA_SHELL, // mass distributed on the surface
|
mjINERTIA_SHELL, // mass distributed on the surface
|
||||||
} mjtGeomInertia;
|
} mjtGeomInertia;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum _mjtBuiltin { // type of built-in procedural texture
|
||||||
|
mjBUILTIN_NONE = 0, // no built-in texture
|
||||||
|
mjBUILTIN_GRADIENT, // gradient: rgb1->rgb2
|
||||||
|
mjBUILTIN_CHECKER, // checker pattern: rgb1, rgb2
|
||||||
|
mjBUILTIN_FLAT // 2d: rgb1; cube: rgb1-up, rgb2-side, rgb3-down
|
||||||
|
} mjtBuiltin;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum _mjtMark { // mark type for procedural textures
|
||||||
|
mjMARK_NONE = 0, // no mark
|
||||||
|
mjMARK_EDGE, // edges
|
||||||
|
mjMARK_CROSS, // cross
|
||||||
|
mjMARK_RANDOM // random dots
|
||||||
|
} mjtMark;
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- attribute structs (mjm) ---------------------------------------
|
//---------------------------------- attribute structs (mjm) ---------------------------------------
|
||||||
|
|
||||||
typedef struct _mjmOrientation { // alternative orientation specifiers
|
typedef struct _mjmOrientation { // alternative orientation specifiers
|
||||||
@@ -309,6 +325,40 @@ typedef struct _mjmFlex {
|
|||||||
} mjmFlex;
|
} mjmFlex;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _mjmTexture { // texture specification
|
||||||
|
mjElement element; // internal, do not modify
|
||||||
|
mjString name; // name
|
||||||
|
mjString classname; // class name
|
||||||
|
mjtTexture type; // texture type
|
||||||
|
|
||||||
|
// method 1: builtin
|
||||||
|
int builtin; // builtin type (mjtBuiltin)
|
||||||
|
int mark; // mark type (mjtMark)
|
||||||
|
double rgb1[3]; // first color for builtin
|
||||||
|
double rgb2[3]; // second color for builtin
|
||||||
|
double markrgb[3]; // mark color
|
||||||
|
double random; // probability of random dots
|
||||||
|
int height; // height in pixels (square for cube and skybox)
|
||||||
|
int width; // width in pixels
|
||||||
|
|
||||||
|
// method 2: single file
|
||||||
|
mjString content_type; // content type of file
|
||||||
|
mjString file; // png file to load; use for all sides of cube
|
||||||
|
int gridsize[2]; // size of grid for composite file; (1,1)-repeat
|
||||||
|
char gridlayout[13]; // row-major: L,R,F,B,U,D for faces; . for unused
|
||||||
|
|
||||||
|
// method 3: separate files
|
||||||
|
mjStringVec cubefiles; // different file for each side of the cube
|
||||||
|
|
||||||
|
// flip options
|
||||||
|
mjtByte hflip; // horizontal flip
|
||||||
|
mjtByte vflip; // vertical flip
|
||||||
|
|
||||||
|
// other
|
||||||
|
mjString info; // message appended to compiler errors
|
||||||
|
} mjmTexture;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _mjmMaterial { // material specification
|
typedef struct _mjmMaterial { // material specification
|
||||||
mjElement element; // internal, do not modify
|
mjElement element; // internal, do not modify
|
||||||
mjString name; // name
|
mjString name; // name
|
||||||
@@ -508,6 +558,9 @@ MJAPI mjmFrame* mjm_addFrame(mjmBody* body, mjmFrame* parentframe);
|
|||||||
// Add flex to model.
|
// Add flex to model.
|
||||||
MJAPI mjmFlex* mjm_addFlex(void* model);
|
MJAPI mjmFlex* mjm_addFlex(void* model);
|
||||||
|
|
||||||
|
// Add texture to model.
|
||||||
|
MJAPI mjmTexture* mjm_addTexture(void* model);
|
||||||
|
|
||||||
// Add material to model.
|
// Add material to model.
|
||||||
MJAPI mjmMaterial* mjm_addMaterial(void* model, void* defspec);
|
MJAPI mjmMaterial* mjm_addMaterial(void* model, void* defspec);
|
||||||
|
|
||||||
@@ -562,6 +615,9 @@ MJAPI void mjm_setString(mjString dest, const char* text);
|
|||||||
// Split text to entries and copy to destination string vector.
|
// Split text to entries and copy to destination string vector.
|
||||||
MJAPI void mjm_setStringVec(mjStringVec dest, const char* text);
|
MJAPI void mjm_setStringVec(mjStringVec dest, const char* text);
|
||||||
|
|
||||||
|
// Set specific entry in destination string vector.
|
||||||
|
MJAPI mjtByte mjm_setInStringVec(mjStringVec dest, int i, const char* text);
|
||||||
|
|
||||||
// Add text entry to destination string vector.
|
// Add text entry to destination string vector.
|
||||||
MJAPI void mjm_addToStringVec(mjStringVec dest, const char* text);
|
MJAPI void mjm_addToStringVec(mjStringVec dest, const char* text);
|
||||||
|
|
||||||
@@ -616,6 +672,9 @@ MJAPI void mjm_defaultLight(mjmLight& light);
|
|||||||
// Default flex attributes.
|
// Default flex attributes.
|
||||||
MJAPI void mjm_defaultFlex(mjmFlex& flex);
|
MJAPI void mjm_defaultFlex(mjmFlex& flex);
|
||||||
|
|
||||||
|
// Default texture attributes.
|
||||||
|
MJAPI void mjm_defaultTexture(mjmTexture& texture);
|
||||||
|
|
||||||
// Default material attributes.
|
// Default material attributes.
|
||||||
MJAPI void mjm_defaultMaterial(mjmMaterial& material);
|
MJAPI void mjm_defaultMaterial(mjmMaterial& material);
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
#include "cc/array_safety.h"
|
||||||
#include "user/user_api.h"
|
#include "user/user_api.h"
|
||||||
#include "user/user_util.h"
|
#include "user/user_util.h"
|
||||||
|
|
||||||
@@ -191,6 +192,20 @@ void mjm_defaultFlex(mjmFlex& flex) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// default texture attributes
|
||||||
|
void mjm_defaultTexture(mjmTexture& texture) {
|
||||||
|
memset(&texture, 0, sizeof(mjmTexture));
|
||||||
|
texture.type = mjTEXTURE_CUBE;
|
||||||
|
mjuu_setvec(texture.rgb1, 0.8, 0.8, 0.8);
|
||||||
|
mjuu_setvec(texture.rgb2, 0.5, 0.5, 0.5);
|
||||||
|
mjuu_setvec(texture.markrgb, 0, 0, 0);
|
||||||
|
texture.random = 0.01;
|
||||||
|
texture.gridsize[0] = texture.gridsize[1] = 1;
|
||||||
|
mujoco::util::strcpy_arr(texture.gridlayout, "............");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// default material attributes
|
// default material attributes
|
||||||
void mjm_defaultMaterial(mjmMaterial& material) {
|
void mjm_defaultMaterial(mjmMaterial& material) {
|
||||||
memset(&material, 0, sizeof(mjmMaterial));
|
memset(&material, 0, sizeof(mjmMaterial));
|
||||||
|
|||||||
@@ -904,6 +904,7 @@ void mjCModel::SetDefaultNames(std::vector<T*>& assets) {
|
|||||||
|
|
||||||
// use filename if name is missing
|
// use filename if name is missing
|
||||||
for (int i=0; i<assets.size(); i++) {
|
for (int i=0; i<assets.size(); i++) {
|
||||||
|
assets[i]->CopyFromSpec();
|
||||||
if (assets[i]->name.empty()) {
|
if (assets[i]->name.empty()) {
|
||||||
stripped = mjuu_strippath(assets[i]->get_file());
|
stripped = mjuu_strippath(assets[i]->get_file());
|
||||||
assets[i]->name = mjuu_stripext(stripped);
|
assets[i]->name = mjuu_stripext(stripped);
|
||||||
|
|||||||
+52
-35
@@ -2579,35 +2579,50 @@ void mjCHField::Compile(const mjVFS* vfs) {
|
|||||||
|
|
||||||
// initialize defaults
|
// initialize defaults
|
||||||
mjCTexture::mjCTexture(mjCModel* _model) {
|
mjCTexture::mjCTexture(mjCModel* _model) {
|
||||||
|
mjm_defaultTexture(spec);
|
||||||
|
|
||||||
// set model pointer
|
// set model pointer
|
||||||
model = _model;
|
model = _model;
|
||||||
|
|
||||||
// clear user settings: builtin
|
|
||||||
type = mjTEXTURE_CUBE;
|
|
||||||
builtin = mjBUILTIN_NONE;
|
|
||||||
mark = mjMARK_NONE;
|
|
||||||
mjuu_setvec(rgb1, 0.8, 0.8, 0.8);
|
|
||||||
mjuu_setvec(rgb2, 0.5, 0.5, 0.5);
|
|
||||||
mjuu_setvec(markrgb, 0, 0, 0);
|
|
||||||
random = 0.01;
|
|
||||||
height = width = 0;
|
|
||||||
|
|
||||||
// clear user settings: single file
|
// clear user settings: single file
|
||||||
file.clear();
|
spec_file_.clear();
|
||||||
gridsize[0] = gridsize[1] = 1;
|
spec_content_type_.clear();
|
||||||
mju::strcpy_arr(gridlayout, "............");
|
|
||||||
|
|
||||||
// clear user settings: separate file
|
// clear user settings: separate file
|
||||||
for (int i=0; i<6; i++) {
|
spec_cubefiles_.assign(6, "");
|
||||||
cubefiles[i].clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear flip options
|
|
||||||
hflip = false;
|
|
||||||
vflip = false;
|
|
||||||
|
|
||||||
// clear internal variables
|
// clear internal variables
|
||||||
rgb = 0;
|
rgb = 0;
|
||||||
|
|
||||||
|
// point to local (needs to be after defaults)
|
||||||
|
PointToLocal();
|
||||||
|
|
||||||
|
// in case this camera is not compiled
|
||||||
|
CopyFromSpec();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void mjCTexture::PointToLocal() {
|
||||||
|
spec.element = (mjElement)this;
|
||||||
|
spec.name = (mjString)&name;
|
||||||
|
spec.classname = (mjString)&classname;
|
||||||
|
spec.file = (mjString)&spec_file_;
|
||||||
|
spec.content_type = (mjString)&spec_content_type_;
|
||||||
|
spec.cubefiles = (mjStringVec)&spec_cubefiles_;
|
||||||
|
spec.info = (mjString)&info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void mjCTexture::CopyFromSpec() {
|
||||||
|
*static_cast<mjmTexture*>(this) = spec;
|
||||||
|
file_ = spec_file_;
|
||||||
|
content_type_ = spec_content_type_;
|
||||||
|
cubefiles_ = spec_cubefiles_;
|
||||||
|
file = (mjString)&file_;
|
||||||
|
content_type = (mjString)&content_type_;
|
||||||
|
cubefiles = (mjStringVec)&cubefiles_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2930,7 +2945,7 @@ void mjCTexture::LoadCustom(mjResource* resource,
|
|||||||
void mjCTexture::LoadFlip(string filename, const mjVFS* vfs,
|
void mjCTexture::LoadFlip(string filename, const mjVFS* vfs,
|
||||||
std::vector<unsigned char>& image,
|
std::vector<unsigned char>& image,
|
||||||
unsigned int& w, unsigned int& h) {
|
unsigned int& w, unsigned int& h) {
|
||||||
std::string asset_type = GetAssetContentType(filename, content_type);
|
std::string asset_type = GetAssetContentType(filename, content_type_);
|
||||||
|
|
||||||
// fallback to custom
|
// fallback to custom
|
||||||
if (asset_type.empty()) {
|
if (asset_type.empty()) {
|
||||||
@@ -3017,7 +3032,7 @@ void mjCTexture::Load2D(string filename, const mjVFS* vfs) {
|
|||||||
rgb = (mjtByte*) mju_malloc(3*width*height);
|
rgb = (mjtByte*) mju_malloc(3*width*height);
|
||||||
if (!rgb) {
|
if (!rgb) {
|
||||||
throw mjCError(this, "Could not allocate memory for texture '%s' (id %d)",
|
throw mjCError(this, "Could not allocate memory for texture '%s' (id %d)",
|
||||||
(const char*)file.c_str(), id);
|
(const char*)file_.c_str(), id);
|
||||||
}
|
}
|
||||||
memcpy(rgb, image.data(), 3*width*height);
|
memcpy(rgb, image.data(), 3*width*height);
|
||||||
image.clear();
|
image.clear();
|
||||||
@@ -3043,7 +3058,7 @@ void mjCTexture::LoadCubeSingle(string filename, const mjVFS* vfs) {
|
|||||||
if (w/gridsize[1]!=h/gridsize[0] || (w%gridsize[1]) || (h%gridsize[0])) {
|
if (w/gridsize[1]!=h/gridsize[0] || (w%gridsize[1]) || (h%gridsize[0])) {
|
||||||
throw mjCError(this,
|
throw mjCError(this,
|
||||||
"PNG size must be integer multiple of gridsize in texture '%s' (id %d)",
|
"PNG size must be integer multiple of gridsize in texture '%s' (id %d)",
|
||||||
(const char*)file.c_str(), id);
|
(const char*)file_.c_str(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign size: repeated or full
|
// assign size: repeated or full
|
||||||
@@ -3059,7 +3074,7 @@ void mjCTexture::LoadCubeSingle(string filename, const mjVFS* vfs) {
|
|||||||
if (!rgb) {
|
if (!rgb) {
|
||||||
throw mjCError(this,
|
throw mjCError(this,
|
||||||
"Could not allocate memory for texture '%s' (id %d)",
|
"Could not allocate memory for texture '%s' (id %d)",
|
||||||
(const char*)file.c_str(), id);
|
(const char*)file_.c_str(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy: repeated
|
// copy: repeated
|
||||||
@@ -3090,7 +3105,7 @@ void mjCTexture::LoadCubeSingle(string filename, const mjVFS* vfs) {
|
|||||||
i = 5;
|
i = 5;
|
||||||
} else if (gridlayout[k]!='.')
|
} else if (gridlayout[k]!='.')
|
||||||
throw mjCError(this, "gridlayout symbol is not among '.RLUDFB' in texture '%s' (id %d)",
|
throw mjCError(this, "gridlayout symbol is not among '.RLUDFB' in texture '%s' (id %d)",
|
||||||
(const char*)file.c_str(), id);
|
(const char*)file_.c_str(), id);
|
||||||
|
|
||||||
// load if specified
|
// load if specified
|
||||||
if (i>=0) {
|
if (i>=0) {
|
||||||
@@ -3132,14 +3147,14 @@ void mjCTexture::LoadCubeSeparate(const mjVFS* vfs) {
|
|||||||
|
|
||||||
// process nonempty files
|
// process nonempty files
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
if (!cubefiles[i].empty()) {
|
if (!cubefiles_[i].empty()) {
|
||||||
// remove path from file if necessary
|
// remove path from file if necessary
|
||||||
if (model->strippath) {
|
if (model->strippath) {
|
||||||
cubefiles[i] = mjuu_strippath(cubefiles[i]);
|
cubefiles_[i] = mjuu_strippath(cubefiles_[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make filename
|
// make filename
|
||||||
string filename = mjuu_makefullname(model->modelfiledir, model->texturedir, cubefiles[i]);
|
string filename = mjuu_makefullname(model->modelfiledir, model->texturedir, cubefiles_[i]);
|
||||||
|
|
||||||
// load PNG or custom
|
// load PNG or custom
|
||||||
unsigned int w, h;
|
unsigned int w, h;
|
||||||
@@ -3150,7 +3165,7 @@ void mjCTexture::LoadCubeSeparate(const mjVFS* vfs) {
|
|||||||
if (w!=h) {
|
if (w!=h) {
|
||||||
throw mjCError(this,
|
throw mjCError(this,
|
||||||
"Non-square PNG file '%s' in cube or skybox id %d",
|
"Non-square PNG file '%s' in cube or skybox id %d",
|
||||||
(const char*)cubefiles[i].c_str(), id);
|
(const char*)cubefiles_[i].c_str(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// first file: set size and allocate data
|
// first file: set size and allocate data
|
||||||
@@ -3169,7 +3184,7 @@ void mjCTexture::LoadCubeSeparate(const mjVFS* vfs) {
|
|||||||
else if (width!=w) {
|
else if (width!=w) {
|
||||||
throw mjCError(this,
|
throw mjCError(this,
|
||||||
"PNG file '%s' has incompatible size in texture id %d",
|
"PNG file '%s' has incompatible size in texture id %d",
|
||||||
(const char*)cubefiles[i].c_str(), id);
|
(const char*)cubefiles_[i].c_str(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy data
|
// copy data
|
||||||
@@ -3199,6 +3214,8 @@ void mjCTexture::LoadCubeSeparate(const mjVFS* vfs) {
|
|||||||
|
|
||||||
// compiler
|
// compiler
|
||||||
void mjCTexture::Compile(const mjVFS* vfs) {
|
void mjCTexture::Compile(const mjVFS* vfs) {
|
||||||
|
CopyFromSpec();
|
||||||
|
|
||||||
// builtin
|
// builtin
|
||||||
if (builtin!=mjBUILTIN_NONE) {
|
if (builtin!=mjBUILTIN_NONE) {
|
||||||
// check size
|
// check size
|
||||||
@@ -3230,14 +3247,14 @@ void mjCTexture::Compile(const mjVFS* vfs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// single file
|
// single file
|
||||||
else if (!file.empty()) {
|
else if (!file_.empty()) {
|
||||||
// remove path from file if necessary
|
// remove path from file if necessary
|
||||||
if (model->strippath) {
|
if (model->strippath) {
|
||||||
file = mjuu_strippath(file);
|
file_ = mjuu_strippath(file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make filename
|
// make filename
|
||||||
string filename = mjuu_makefullname(model->modelfiledir, model->texturedir, file);
|
string filename = mjuu_makefullname(model->modelfiledir, model->texturedir, file_);
|
||||||
|
|
||||||
// dispatch
|
// dispatch
|
||||||
if (type==mjTEXTURE_2D) {
|
if (type==mjTEXTURE_2D) {
|
||||||
@@ -3259,14 +3276,14 @@ void mjCTexture::Compile(const mjVFS* vfs) {
|
|||||||
// at least one cubefile must be defined
|
// at least one cubefile must be defined
|
||||||
bool defined = false;
|
bool defined = false;
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
if (!cubefiles[i].empty()) {
|
if (!cubefiles_[i].empty()) {
|
||||||
defined = true;
|
defined = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!defined) {
|
if (!defined) {
|
||||||
throw mjCError(this,
|
throw mjCError(this,
|
||||||
"No cubefiles defined in cube or skybox texture '%s' (id %d)",
|
"No cubefiles_ defined in cube or skybox texture '%s' (id %d)",
|
||||||
(const char*)name.c_str(), id);
|
(const char*)name.c_str(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-43
@@ -68,24 +68,6 @@ class mjXURDF; // defined in xml_urdf
|
|||||||
const int mjGEOMINFO[mjNGEOMTYPES] = {3, 0, 1, 2, 3, 2, 3, 0};
|
const int mjGEOMINFO[mjNGEOMTYPES] = {3, 0, 1, 2, 3, 2, 3, 0};
|
||||||
|
|
||||||
|
|
||||||
// builtin type for procedural textures
|
|
||||||
typedef enum _mjtBuiltin {
|
|
||||||
mjBUILTIN_NONE = 0, // no builtin
|
|
||||||
mjBUILTIN_GRADIENT, // circular gradient: rgb1->rgb2->rgb3
|
|
||||||
mjBUILTIN_CHECKER, // checker pattern: rgb1, rgb2
|
|
||||||
mjBUILTIN_FLAT // 2d: rgb1; cube: rgb1-up, rgb2-side, rgb3-down
|
|
||||||
} mjtBuiltin;
|
|
||||||
|
|
||||||
|
|
||||||
// mark type for procedural textures
|
|
||||||
typedef enum _mjtMark {
|
|
||||||
mjMARK_NONE = 0, // no mark
|
|
||||||
mjMARK_EDGE, // paint edges
|
|
||||||
mjMARK_CROSS, // paint cross
|
|
||||||
mjMARK_RANDOM // paint random dots
|
|
||||||
} mjtMark;
|
|
||||||
|
|
||||||
|
|
||||||
// error information
|
// error information
|
||||||
class [[nodiscard]] mjCError {
|
class [[nodiscard]] mjCError {
|
||||||
public:
|
public:
|
||||||
@@ -871,7 +853,7 @@ class mjCHField : public mjCBase {
|
|||||||
//------------------------- class mjCTexture -------------------------------------------------------
|
//------------------------- class mjCTexture -------------------------------------------------------
|
||||||
// Describes a texture
|
// Describes a texture
|
||||||
|
|
||||||
class mjCTexture : public mjCBase {
|
class mjCTexture : public mjCBase, private mjmTexture {
|
||||||
friend class mjCModel;
|
friend class mjCModel;
|
||||||
friend class mjXReader;
|
friend class mjXReader;
|
||||||
friend class mjXWriter;
|
friend class mjXWriter;
|
||||||
@@ -879,32 +861,17 @@ class mjCTexture : public mjCBase {
|
|||||||
public:
|
public:
|
||||||
~mjCTexture(); // destructor
|
~mjCTexture(); // destructor
|
||||||
|
|
||||||
std::string get_file() const { return file; }
|
mjmTexture spec;
|
||||||
|
using mjCBase::name;
|
||||||
|
using mjCBase::classname;
|
||||||
|
using mjCBase::info;
|
||||||
|
|
||||||
mjtTexture type; // texture type
|
void CopyFromSpec(void);
|
||||||
|
void PointToLocal(void);
|
||||||
|
|
||||||
// method 1: builtin
|
std::string get_file() const { return file_; }
|
||||||
mjtBuiltin builtin; // builtin type
|
std::string get_content_type() const { return content_type_; }
|
||||||
mjtMark mark; // mark type
|
std::vector<std::string> get_cubefiles() const { return cubefiles_; }
|
||||||
double rgb1[3]; // first color for builtin
|
|
||||||
double rgb2[3]; // second color for builtin
|
|
||||||
double markrgb[3]; // mark color
|
|
||||||
double random; // probability of random dots
|
|
||||||
int height; // height in pixels (square for cube and skybox)
|
|
||||||
int width; // width in pixels
|
|
||||||
|
|
||||||
// method 2: single file
|
|
||||||
std::string content_type; // content type of file
|
|
||||||
std::string file; // png file to load; use for all sides of cube
|
|
||||||
int gridsize[2]; // size of grid for composite file; (1,1)-repeat
|
|
||||||
char gridlayout[13]; // row-major: L,R,F,B,U,D for faces; . for unused
|
|
||||||
|
|
||||||
// method 3: separate files
|
|
||||||
std::string cubefiles[6]; // different file for each side of the cube
|
|
||||||
|
|
||||||
// flip options
|
|
||||||
bool hflip; // horizontal flip
|
|
||||||
bool vflip; // vertical flip
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mjCTexture(mjCModel*); // constructor
|
mjCTexture(mjCModel*); // constructor
|
||||||
@@ -928,6 +895,13 @@ class mjCTexture : public mjCBase {
|
|||||||
unsigned int& w, unsigned int& h);
|
unsigned int& w, unsigned int& h);
|
||||||
|
|
||||||
mjtByte* rgb; // rgb data
|
mjtByte* rgb; // rgb data
|
||||||
|
std::string file_;
|
||||||
|
std::string content_type_;
|
||||||
|
std::vector<std::string> cubefiles_;
|
||||||
|
|
||||||
|
std::string spec_file_;
|
||||||
|
std::string spec_content_type_;
|
||||||
|
std::vector<std::string> spec_cubefiles_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2980,7 +2980,7 @@ void mjXReader::Visual(XMLElement* section) {
|
|||||||
// asset section parser
|
// asset section parser
|
||||||
void mjXReader::Asset(XMLElement* section) {
|
void mjXReader::Asset(XMLElement* section) {
|
||||||
int n;
|
int n;
|
||||||
string text, name;
|
string text, name, texname, content_type, file;
|
||||||
XMLElement* elem;
|
XMLElement* elem;
|
||||||
|
|
||||||
// iterate over child elements
|
// iterate over child elements
|
||||||
@@ -2998,16 +2998,25 @@ void mjXReader::Asset(XMLElement* section) {
|
|||||||
// texture sub-element
|
// texture sub-element
|
||||||
if (name=="texture") {
|
if (name=="texture") {
|
||||||
// create texture
|
// create texture
|
||||||
mjCTexture* ptex = model->AddTexture();
|
mjmTexture* ptex = mjm_addTexture(model);
|
||||||
GetXMLPos(elem, ptex);
|
|
||||||
|
// write error info
|
||||||
|
mjm_setString(ptex->info,
|
||||||
|
std::string("line = " + std::to_string(elem->GetLineNum()) + ", column = -1").c_str());
|
||||||
|
|
||||||
// read attributes
|
// read attributes
|
||||||
if (MapValue(elem, "type", &n, texture_map, texture_sz)) {
|
if (MapValue(elem, "type", &n, texture_map, texture_sz)) {
|
||||||
ptex->type = (mjtTexture)n;
|
ptex->type = (mjtTexture)n;
|
||||||
}
|
}
|
||||||
ReadAttrTxt(elem, "name", ptex->name);
|
if (ReadAttrTxt(elem, "name", texname)) {
|
||||||
ReadAttrTxt(elem, "content_type", ptex->content_type);
|
mjm_setString(ptex->name, texname.c_str());
|
||||||
ReadAttrTxt(elem, "file", ptex->file);
|
}
|
||||||
|
if (ReadAttrTxt(elem, "content_type", content_type)) {
|
||||||
|
mjm_setString(ptex->content_type, content_type.c_str());
|
||||||
|
}
|
||||||
|
if (ReadAttrTxt(elem, "file", file)) {
|
||||||
|
mjm_setString(ptex->file, file.c_str());
|
||||||
|
}
|
||||||
ReadAttrInt(elem, "width", &ptex->width);
|
ReadAttrInt(elem, "width", &ptex->width);
|
||||||
ReadAttrInt(elem, "height", &ptex->height);
|
ReadAttrInt(elem, "height", &ptex->height);
|
||||||
ReadAttr(elem, "rgb1", 3, ptex->rgb1, text);
|
ReadAttr(elem, "rgb1", 3, ptex->rgb1, text);
|
||||||
@@ -3042,12 +3051,16 @@ void mjXReader::Asset(XMLElement* section) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// separate files
|
// separate files
|
||||||
ReadAttrTxt(elem, "fileright", ptex->cubefiles[0]);
|
std::vector<string> cubefiles(6);
|
||||||
ReadAttrTxt(elem, "fileleft", ptex->cubefiles[1]);
|
ReadAttrTxt(elem, "fileright", cubefiles[0]);
|
||||||
ReadAttrTxt(elem, "fileup", ptex->cubefiles[2]);
|
ReadAttrTxt(elem, "fileleft", cubefiles[1]);
|
||||||
ReadAttrTxt(elem, "filedown", ptex->cubefiles[3]);
|
ReadAttrTxt(elem, "fileup", cubefiles[2]);
|
||||||
ReadAttrTxt(elem, "filefront", ptex->cubefiles[4]);
|
ReadAttrTxt(elem, "filedown", cubefiles[3]);
|
||||||
ReadAttrTxt(elem, "fileback", ptex->cubefiles[5]);
|
ReadAttrTxt(elem, "filefront", cubefiles[4]);
|
||||||
|
ReadAttrTxt(elem, "fileback", cubefiles[5]);
|
||||||
|
for (int i = 0; i < cubefiles.size(); i++) {
|
||||||
|
mjm_setInStringVec(ptex->cubefiles, i, cubefiles[i].c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// material sub-element
|
// material sub-element
|
||||||
|
|||||||
@@ -1358,16 +1358,16 @@ void mjXWriter::Asset(XMLElement* root) {
|
|||||||
// write textures loaded from files
|
// write textures loaded from files
|
||||||
else {
|
else {
|
||||||
// write single file
|
// write single file
|
||||||
WriteAttrTxt(elem, "content_type", ptex->content_type);
|
WriteAttrTxt(elem, "content_type", ptex->get_content_type());
|
||||||
WriteAttrTxt(elem, "file", ptex->file);
|
WriteAttrTxt(elem, "file", ptex->get_file());
|
||||||
|
|
||||||
// write separate files
|
// write separate files
|
||||||
WriteAttrTxt(elem, "fileright", ptex->cubefiles[0]);
|
WriteAttrTxt(elem, "fileright", ptex->get_cubefiles()[0]);
|
||||||
WriteAttrTxt(elem, "fileleft", ptex->cubefiles[1]);
|
WriteAttrTxt(elem, "fileleft", ptex->get_cubefiles()[1]);
|
||||||
WriteAttrTxt(elem, "fileup", ptex->cubefiles[2]);
|
WriteAttrTxt(elem, "fileup", ptex->get_cubefiles()[2]);
|
||||||
WriteAttrTxt(elem, "filedown", ptex->cubefiles[3]);
|
WriteAttrTxt(elem, "filedown", ptex->get_cubefiles()[3]);
|
||||||
WriteAttrTxt(elem, "filefront", ptex->cubefiles[4]);
|
WriteAttrTxt(elem, "filefront", ptex->get_cubefiles()[4]);
|
||||||
WriteAttrTxt(elem, "fileback", ptex->cubefiles[5]);
|
WriteAttrTxt(elem, "fileback", ptex->get_cubefiles()[5]);
|
||||||
if (ptex->hflip) {
|
if (ptex->hflip) {
|
||||||
WriteAttrKey(elem, "hflip", bool_map, 2, 1);
|
WriteAttrKey(elem, "hflip", bool_map, 2, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user