Add support in mjModel for tagging textures with different roles, and use the slot index of a texture to designate its role.

PiperOrigin-RevId: 654030065
Change-Id: I34a5b132a7f91a6bb8f260500c1b9c128a03b596
This commit is contained in:
Tom Erez
2024-07-19 09:28:34 -07:00
committed by Copybara-Service
parent 8a8a44a4db
commit 796173170c
14 changed files with 99 additions and 27 deletions
+11
View File
@@ -175,6 +175,17 @@ Texture types, specifying how the texture will be mapped. These values are used
.. mujoco-include:: mjtTexture .. mujoco-include:: mjtTexture
.. _mjtTextureRole:
mjtTextureRole
~~~~~~~~~~~~~~
Texture roles, specifying how the renderer should interpret the texture. Note that the MuJoCo built-in renderer only
uses RGB textures. These values are used to store the texture index in the material's array ``m->mat_texid``.
.. mujoco-include:: mjtTextureRole
.. _mjtIntegrator: .. _mjtIntegrator:
mjtIntegrator mjtIntegrator
+17 -4
View File
@@ -477,6 +477,19 @@ typedef enum mjtTexture_ { // type of texture
mjTEXTURE_CUBE, // cube texture, suitable for all other geom types mjTEXTURE_CUBE, // cube texture, suitable for all other geom types
mjTEXTURE_SKYBOX // cube texture used as skybox mjTEXTURE_SKYBOX // cube texture used as skybox
} mjtTexture; } mjtTexture;
typedef enum mjtTextureRole_ { // role of texture map in rendering
mjTEXROLE_USER = 0, // unspecified
mjTEXROLE_RGB, // base color (albedo)
mjTEXROLE_OCCLUSION, // ambient occlusion
mjTEXROLE_ROUGHNESS, // roughness
mjTEXROLE_METALLIC, // metallic
mjTEXROLE_NORMAL, // normal (bump) map
mjTEXROLE_OPACITY, // transperancy
mjTEXROLE_EMISSIVE, // light emission
mjTEXROLE_RGBA, // base color, opacity
mjTEXROLE_ORM, // occlusion, roughness, metallic
mjNTEXROLE
} mjtTextureRole;
typedef enum mjtIntegrator_ { // integrator mode typedef enum mjtIntegrator_ { // integrator mode
mjINT_EULER = 0, // semi-implicit Euler mjINT_EULER = 0, // semi-implicit Euler
mjINT_RK4, // 4th-order Runge Kutta mjINT_RK4, // 4th-order Runge Kutta
@@ -1217,7 +1230,7 @@ struct mjModel_ {
int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1) int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1)
// materials // materials
int* mat_texid; // indices of textures; -1: none (nmat x mjNTEXMAT) int* mat_texid; // indices of textures; -1: none (nmat x mjNTEXROLE)
mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1) mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1)
float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2) float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2)
float* mat_emission; // emission (x rgb) (nmat x 1) float* mat_emission; // emission (x rgb) (nmat x 1)
@@ -1544,9 +1557,9 @@ struct mjrContext_ { // custom OpenGL context
unsigned int auxColor_r[mjNAUX]; // auxiliary color buffer for resolving unsigned int auxColor_r[mjNAUX]; // auxiliary color buffer for resolving
// materials with textures // materials with textures
int mat_texid[mjMAXMATERIAL*mjNTEXMAT]; // material texture ids (-1: no texture) int mat_texid[mjMAXMATERIAL*mjNTEXROLE]; // material texture ids (-1: no texture)
int mat_texuniform[mjMAXMATERIAL]; // texture repetition for 2d mapping int mat_texuniform[mjMAXMATERIAL]; // texture repetition for 2d mapping
int mat_texrepeat[mjMAXMATERIAL*2]; // texture repetition for 2d mapping int mat_texrepeat[mjMAXMATERIAL*2]; // texture repetition for 2d mapping
// texture objects and info // texture objects and info
int ntexture; // number of allocated textures int ntexture; // number of allocated textures
+16 -2
View File
@@ -42,7 +42,6 @@
#define mjNIMP 5 // number of solver impedance parameters #define mjNIMP 5 // number of solver impedance parameters
#define mjNSOLVER 200 // size of one mjData.solver array #define mjNSOLVER 200 // size of one mjData.solver array
#define mjNISLAND 20 // number of mjData.solver arrays #define mjNISLAND 20 // number of mjData.solver arrays
#define mjNTEXMAT 6 // number of textures per material
//---------------------------------- enum types (mjt) ---------------------------------------------- //---------------------------------- enum types (mjt) ----------------------------------------------
@@ -133,6 +132,21 @@ typedef enum mjtTexture_ { // type of texture
} mjtTexture; } mjtTexture;
typedef enum mjtTextureRole_ { // role of texture map in rendering
mjTEXROLE_USER = 0, // unspecified
mjTEXROLE_RGB, // base color (albedo)
mjTEXROLE_OCCLUSION, // ambient occlusion
mjTEXROLE_ROUGHNESS, // roughness
mjTEXROLE_METALLIC, // metallic
mjTEXROLE_NORMAL, // normal (bump) map
mjTEXROLE_OPACITY, // transperancy
mjTEXROLE_EMISSIVE, // light emission
mjTEXROLE_RGBA, // base color, opacity
mjTEXROLE_ORM, // occlusion, roughness, metallic
mjNTEXROLE
} mjtTextureRole;
typedef enum mjtIntegrator_ { // integrator mode typedef enum mjtIntegrator_ { // integrator mode
mjINT_EULER = 0, // semi-implicit Euler mjINT_EULER = 0, // semi-implicit Euler
mjINT_RK4, // 4th-order Runge Kutta mjINT_RK4, // 4th-order Runge Kutta
@@ -930,7 +944,7 @@ struct mjModel_ {
int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1) int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1)
// materials // materials
int* mat_texid; // indices of textures; -1: none (nmat x mjNTEXMAT) int* mat_texid; // indices of textures; -1: none (nmat x mjNTEXROLE)
mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1) mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1)
float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2) float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2)
float* mat_emission; // emission (x rgb) (nmat x 1) float* mat_emission; // emission (x rgb) (nmat x 1)
+3 -3
View File
@@ -115,9 +115,9 @@ struct mjrContext_ { // custom OpenGL context
unsigned int auxColor_r[mjNAUX]; // auxiliary color buffer for resolving unsigned int auxColor_r[mjNAUX]; // auxiliary color buffer for resolving
// materials with textures // materials with textures
int mat_texid[mjMAXMATERIAL*mjNTEXMAT]; // material texture ids (-1: no texture) int mat_texid[mjMAXMATERIAL*mjNTEXROLE]; // material texture ids (-1: no texture)
int mat_texuniform[mjMAXMATERIAL]; // texture repetition for 2d mapping int mat_texuniform[mjMAXMATERIAL]; // texture repetition for 2d mapping
int mat_texrepeat[mjMAXMATERIAL*2]; // texture repetition for 2d mapping int mat_texrepeat[mjMAXMATERIAL*2]; // texture repetition for 2d mapping
// texture objects and info // texture objects and info
int ntexture; // number of allocated textures int ntexture; // number of allocated textures
+1 -1
View File
@@ -414,7 +414,7 @@
X ( int, tex_adr, ntex, 1 ) \ X ( int, tex_adr, ntex, 1 ) \
X ( mjtByte, tex_data, ntexdata, 1 ) \ X ( mjtByte, tex_data, ntexdata, 1 ) \
XMJV( int, tex_pathadr, ntex, 1 ) \ XMJV( int, tex_pathadr, ntex, 1 ) \
XMJV( int, mat_texid, nmat, mjNTEXMAT ) \ XMJV( int, mat_texid, nmat, mjNTEXROLE ) \
XMJV( mjtByte, mat_texuniform, nmat, 1 ) \ XMJV( mjtByte, mat_texuniform, nmat, 1 ) \
XMJV( float, mat_texrepeat, nmat, 2 ) \ XMJV( float, mat_texrepeat, nmat, 2 ) \
XMJV( float, mat_emission, nmat, 1 ) \ XMJV( float, mat_emission, nmat, 1 ) \
+18
View File
@@ -119,6 +119,24 @@ ENUMS: Mapping[str, EnumDecl] = dict([
('mjTEXTURE_SKYBOX', 2), ('mjTEXTURE_SKYBOX', 2),
]), ]),
)), )),
('mjtTextureRole',
EnumDecl(
name='mjtTextureRole',
declname='enum mjtTextureRole_',
values=dict([
('mjTEXROLE_USER', 0),
('mjTEXROLE_RGB', 1),
('mjTEXROLE_OCCLUSION', 2),
('mjTEXROLE_ROUGHNESS', 3),
('mjTEXROLE_METALLIC', 4),
('mjTEXROLE_NORMAL', 5),
('mjTEXROLE_OPACITY', 6),
('mjTEXROLE_EMISSIVE', 7),
('mjTEXROLE_RGBA', 8),
('mjTEXROLE_ORM', 9),
('mjNTEXROLE', 10),
]),
)),
('mjtIntegrator', ('mjtIntegrator',
EnumDecl( EnumDecl(
name='mjtIntegrator', name='mjtIntegrator',
+2 -2
View File
@@ -2925,7 +2925,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=PointerType( type=PointerType(
inner_type=ValueType(name='int'), inner_type=ValueType(name='int'),
), ),
doc='indices of textures; -1: none (nmat x mjNTEXMAT)', # pylint: disable=line-too-long doc='indices of textures; -1: none (nmat x mjNTEXROLE)', # pylint: disable=line-too-long
), ),
StructFieldDecl( StructFieldDecl(
name='mat_texuniform', name='mat_texuniform',
@@ -7967,7 +7967,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
name='mat_texid', name='mat_texid',
type=ArrayType( type=ArrayType(
inner_type=ValueType(name='int'), inner_type=ValueType(name='int'),
extents=(600,), extents=(1000,),
), ),
doc='material texture ids (-1: no texture)', doc='material texture ids (-1: no texture)',
), ),
+1 -1
View File
@@ -168,7 +168,7 @@
X( float, light_, specular, nlight, 3 ) X( float, light_, specular, nlight, 3 )
#define MJMODEL_MATERIAL \ #define MJMODEL_MATERIAL \
X( int, mat_, texid, nmat, mjNTEXMAT ) \ X( int, mat_, texid, nmat, mjNTEXROLE ) \
X( mjtByte, mat_, texuniform, nmat, 1 ) \ X( mjtByte, mat_, texuniform, nmat, 1 ) \
X( float, mat_, texrepeat, nmat, 2 ) \ X( float, mat_, texrepeat, nmat, 2 ) \
X( float, mat_, emission, nmat, 1 ) \ X( float, mat_, emission, nmat, 1 ) \
+3 -1
View File
@@ -252,7 +252,9 @@ class USDExporter:
assert geom_name not in self.geom_names assert geom_name not in self.geom_names
texture_file = ( texture_file = (
self.texture_files[self.model.mat_texid[geom.matid][0]] self.texture_files[
self.model.mat_texid[geom.matid][mujoco.mjTEXROLE_RGB]
]
if geom.matid != -1 if geom.matid != -1
else None else None
) )
+1 -1
View File
@@ -334,7 +334,7 @@ void mj_printFormattedModel(const mjModel* m, const char* filename, const char*
const int* object_class; const int* object_class;
#define X(type, name, num, sz) \ #define X(type, name, num, sz) \
if (&m->num == object_class && (strncmp(#name, "name_", 5) != 0) && sz) { \ if (&m->num == object_class && (strncmp(#name, "name_", 5) != 0) && sz > 0) { \
const char* format = _Generic(*m->name, \ const char* format = _Generic(*m->name, \
double: float_format, \ double: float_format, \
float: float_format, \ float: float_format, \
+6 -6
View File
@@ -1307,9 +1307,9 @@ static void makeMaterial(const mjModel* m, mjrContext* con) {
mju_error("Maximum number of materials is %d", mjMAXMATERIAL); mju_error("Maximum number of materials is %d", mjMAXMATERIAL);
} }
for (int i=0; i < m->nmat; i++) { for (int i=0; i < m->nmat; i++) {
if (m->mat_texid[i*mjNTEXMAT] >= 0) { if (m->mat_texid[i*mjNTEXROLE + mjTEXROLE_RGB] >= 0) {
for (int j=0; j < mjNTEXMAT; j++) { for (int j=0; j < mjNTEXROLE; j++) {
con->mat_texid[i*mjNTEXMAT + j] = m->mat_texid[i*mjNTEXMAT + j]; con->mat_texid[i*mjNTEXROLE + j] = m->mat_texid[i*mjNTEXROLE + j];
} }
con->mat_texuniform[i] = m->mat_texuniform[i]; con->mat_texuniform[i] = m->mat_texuniform[i];
con->mat_texrepeat[2*i] = m->mat_texrepeat[2*i]; con->mat_texrepeat[2*i] = m->mat_texrepeat[2*i];
@@ -1322,10 +1322,10 @@ static void makeMaterial(const mjModel* m, mjrContext* con) {
if (m->nmat >= mjMAXMATERIAL-2) { if (m->nmat >= mjMAXMATERIAL-2) {
mju_error("With skybox, maximum number of materials is %d", mjMAXMATERIAL); mju_error("With skybox, maximum number of materials is %d", mjMAXMATERIAL);
} }
con->mat_texid[mjNTEXMAT * (mjMAXMATERIAL-1)] = i; for (int j=0; j < mjNTEXROLE; j++) {
for (int j=1; j < mjNTEXMAT; j++) { con->mat_texid[mjNTEXROLE * (mjMAXMATERIAL-1) + j] = -1;
con->mat_texid[mjNTEXMAT * (mjMAXMATERIAL-1) + j] = -1;
} }
con->mat_texid[mjNTEXROLE * (mjMAXMATERIAL-1) + mjTEXROLE_RGB] = i;
break; break;
} }
+3 -1
View File
@@ -63,7 +63,9 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
float plane[4], scl[2]; float plane[4], scl[2];
int texid = -1; int texid = -1;
if (geom) { if (geom) {
texid = (geom->matid == -1) ? -1 : con->mat_texid[mjNTEXMAT * geom->matid]; if (geom->matid >= 0) {
texid = con->mat_texid[mjNTEXROLE * geom->matid + mjTEXROLE_RGB];
}
} }
// shadow // shadow
+3 -3
View File
@@ -2520,10 +2520,10 @@ void mjCModel::CopyObjects(mjModel* m) {
mjCMaterial* pmat = materials_[i]; mjCMaterial* pmat = materials_[i];
// set fields // set fields
m->mat_texid[mjNTEXMAT*i] = pmat->texid; for (int j=0; j<mjNTEXROLE; j++) {
for (int j=1; j<mjNTEXMAT; j++) { m->mat_texid[mjNTEXROLE*i+j] = -1;
m->mat_texid[mjNTEXMAT*i+j] = -1;
} }
m->mat_texid[mjNTEXROLE*i+mjTEXROLE_RGB] = pmat->texid;
m->mat_texuniform[i] = pmat->texuniform; m->mat_texuniform[i] = pmat->texuniform;
mjuu_copyvec(m->mat_texrepeat+2*i, pmat->texrepeat, 2); mjuu_copyvec(m->mat_texrepeat+2*i, pmat->texrepeat, 2);
m->mat_emission[i] = pmat->emission; m->mat_emission[i] = pmat->emission;
+14 -2
View File
@@ -50,7 +50,6 @@ public const int mjNREF = 2;
public const int mjNIMP = 5; public const int mjNIMP = 5;
public const int mjNSOLVER = 200; public const int mjNSOLVER = 200;
public const int mjNISLAND = 20; public const int mjNISLAND = 20;
public const int mjNTEXMAT = 6;
public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJPLUGIN_H_ = true; public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJPLUGIN_H_ = true;
public const bool mjEXTERNC = true; public const bool mjEXTERNC = true;
public const bool THIRD_PARTY_MUJOCO_MJRENDER_H_ = true; public const bool THIRD_PARTY_MUJOCO_MJRENDER_H_ = true;
@@ -209,6 +208,19 @@ public enum mjtTexture : int{
mjTEXTURE_CUBE = 1, mjTEXTURE_CUBE = 1,
mjTEXTURE_SKYBOX = 2, mjTEXTURE_SKYBOX = 2,
} }
public enum mjtTextureRole : int{
mjTEXROLE_USER = 0,
mjTEXROLE_RGB = 1,
mjTEXROLE_OCCLUSION = 2,
mjTEXROLE_ROUGHNESS = 3,
mjTEXROLE_METALLIC = 4,
mjTEXROLE_NORMAL = 5,
mjTEXROLE_OPACITY = 6,
mjTEXROLE_EMISSIVE = 7,
mjTEXROLE_RGBA = 8,
mjTEXROLE_ORM = 9,
mjNTEXROLE = 10,
}
public enum mjtIntegrator : int{ public enum mjtIntegrator : int{
mjINT_EULER = 0, mjINT_EULER = 0,
mjINT_RK4 = 1, mjINT_RK4 = 1,
@@ -5631,7 +5643,7 @@ public unsafe struct mjrContext_ {
public fixed uint auxFBO_r[10]; public fixed uint auxFBO_r[10];
public fixed uint auxColor[10]; public fixed uint auxColor[10];
public fixed uint auxColor_r[10]; public fixed uint auxColor_r[10];
public fixed int mat_texid[600]; public fixed int mat_texid[1000];
public fixed int mat_texuniform[100]; public fixed int mat_texuniform[100];
public fixed int mat_texrepeat[200]; public fixed int mat_texrepeat[200];
public int ntexture; public int ntexture;