Adds color space to textures.
PiperOrigin-RevId: 761907261 Change-Id: Iec546d1d5907a15e57ef809ec31850640fc52915
This commit is contained in:
committed by
Copybara-Service
parent
62a9d5b98d
commit
3e9bc79b54
@@ -1526,6 +1526,12 @@ still be specified here but this functionality is now deprecated and will be rem
|
||||
with the texrepeat attribute of :ref:`material <asset-material>`. The data can be loaded from a single file or
|
||||
created procedurally.
|
||||
|
||||
.. _asset-texture-colorspace:
|
||||
|
||||
:at:`colorspace`: :at-val:`[auto, linear, sRGB], "auto"`
|
||||
This attribute determines the color space of the texture. The default value ``auto`` means that the color space will
|
||||
be determined from the image file itself. If no color space is defined in the file, then ``linear`` is assumed.
|
||||
|
||||
.. _asset-texture-content_type:
|
||||
|
||||
:at:`content_type`: :at-val:`string, optional`
|
||||
|
||||
+6
-6
@@ -153,17 +153,17 @@
|
||||
| :ref:`texture | \* | :class: mjcf-attributes |
|
||||
| <asset-texture>` | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`name<asset-texture-name>` | :ref:`type<asset-texture-type>` | :ref:`content_type<asset-texture-content_type>` | :ref:`file<asset-texture-file>` | |
|
||||
| | | | :ref:`name<asset-texture-name>` | :ref:`type<asset-texture-type>` | :ref:`colorspace<asset-texture-colorspace>` | :ref:`content_type<asset-texture-content_type>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`gridsize<asset-texture-gridsize>` | :ref:`gridlayout<asset-texture-gridlayout>` | :ref:`fileright<asset-texture-fileright>` | :ref:`fileleft<asset-texture-fileleft>` | |
|
||||
| | | | :ref:`file<asset-texture-file>` | :ref:`gridsize<asset-texture-gridsize>` | :ref:`gridlayout<asset-texture-gridlayout>` | :ref:`fileright<asset-texture-fileright>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`fileup<asset-texture-fileup>` | :ref:`filedown<asset-texture-filedown>` | :ref:`filefront<asset-texture-filefront>` | :ref:`fileback<asset-texture-fileback>` | |
|
||||
| | | | :ref:`fileleft<asset-texture-fileleft>` | :ref:`fileup<asset-texture-fileup>` | :ref:`filedown<asset-texture-filedown>` | :ref:`filefront<asset-texture-filefront>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`builtin<asset-texture-builtin>` | :ref:`rgb1<asset-texture-rgb1>` | :ref:`rgb2<asset-texture-rgb2>` | :ref:`mark<asset-texture-mark>` | |
|
||||
| | | | :ref:`fileback<asset-texture-fileback>` | :ref:`builtin<asset-texture-builtin>` | :ref:`rgb1<asset-texture-rgb1>` | :ref:`rgb2<asset-texture-rgb2>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`markrgb<asset-texture-markrgb>` | :ref:`random<asset-texture-random>` | :ref:`width<asset-texture-width>` | :ref:`height<asset-texture-height>` | |
|
||||
| | | | :ref:`mark<asset-texture-mark>` | :ref:`markrgb<asset-texture-markrgb>` | :ref:`random<asset-texture-random>` | :ref:`width<asset-texture-width>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`hflip<asset-texture-hflip>` | :ref:`vflip<asset-texture-vflip>` | :ref:`nchannel<asset-texture-nchannel>` | | |
|
||||
| | | | :ref:`height<asset-texture-height>` | :ref:`hflip<asset-texture-hflip>` | :ref:`vflip<asset-texture-vflip>` | :ref:`nchannel<asset-texture-nchannel>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |_| asset |br| |_| |L| | | .. table:: |
|
||||
|
||||
@@ -544,6 +544,11 @@ typedef enum mjtTextureRole_ { // role of texture map in rendering
|
||||
mjTEXROLE_ORM, // occlusion, roughness, metallic
|
||||
mjNTEXROLE
|
||||
} mjtTextureRole;
|
||||
typedef enum mjtColorSpace_ { // type of color space encoding
|
||||
mjCOLORSPACE_AUTO = 0, // attempts to autodetect color space, defaults to linear
|
||||
mjCOLORSPACE_LINEAR, // linear color space
|
||||
mjCOLORSPACE_SRGB // standard RGB color space
|
||||
} mjtColorSpace;
|
||||
typedef enum mjtIntegrator_ { // integrator mode
|
||||
mjINT_EULER = 0, // semi-implicit Euler
|
||||
mjINT_RK4, // 4th-order Runge Kutta
|
||||
@@ -1326,6 +1331,7 @@ struct mjModel_ {
|
||||
|
||||
// textures
|
||||
int* tex_type; // texture type (mjtTexture) (ntex x 1)
|
||||
int* tex_colorspace; // texture colorspace (mjtColorSpace) (ntex x 1)
|
||||
int* tex_height; // number of rows in texture image (ntex x 1)
|
||||
int* tex_width; // number of columns in texture image (ntex x 1)
|
||||
int* tex_nchannel; // number of channels in texture image (ntex x 1)
|
||||
@@ -2150,6 +2156,7 @@ typedef struct mjsTexture_ { // texture specification
|
||||
mjsElement* element; // element type
|
||||
mjString* name; // name
|
||||
mjtTexture type; // texture type
|
||||
mjtColorSpace colorspace; // colorspace
|
||||
|
||||
// method 1: builtin
|
||||
int builtin; // builtin type (mjtBuiltin)
|
||||
|
||||
@@ -151,6 +151,13 @@ typedef enum mjtTextureRole_ { // role of texture map in rendering
|
||||
} mjtTextureRole;
|
||||
|
||||
|
||||
typedef enum mjtColorSpace_ { // type of color space encoding
|
||||
mjCOLORSPACE_AUTO = 0, // attempts to autodetect color space, defaults to linear
|
||||
mjCOLORSPACE_LINEAR, // linear color space
|
||||
mjCOLORSPACE_SRGB // standard RGB color space
|
||||
} mjtColorSpace;
|
||||
|
||||
|
||||
typedef enum mjtIntegrator_ { // integrator mode
|
||||
mjINT_EULER = 0, // semi-implicit Euler
|
||||
mjINT_RK4, // 4th-order Runge Kutta
|
||||
@@ -994,6 +1001,7 @@ struct mjModel_ {
|
||||
|
||||
// textures
|
||||
int* tex_type; // texture type (mjtTexture) (ntex x 1)
|
||||
int* tex_colorspace; // texture colorspace (mjtColorSpace) (ntex x 1)
|
||||
int* tex_height; // number of rows in texture image (ntex x 1)
|
||||
int* tex_width; // number of columns in texture image (ntex x 1)
|
||||
int* tex_nchannel; // number of channels in texture image (ntex x 1)
|
||||
|
||||
@@ -525,6 +525,7 @@ typedef struct mjsTexture_ { // texture specification
|
||||
mjsElement* element; // element type
|
||||
mjString* name; // name
|
||||
mjtTexture type; // texture type
|
||||
mjtColorSpace colorspace; // colorspace
|
||||
|
||||
// method 1: builtin
|
||||
int builtin; // builtin type (mjtBuiltin)
|
||||
|
||||
@@ -439,6 +439,7 @@
|
||||
XNV ( float, hfield_data, nhfielddata, 1 ) \
|
||||
X ( int, hfield_pathadr, nhfield, 1 ) \
|
||||
X ( int, tex_type, ntex, 1 ) \
|
||||
X ( int, tex_colorspace, ntex, 1 ) \
|
||||
X ( int, tex_height, ntex, 1 ) \
|
||||
X ( int, tex_width, ntex, 1 ) \
|
||||
X ( int, tex_nchannel, ntex, 1 ) \
|
||||
|
||||
@@ -139,6 +139,16 @@ ENUMS: Mapping[str, EnumDecl] = dict([
|
||||
('mjNTEXROLE', 10),
|
||||
]),
|
||||
)),
|
||||
('mjtColorSpace',
|
||||
EnumDecl(
|
||||
name='mjtColorSpace',
|
||||
declname='enum mjtColorSpace_',
|
||||
values=dict([
|
||||
('mjCOLORSPACE_AUTO', 0),
|
||||
('mjCOLORSPACE_LINEAR', 1),
|
||||
('mjCOLORSPACE_SRGB', 2),
|
||||
]),
|
||||
)),
|
||||
('mjtIntegrator',
|
||||
EnumDecl(
|
||||
name='mjtIntegrator',
|
||||
|
||||
@@ -3339,6 +3339,14 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
||||
doc='texture type (mjtTexture)',
|
||||
array_extent=('ntex',),
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='tex_colorspace',
|
||||
type=PointerType(
|
||||
inner_type=ValueType(name='int'),
|
||||
),
|
||||
doc='texture colorspace (mjtColorSpace)',
|
||||
array_extent=('ntex',),
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='tex_height',
|
||||
type=PointerType(
|
||||
@@ -9613,6 +9621,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
||||
type=ValueType(name='mjtTexture'),
|
||||
doc='texture type',
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='colorspace',
|
||||
type=ValueType(name='mjtColorSpace'),
|
||||
doc='colorspace',
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='builtin',
|
||||
type=ValueType(name='int'),
|
||||
|
||||
@@ -1387,15 +1387,20 @@ void mjr_uploadTexture(const mjModel* m, const mjrContext* con, int texid) {
|
||||
|
||||
// assign data
|
||||
int type = 0;
|
||||
int internaltype = 0;
|
||||
if (m->tex_nchannel[texid] == 3) {
|
||||
type = GL_RGB;
|
||||
internaltype = (m->tex_colorspace[texid] == mjCOLORSPACE_SRGB) ? GL_SRGB8_EXT : GL_RGB;
|
||||
} else if (m->tex_nchannel[texid] == 4) {
|
||||
type = GL_RGBA;
|
||||
internaltype = (m->tex_colorspace[texid] == mjCOLORSPACE_SRGB) ? GL_SRGB8_ALPHA8_EXT : GL_RGBA;
|
||||
} else {
|
||||
mju_error("Number of channels not supported: %d", m->tex_nchannel[texid]);
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, type, m->tex_width[texid], m->tex_height[texid], 0,
|
||||
type, GL_UNSIGNED_BYTE, m->tex_data + m->tex_adr[texid]);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internaltype, m->tex_width[texid],
|
||||
m->tex_height[texid], 0, type, GL_UNSIGNED_BYTE,
|
||||
m->tex_data + m->tex_adr[texid]);
|
||||
|
||||
// generate mipmaps
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
@@ -273,6 +273,7 @@ void mjs_defaultSkin(mjsSkin* skin) {
|
||||
void mjs_defaultTexture(mjsTexture* texture) {
|
||||
memset(texture, 0, sizeof(mjsTexture));
|
||||
texture->type = mjTEXTURE_CUBE;
|
||||
texture->colorspace = mjCOLORSPACE_AUTO;
|
||||
texture->rgb1[0] = texture->rgb1[1] = texture->rgb1[2] = 0.8;
|
||||
texture->rgb2[0] = texture->rgb2[1] = texture->rgb2[2] = 0.5;
|
||||
texture->random = 0.01;
|
||||
|
||||
@@ -3285,6 +3285,7 @@ void mjCModel::CopyObjects(mjModel* m) {
|
||||
|
||||
// set fields
|
||||
m->tex_type[i] = ptex->type;
|
||||
m->tex_colorspace[i] = ptex->colorspace;
|
||||
m->tex_height[i] = ptex->height;
|
||||
m->tex_width[i] = ptex->width;
|
||||
m->tex_nchannel[i] = ptex->nchannel;
|
||||
|
||||
+36
-10
@@ -55,6 +55,8 @@ class PNGImage {
|
||||
LodePNGColorType color_type);
|
||||
int Width() const { return width_; }
|
||||
int Height() const { return height_; }
|
||||
bool IsSRGB() const { return is_srgb_; }
|
||||
|
||||
uint8_t operator[] (int i) const { return data_[i]; }
|
||||
std::vector<unsigned char>& MoveData() { return data_; }
|
||||
|
||||
@@ -65,6 +67,7 @@ class PNGImage {
|
||||
|
||||
int width_;
|
||||
int height_;
|
||||
bool is_srgb_;
|
||||
LodePNGColorType color_type_;
|
||||
std::vector<uint8_t> data_;
|
||||
};
|
||||
@@ -104,8 +107,11 @@ PNGImage PNGImage::Load(const mjCBase* obj, mjResource* resource,
|
||||
|
||||
// decode PNG from buffer
|
||||
unsigned int w, h;
|
||||
unsigned err = lodepng::decode(image.data_, w, h,
|
||||
buffer, nbuffer, image.color_type_, 8);
|
||||
|
||||
lodepng::State state;
|
||||
state.info_raw.colortype = image.color_type_;
|
||||
state.info_raw.bitdepth = 8;
|
||||
unsigned err = lodepng::decode(image.data_, w, h, state, buffer, nbuffer);
|
||||
|
||||
// check for errors
|
||||
if (err) {
|
||||
@@ -116,6 +122,7 @@ PNGImage PNGImage::Load(const mjCBase* obj, mjResource* resource,
|
||||
|
||||
image.width_ = w;
|
||||
image.height_ = h;
|
||||
image.is_srgb_ = (state.info_png.srgb_defined == 1);
|
||||
|
||||
if (image.width_ <= 0 || image.height_ < 0) {
|
||||
std::stringstream ss;
|
||||
@@ -4257,7 +4264,7 @@ void mjCTexture::BuiltinCube(void) {
|
||||
// load PNG file
|
||||
void mjCTexture::LoadPNG(mjResource* resource,
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h) {
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb) {
|
||||
LodePNGColorType color_type;
|
||||
if (nchannel == 4) {
|
||||
color_type = LCT_RGBA;
|
||||
@@ -4272,13 +4279,14 @@ void mjCTexture::LoadPNG(mjResource* resource,
|
||||
PNGImage png_image = PNGImage::Load(this, resource, color_type);
|
||||
w = png_image.Width();
|
||||
h = png_image.Height();
|
||||
is_srgb = png_image.IsSRGB();
|
||||
image = png_image.MoveData();
|
||||
}
|
||||
|
||||
// load custom file
|
||||
void mjCTexture::LoadCustom(mjResource* resource,
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h) {
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb) {
|
||||
const void* buffer = 0;
|
||||
int buffer_sz = mju_readResource(resource, &buffer);
|
||||
|
||||
@@ -4295,6 +4303,9 @@ void mjCTexture::LoadCustom(mjResource* resource,
|
||||
w = pint[0];
|
||||
h = pint[1];
|
||||
|
||||
// assume linear color space
|
||||
is_srgb = false;
|
||||
|
||||
// check dimensions
|
||||
if (w < 1 || h < 1) {
|
||||
throw mjCError(this, "Non-PNG texture, assuming custom binary file format,\n"
|
||||
@@ -4317,7 +4328,7 @@ void mjCTexture::LoadCustom(mjResource* resource,
|
||||
// load from PNG or custom file, flip if specified
|
||||
void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h) {
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb) {
|
||||
std::string asset_type = GetAssetContentType(filename, content_type_);
|
||||
|
||||
// fallback to custom
|
||||
@@ -4333,9 +4344,9 @@ void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
||||
|
||||
try {
|
||||
if (asset_type == "image/png") {
|
||||
LoadPNG(resource, image, w, h);
|
||||
LoadPNG(resource, image, w, h, is_srgb);
|
||||
} else {
|
||||
LoadCustom(resource, image, w, h);
|
||||
LoadCustom(resource, image, w, h, is_srgb);
|
||||
}
|
||||
mju_closeResource(resource);
|
||||
} catch(mjCError err) {
|
||||
@@ -4402,12 +4413,16 @@ void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
||||
void mjCTexture::Load2D(std::string filename, const mjVFS* vfs) {
|
||||
// load PNG or custom
|
||||
unsigned int w, h;
|
||||
bool is_srgb;
|
||||
std::vector<unsigned char> image;
|
||||
LoadFlip(filename, vfs, image, w, h);
|
||||
LoadFlip(filename, vfs, image, w, h, is_srgb);
|
||||
|
||||
// assign size
|
||||
width = w;
|
||||
height = h;
|
||||
if (colorspace == mjCOLORSPACE_AUTO) {
|
||||
colorspace = is_srgb ? mjCOLORSPACE_SRGB : mjCOLORSPACE_LINEAR;
|
||||
}
|
||||
|
||||
// allocate and copy data
|
||||
std::int64_t size = static_cast<std::int64_t>(width)*height;
|
||||
@@ -4435,8 +4450,13 @@ void mjCTexture::LoadCubeSingle(std::string filename, const mjVFS* vfs) {
|
||||
|
||||
// load PNG or custom
|
||||
unsigned int w, h;
|
||||
bool is_srgb;
|
||||
std::vector<unsigned char> image;
|
||||
LoadFlip(filename, vfs, image, w, h);
|
||||
LoadFlip(filename, vfs, image, w, h, is_srgb);
|
||||
|
||||
if (colorspace == mjCOLORSPACE_AUTO) {
|
||||
colorspace = is_srgb ? mjCOLORSPACE_SRGB : mjCOLORSPACE_LINEAR;
|
||||
}
|
||||
|
||||
// check gridsize for compatibility
|
||||
if (w/gridsize[1] != h/gridsize[0] || (w%gridsize[1]) || (h%gridsize[0])) {
|
||||
@@ -4549,8 +4569,14 @@ void mjCTexture::LoadCubeSeparate(const mjVFS* vfs) {
|
||||
|
||||
// load PNG or custom
|
||||
unsigned int w, h;
|
||||
bool is_srgb;
|
||||
std::vector<unsigned char> image;
|
||||
LoadFlip(filename.Str(), vfs, image, w, h);
|
||||
LoadFlip(filename.Str(), vfs, image, w, h, is_srgb);
|
||||
|
||||
// assume all faces have the same colorspace
|
||||
if (colorspace == mjCOLORSPACE_AUTO) {
|
||||
colorspace = is_srgb ? mjCOLORSPACE_SRGB : mjCOLORSPACE_LINEAR;
|
||||
}
|
||||
|
||||
// PNG must be square
|
||||
if (w != h) {
|
||||
|
||||
@@ -1328,14 +1328,14 @@ class mjCTexture : public mjCTexture_, private mjsTexture {
|
||||
|
||||
void LoadFlip(std::string filename, const mjVFS* vfs, // load and flip
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h);
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb);
|
||||
|
||||
void LoadPNG(mjResource* resource,
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h);
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb);
|
||||
void LoadCustom(mjResource* resource,
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h);
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb);
|
||||
|
||||
bool clear_data_; // if true, data_ is empty and should be filled by Compile
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@ extern const int jac_sz;
|
||||
extern const int solver_sz;
|
||||
extern const int equality_sz;
|
||||
extern const int texture_sz;
|
||||
extern const int colorspace_sz;
|
||||
extern const int builtin_sz;
|
||||
extern const int mark_sz;
|
||||
extern const int dyn_sz;
|
||||
@@ -60,6 +61,7 @@ extern const mjMap jac_map[];
|
||||
extern const mjMap solver_map[];
|
||||
extern const mjMap equality_map[];
|
||||
extern const mjMap texture_map[];
|
||||
extern const mjMap colorspace_map[];
|
||||
extern const mjMap texrole_map[];
|
||||
extern const mjMap builtin_map[];
|
||||
extern const mjMap mark_map[];
|
||||
|
||||
@@ -241,8 +241,8 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||
{"<"},
|
||||
{"bone", "*", "5", "body", "bindpos", "bindquat", "vertid", "vertweight"},
|
||||
{">"},
|
||||
{"texture", "*", "23", "name", "type", "content_type", "file", "gridsize", "gridlayout",
|
||||
"fileright", "fileleft", "fileup", "filedown", "filefront", "fileback",
|
||||
{"texture", "*", "24", "name", "type", "colorspace", "content_type", "file", "gridsize",
|
||||
"gridlayout", "fileright", "fileleft", "fileup", "filedown", "filefront", "fileback",
|
||||
"builtin", "rgb1", "rgb2", "mark", "markrgb", "random", "width", "height",
|
||||
"hflip", "vflip", "nchannel"},
|
||||
{"material", "*", "12", "name", "class", "texture", "texrepeat", "texuniform",
|
||||
@@ -650,6 +650,15 @@ const mjMap texture_map[texture_sz] = {
|
||||
};
|
||||
|
||||
|
||||
// colorspace for texture
|
||||
const int colorspace_sz = 3;
|
||||
const mjMap colorspace_map[colorspace_sz] = {
|
||||
{"auto", mjCOLORSPACE_AUTO},
|
||||
{"linear", mjCOLORSPACE_LINEAR},
|
||||
{"sRGB", mjCOLORSPACE_SRGB}
|
||||
};
|
||||
|
||||
|
||||
// builtin type for texture
|
||||
const int builtin_sz = 4;
|
||||
const mjMap builtin_map[builtin_sz] = {
|
||||
@@ -3194,6 +3203,9 @@ void mjXReader::Asset(XMLElement* section, const mjVFS* vfs) {
|
||||
if (MapValue(elem, "type", &n, texture_map, texture_sz)) {
|
||||
texture->type = (mjtTexture)n;
|
||||
}
|
||||
if (MapValue(elem, "colorspace", &n, colorspace_map, colorspace_sz)) {
|
||||
texture->colorspace = (mjtColorSpace)n;
|
||||
}
|
||||
if (ReadAttrTxt(elem, "name", texname)) {
|
||||
mjs_setString(texture->name, texname.c_str());
|
||||
}
|
||||
|
||||
@@ -1488,6 +1488,7 @@ void mjXWriter::Asset(XMLElement* root) {
|
||||
|
||||
// write common attributes
|
||||
WriteAttrKey(elem, "type", texture_map, texture_sz, texture->type);
|
||||
WriteAttrKey(elem, "colorspace", colorspace_map, colorspace_sz, texture->colorspace);
|
||||
WriteAttrTxt(elem, "name", texture->name);
|
||||
|
||||
// write builtin
|
||||
|
||||
@@ -225,6 +225,11 @@ public enum mjtTextureRole : int{
|
||||
mjTEXROLE_ORM = 9,
|
||||
mjNTEXROLE = 10,
|
||||
}
|
||||
public enum mjtColorSpace : int{
|
||||
mjCOLORSPACE_AUTO = 0,
|
||||
mjCOLORSPACE_LINEAR = 1,
|
||||
mjCOLORSPACE_SRGB = 2,
|
||||
}
|
||||
public enum mjtIntegrator : int{
|
||||
mjINT_EULER = 0,
|
||||
mjINT_RK4 = 1,
|
||||
@@ -5569,6 +5574,7 @@ public unsafe struct mjModel_ {
|
||||
public float* hfield_data;
|
||||
public int* hfield_pathadr;
|
||||
public int* tex_type;
|
||||
public int* tex_colorspace;
|
||||
public int* tex_height;
|
||||
public int* tex_width;
|
||||
public int* tex_nchannel;
|
||||
|
||||
Reference in New Issue
Block a user