Copy texture coordinates from OBJ into flex. Fixes #2464.
PiperOrigin-RevId: 732109960 Change-Id: I506b3540ab5d489ce8f10d0c473919611ccb654a
This commit is contained in:
committed by
Copybara-Service
parent
06e217df7e
commit
7651cb1b33
@@ -3916,9 +3916,14 @@ cases, the user will specify a :el:`flexcomp` which will then automatically cons
|
|||||||
|
|
||||||
.. _deformable-flex-texcoord:
|
.. _deformable-flex-texcoord:
|
||||||
|
|
||||||
:at:`texcoord`: :at-val:`real(2*nvert), optional`
|
:at:`texcoord`: :at-val:`real(2*vert or ntexcoord), optional`
|
||||||
Texture coordinates for each vertex. If omitted, texture mapping for this flex is disabled, even if a texture is
|
Texture coordinates. If omitted, texture mapping for this flex is disabled, even if a texture is specified in the
|
||||||
specified in the material.
|
material.
|
||||||
|
|
||||||
|
.. _deformable-flex-facetexcoord:
|
||||||
|
|
||||||
|
:at:`facetexcoord`: :at-val:`int((dim+1)*nelem), optional`
|
||||||
|
Texture indices for each face. If omitted, texture are assumed to be vertex-based.
|
||||||
|
|
||||||
.. _deformable-flex-element:
|
.. _deformable-flex-element:
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -485,7 +485,9 @@
|
|||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`material<deformable-flex-material>` | :ref:`rgba<deformable-flex-rgba>` | :ref:`flatskin<deformable-flex-flatskin>` | :ref:`body<deformable-flex-body>` | |
|
| | | | :ref:`material<deformable-flex-material>` | :ref:`rgba<deformable-flex-rgba>` | :ref:`flatskin<deformable-flex-flatskin>` | :ref:`body<deformable-flex-body>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`vertex<deformable-flex-vertex>` | :ref:`element<deformable-flex-element>` | :ref:`texcoord<deformable-flex-texcoord>` | :ref:`node<deformable-flex-node>` | |
|
| | | | :ref:`vertex<deformable-flex-vertex>` | :ref:`element<deformable-flex-element>` | :ref:`texcoord<deformable-flex-texcoord>` | :ref:`facetexcoord<deformable-flex-facetexcoord>` | |
|
||||||
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
|
| | | | :ref:`node<deformable-flex-node>` | | | | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |_2| flex |br| |_2| |L| | | .. table:: |
|
| |_2| flex |br| |_2| |L| | | .. table:: |
|
||||||
|
|||||||
@@ -1177,6 +1177,7 @@ struct mjModel_ {
|
|||||||
int* flex_vertbodyid; // vertex body ids (nflexvert x 1)
|
int* flex_vertbodyid; // vertex body ids (nflexvert x 1)
|
||||||
int* flex_edge; // edge vertex ids (2 per edge) (nflexedge x 2)
|
int* flex_edge; // edge vertex ids (2 per edge) (nflexedge x 2)
|
||||||
int* flex_elem; // element vertex ids (dim+1 per elem) (nflexelemdata x 1)
|
int* flex_elem; // element vertex ids (dim+1 per elem) (nflexelemdata x 1)
|
||||||
|
int* flex_elemtexcoord; // element texture coordinates (dim+1) (nflexelemdata x 1)
|
||||||
int* flex_elemedge; // element edge ids (nflexelemedge x 1)
|
int* flex_elemedge; // element edge ids (nflexelemedge x 1)
|
||||||
int* flex_elemlayer; // element distance from surface, 3D only (nflexelem x 1)
|
int* flex_elemlayer; // element distance from surface, 3D only (nflexelem x 1)
|
||||||
int* flex_shell; // shell fragment vertex ids (dim per frag) (nflexshelldata x 1)
|
int* flex_shell; // shell fragment vertex ids (dim per frag) (nflexshelldata x 1)
|
||||||
@@ -2009,6 +2010,7 @@ typedef struct mjsFlex_ { // flex specification
|
|||||||
mjDoubleVec* vert; // vertex positions
|
mjDoubleVec* vert; // vertex positions
|
||||||
mjIntVec* elem; // element vertex ids
|
mjIntVec* elem; // element vertex ids
|
||||||
mjFloatVec* texcoord; // vertex texture coordinates
|
mjFloatVec* texcoord; // vertex texture coordinates
|
||||||
|
mjIntVec* facetexcoord; // face texture coordinates
|
||||||
|
|
||||||
// other
|
// other
|
||||||
mjString* info; // message appended to compiler errors
|
mjString* info; // message appended to compiler errors
|
||||||
@@ -2997,6 +2999,7 @@ struct mjvSceneState_ {
|
|||||||
int* flex_vertadr;
|
int* flex_vertadr;
|
||||||
int* flex_vertnum;
|
int* flex_vertnum;
|
||||||
int* flex_elem;
|
int* flex_elem;
|
||||||
|
int* flex_elemtexcoord;
|
||||||
int* flex_elemlayer;
|
int* flex_elemlayer;
|
||||||
int* flex_elemadr;
|
int* flex_elemadr;
|
||||||
int* flex_elemnum;
|
int* flex_elemnum;
|
||||||
|
|||||||
@@ -885,6 +885,7 @@ struct mjModel_ {
|
|||||||
int* flex_vertbodyid; // vertex body ids (nflexvert x 1)
|
int* flex_vertbodyid; // vertex body ids (nflexvert x 1)
|
||||||
int* flex_edge; // edge vertex ids (2 per edge) (nflexedge x 2)
|
int* flex_edge; // edge vertex ids (2 per edge) (nflexedge x 2)
|
||||||
int* flex_elem; // element vertex ids (dim+1 per elem) (nflexelemdata x 1)
|
int* flex_elem; // element vertex ids (dim+1 per elem) (nflexelemdata x 1)
|
||||||
|
int* flex_elemtexcoord; // element texture coordinates (dim+1) (nflexelemdata x 1)
|
||||||
int* flex_elemedge; // element edge ids (nflexelemedge x 1)
|
int* flex_elemedge; // element edge ids (nflexelemedge x 1)
|
||||||
int* flex_elemlayer; // element distance from surface, 3D only (nflexelem x 1)
|
int* flex_elemlayer; // element distance from surface, 3D only (nflexelem x 1)
|
||||||
int* flex_shell; // shell fragment vertex ids (dim per frag) (nflexshelldata x 1)
|
int* flex_shell; // shell fragment vertex ids (dim per frag) (nflexshelldata x 1)
|
||||||
|
|||||||
@@ -446,6 +446,7 @@ typedef struct mjsFlex_ { // flex specification
|
|||||||
mjDoubleVec* vert; // vertex positions
|
mjDoubleVec* vert; // vertex positions
|
||||||
mjIntVec* elem; // element vertex ids
|
mjIntVec* elem; // element vertex ids
|
||||||
mjFloatVec* texcoord; // vertex texture coordinates
|
mjFloatVec* texcoord; // vertex texture coordinates
|
||||||
|
mjIntVec* facetexcoord; // face texture coordinates
|
||||||
|
|
||||||
// other
|
// other
|
||||||
mjString* info; // message appended to compiler errors
|
mjString* info; // message appended to compiler errors
|
||||||
|
|||||||
@@ -523,6 +523,7 @@ struct mjvSceneState_ {
|
|||||||
int* flex_vertadr;
|
int* flex_vertadr;
|
||||||
int* flex_vertnum;
|
int* flex_vertnum;
|
||||||
int* flex_elem;
|
int* flex_elem;
|
||||||
|
int* flex_elemtexcoord;
|
||||||
int* flex_elemlayer;
|
int* flex_elemlayer;
|
||||||
int* flex_elemadr;
|
int* flex_elemadr;
|
||||||
int* flex_elemnum;
|
int* flex_elemnum;
|
||||||
|
|||||||
@@ -350,6 +350,7 @@
|
|||||||
X ( int, flex_vertbodyid, nflexvert, 1 ) \
|
X ( int, flex_vertbodyid, nflexvert, 1 ) \
|
||||||
X ( int, flex_edge, nflexedge, 2 ) \
|
X ( int, flex_edge, nflexedge, 2 ) \
|
||||||
XMJV( int, flex_elem, nflexelemdata, 1 ) \
|
XMJV( int, flex_elem, nflexelemdata, 1 ) \
|
||||||
|
XMJV( int, flex_elemtexcoord, nflexelemdata, 1 ) \
|
||||||
X ( int, flex_elemedge, nflexelemedge, 1 ) \
|
X ( int, flex_elemedge, nflexelemedge, 1 ) \
|
||||||
XMJV( int, flex_elemlayer, nflexelem, 1 ) \
|
XMJV( int, flex_elemlayer, nflexelem, 1 ) \
|
||||||
XMJV( int, flex_shell, nflexshelldata,1 ) \
|
XMJV( int, flex_shell, nflexshelldata,1 ) \
|
||||||
|
|||||||
@@ -2620,6 +2620,14 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
doc='element vertex ids (dim+1 per elem)',
|
doc='element vertex ids (dim+1 per elem)',
|
||||||
array_extent=('nflexelemdata',),
|
array_extent=('nflexelemdata',),
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='flex_elemtexcoord',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='element texture coordinates (dim+1)',
|
||||||
|
array_extent=('nflexelemdata',),
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='flex_elemedge',
|
name='flex_elemedge',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
@@ -7636,6 +7644,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='',
|
doc='',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='flex_elemtexcoord',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='flex_elemlayer',
|
name='flex_elemlayer',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
@@ -10440,6 +10455,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='vertex texture coordinates',
|
doc='vertex texture coordinates',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='facetexcoord',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjIntVec'),
|
||||||
|
),
|
||||||
|
doc='face texture coordinates',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='info',
|
name='info',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
|
|||||||
@@ -2527,15 +2527,16 @@ void mjv_updateActiveFlex(const mjModel* m, mjData* d, mjvScene* scn, const mjvO
|
|||||||
if (dim == 2 || m->flex_elemlayer[m->flex_elemadr[f]+e] == opt->flex_layer) {
|
if (dim == 2 || m->flex_elemlayer[m->flex_elemadr[f]+e] == opt->flex_layer) {
|
||||||
// get element data
|
// get element data
|
||||||
const int* edata = m->flex_elem + m->flex_elemdataadr[f] + e*(dim+1);
|
const int* edata = m->flex_elem + m->flex_elemdataadr[f] + e*(dim+1);
|
||||||
|
const int* tdata = m->flex_elemtexcoord + m->flex_elemdataadr[f] + e*(dim+1);
|
||||||
|
|
||||||
// triangles: two faces per element
|
// triangles: two faces per element
|
||||||
if (dim == 2) {
|
if (dim == 2) {
|
||||||
makeFace(face, normal, radius, vertxpos, nface, edata[0], edata[1], edata[2]);
|
makeFace(face, normal, radius, vertxpos, nface, edata[0], edata[1], edata[2]);
|
||||||
copyTex(texdst, texsrc, nface, edata[0], edata[1], edata[2]);
|
copyTex(texdst, texsrc, nface, tdata[0], tdata[1], tdata[2]);
|
||||||
nface++;
|
nface++;
|
||||||
|
|
||||||
makeFace(face, normal, radius, vertxpos, nface, edata[0], edata[2], edata[1]);
|
makeFace(face, normal, radius, vertxpos, nface, edata[0], edata[2], edata[1]);
|
||||||
copyTex(texdst, texsrc, nface, edata[0], edata[2], edata[1]);
|
copyTex(texdst, texsrc, nface, tdata[0], tdata[2], tdata[1]);
|
||||||
nface++;
|
nface++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2543,22 +2544,22 @@ void mjv_updateActiveFlex(const mjModel* m, mjData* d, mjvScene* scn, const mjvO
|
|||||||
else {
|
else {
|
||||||
makeFace(face, normal, radius, vertxpos,
|
makeFace(face, normal, radius, vertxpos,
|
||||||
nface, edata[0], edata[1], edata[2]);
|
nface, edata[0], edata[1], edata[2]);
|
||||||
copyTex(texdst, texsrc, nface, edata[0], edata[1], edata[2]);
|
copyTex(texdst, texsrc, nface, tdata[0], tdata[1], tdata[2]);
|
||||||
nface++;
|
nface++;
|
||||||
|
|
||||||
makeFace(face, normal, radius, vertxpos,
|
makeFace(face, normal, radius, vertxpos,
|
||||||
nface, edata[0], edata[2], edata[3]);
|
nface, edata[0], edata[2], edata[3]);
|
||||||
copyTex(texdst, texsrc, nface, edata[0], edata[2], edata[3]);
|
copyTex(texdst, texsrc, nface, tdata[0], tdata[2], tdata[3]);
|
||||||
nface++;
|
nface++;
|
||||||
|
|
||||||
makeFace(face, normal, radius, vertxpos,
|
makeFace(face, normal, radius, vertxpos,
|
||||||
nface, edata[0], edata[3], edata[1]);
|
nface, edata[0], edata[3], edata[1]);
|
||||||
copyTex(texdst, texsrc, nface, edata[0], edata[3], edata[1]);
|
copyTex(texdst, texsrc, nface, tdata[0], tdata[3], tdata[1]);
|
||||||
nface++;
|
nface++;
|
||||||
|
|
||||||
makeFace(face, normal, radius, vertxpos,
|
makeFace(face, normal, radius, vertxpos,
|
||||||
nface, edata[1], edata[3], edata[2]);
|
nface, edata[1], edata[3], edata[2]);
|
||||||
copyTex(texdst, texsrc, nface, edata[1], edata[3], edata[2]);
|
copyTex(texdst, texsrc, nface, tdata[1], tdata[3], tdata[2]);
|
||||||
nface++;
|
nface++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2598,13 +2599,14 @@ void mjv_updateActiveFlex(const mjModel* m, mjData* d, mjvScene* scn, const mjvO
|
|||||||
if (dim == 2) {
|
if (dim == 2) {
|
||||||
for (int e=0; e < m->flex_elemnum[f]; e++) {
|
for (int e=0; e < m->flex_elemnum[f]; e++) {
|
||||||
const int* edata = m->flex_elem + m->flex_elemdataadr[f] + e*(dim+1);
|
const int* edata = m->flex_elem + m->flex_elemdataadr[f] + e*(dim+1);
|
||||||
|
const int* tdata = m->flex_elemtexcoord + m->flex_elemdataadr[f] + e*(dim+1);
|
||||||
makeSmooth(face, normal, radius, flg_flat, vertnorm, vertxpos,
|
makeSmooth(face, normal, radius, flg_flat, vertnorm, vertxpos,
|
||||||
nface, edata[0], edata[1], edata[2]);
|
nface, edata[0], edata[1], edata[2]);
|
||||||
copyTex(texdst, texsrc, nface, edata[0], edata[1], edata[2]);
|
copyTex(texdst, texsrc, nface, tdata[0], tdata[1], tdata[2]);
|
||||||
nface++;
|
nface++;
|
||||||
makeSmooth(face, normal, -radius, flg_flat, vertnorm, vertxpos,
|
makeSmooth(face, normal, -radius, flg_flat, vertnorm, vertxpos,
|
||||||
nface, edata[0], edata[2], edata[1]);
|
nface, edata[0], edata[2], edata[1]);
|
||||||
copyTex(texdst, texsrc, nface, edata[0], edata[2], edata[1]);
|
copyTex(texdst, texsrc, nface, tdata[0], tdata[2], tdata[1]);
|
||||||
nface++;
|
nface++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -413,6 +413,7 @@ bool mjCFlexcomp::Make(mjsBody* body, char* error, int error_sz) {
|
|||||||
mjs_setString(pf->name, name.c_str());
|
mjs_setString(pf->name, name.c_str());
|
||||||
mjs_setInt(pf->elem, element.data(), element.size());
|
mjs_setInt(pf->elem, element.data(), element.size());
|
||||||
mjs_setFloat(pf->texcoord, texcoord.data(), texcoord.size());
|
mjs_setFloat(pf->texcoord, texcoord.data(), texcoord.size());
|
||||||
|
mjs_setInt(pf->facetexcoord, facetexcoord.data(), facetexcoord.size());
|
||||||
if (!centered) {
|
if (!centered) {
|
||||||
mjs_setDouble(pf->vert, point.data(), point.size());
|
mjs_setDouble(pf->vert, point.data(), point.size());
|
||||||
}
|
}
|
||||||
@@ -1055,6 +1056,11 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, char* error, int error_sz) {
|
|||||||
point[i] = (double) mesh.Vert(i);
|
point[i] = (double) mesh.Vert(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mesh.HasTexcoord()) {
|
||||||
|
texcoord = mesh.Texcoord();
|
||||||
|
facetexcoord = mesh.FaceTexcoord();
|
||||||
|
}
|
||||||
|
|
||||||
// copy faces or create 3D mesh
|
// copy faces or create 3D mesh
|
||||||
if (def.spec.flex->dim == 2) {
|
if (def.spec.flex->dim == 2) {
|
||||||
element = mesh.Face();
|
element = mesh.Face();
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ class mjCFlexcomp {
|
|||||||
std::vector<bool> used; // is point used by any element (false: skip)
|
std::vector<bool> used; // is point used by any element (false: skip)
|
||||||
std::vector<int> element; // flex elements
|
std::vector<int> element; // flex elements
|
||||||
std::vector<float> texcoord; // vertex texture coordinates
|
std::vector<float> texcoord; // vertex texture coordinates
|
||||||
|
std::vector<int> facetexcoord; // face texture coordinates (OBJ only)
|
||||||
|
|
||||||
// plugin support
|
// plugin support
|
||||||
std::string plugin_name;
|
std::string plugin_name;
|
||||||
|
|||||||
+10
-1
@@ -3184,6 +3184,7 @@ void mjCFlex::PointToLocal() {
|
|||||||
spec.vert = &spec_vert_;
|
spec.vert = &spec_vert_;
|
||||||
spec.node = &spec_node_;
|
spec.node = &spec_node_;
|
||||||
spec.texcoord = &spec_texcoord_;
|
spec.texcoord = &spec_texcoord_;
|
||||||
|
spec.facetexcoord = &spec_facetexcoord_;
|
||||||
spec.elem = &spec_elem_;
|
spec.elem = &spec_elem_;
|
||||||
spec.info = &info;
|
spec.info = &info;
|
||||||
material = nullptr;
|
material = nullptr;
|
||||||
@@ -3192,6 +3193,7 @@ void mjCFlex::PointToLocal() {
|
|||||||
vert = nullptr;
|
vert = nullptr;
|
||||||
node = nullptr;
|
node = nullptr;
|
||||||
texcoord = nullptr;
|
texcoord = nullptr;
|
||||||
|
facetexcoord = nullptr;
|
||||||
elem = nullptr;
|
elem = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3217,6 +3219,7 @@ void mjCFlex::CopyFromSpec() {
|
|||||||
vert_ = spec_vert_;
|
vert_ = spec_vert_;
|
||||||
node_ = spec_node_;
|
node_ = spec_node_;
|
||||||
texcoord_ = spec_texcoord_;
|
texcoord_ = spec_texcoord_;
|
||||||
|
facetexcoord_ = spec_facetexcoord_;
|
||||||
elem_ = spec_elem_;
|
elem_ = spec_elem_;
|
||||||
|
|
||||||
// clear precompiled asset. TODO: use asset cache
|
// clear precompiled asset. TODO: use asset cache
|
||||||
@@ -3320,10 +3323,16 @@ void mjCFlex::Compile(const mjVFS* vfs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check texcoord
|
// check texcoord
|
||||||
if (!texcoord_.empty() && texcoord_.size()!=2*nvert) {
|
if (!texcoord_.empty() && texcoord_.size()!=2*nvert && facetexcoord_.empty()) {
|
||||||
throw mjCError(this, "two texture coordinates per vertex expected");
|
throw mjCError(this, "two texture coordinates per vertex expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no facetexcoord: copy from faces
|
||||||
|
if (facetexcoord_.empty() && !texcoord_.empty()) {
|
||||||
|
facetexcoord_.assign(3*nelem, 0);
|
||||||
|
memcpy(facetexcoord_.data(), elem_.data(), 3*nelem*sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
// resolve material name
|
// resolve material name
|
||||||
mjCBase* pmat = model->FindObject(mjOBJ_MATERIAL, material_);
|
mjCBase* pmat = model->FindObject(mjOBJ_MATERIAL, material_);
|
||||||
if (pmat) {
|
if (pmat) {
|
||||||
|
|||||||
@@ -2911,10 +2911,13 @@ void mjCModel::CopyObjects(mjModel* m) {
|
|||||||
}
|
}
|
||||||
if (pfl->texcoord_.empty()) {
|
if (pfl->texcoord_.empty()) {
|
||||||
m->flex_texcoordadr[i] = -1;
|
m->flex_texcoordadr[i] = -1;
|
||||||
|
memcpy(m->flex_elemtexcoord + elemdata_adr, pfl->elem_.data(), pfl->elem_.size()*sizeof(int));
|
||||||
} else {
|
} else {
|
||||||
m->flex_texcoordadr[i] = texcoord_adr;
|
m->flex_texcoordadr[i] = texcoord_adr;
|
||||||
memcpy(m->flex_texcoord + 2*texcoord_adr,
|
memcpy(m->flex_texcoord + 2*texcoord_adr,
|
||||||
pfl->texcoord_.data(), pfl->texcoord_.size()*sizeof(float));
|
pfl->texcoord_.data(), pfl->texcoord_.size()*sizeof(float));
|
||||||
|
memcpy(m->flex_elemtexcoord + elemdata_adr, pfl->facetexcoord_.data(),
|
||||||
|
pfl->facetexcoord_.size()*sizeof(int));
|
||||||
}
|
}
|
||||||
m->flex_elemnum[i] = pfl->nelem;
|
m->flex_elemnum[i] = pfl->nelem;
|
||||||
memcpy(m->flex_elem + elemdata_adr, pfl->elem_.data(), pfl->elem_.size()*sizeof(int));
|
memcpy(m->flex_elem + elemdata_adr, pfl->elem_.data(), pfl->elem_.size()*sizeof(int));
|
||||||
|
|||||||
@@ -776,6 +776,7 @@ class mjCFlex_ : public mjCBase {
|
|||||||
std::vector<double> node_; // node positions
|
std::vector<double> node_; // node positions
|
||||||
std::vector<int> elem_; // element vertex ids
|
std::vector<int> elem_; // element vertex ids
|
||||||
std::vector<float> texcoord_; // vertex texture coordinates
|
std::vector<float> texcoord_; // vertex texture coordinates
|
||||||
|
std::vector<int> facetexcoord_; // face texture coordinates (OBJ only)
|
||||||
std::string material_; // name of material used for rendering
|
std::string material_; // name of material used for rendering
|
||||||
|
|
||||||
std::string spec_material_;
|
std::string spec_material_;
|
||||||
@@ -785,6 +786,7 @@ class mjCFlex_ : public mjCBase {
|
|||||||
std::vector<double> spec_node_;
|
std::vector<double> spec_node_;
|
||||||
std::vector<int> spec_elem_;
|
std::vector<int> spec_elem_;
|
||||||
std::vector<float> spec_texcoord_;
|
std::vector<float> spec_texcoord_;
|
||||||
|
std::vector<int> spec_facetexcoord_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class mjCFlex: public mjCFlex_, private mjsFlex {
|
class mjCFlex: public mjCFlex_, private mjsFlex {
|
||||||
@@ -815,6 +817,7 @@ class mjCFlex: public mjCFlex_, private mjsFlex {
|
|||||||
const std::vector<double>& get_elemaabb() const { return elemaabb_; }
|
const std::vector<double>& get_elemaabb() const { return elemaabb_; }
|
||||||
const std::vector<int>& get_elem() const { return elem_; }
|
const std::vector<int>& get_elem() const { return elem_; }
|
||||||
const std::vector<float>& get_texcoord() const { return texcoord_; }
|
const std::vector<float>& get_texcoord() const { return texcoord_; }
|
||||||
|
const std::vector<int>& get_facetexcoord() const { return facetexcoord_; }
|
||||||
const std::vector<std::string>& get_nodebody() const { return nodebody_; }
|
const std::vector<std::string>& get_nodebody() const { return nodebody_; }
|
||||||
|
|
||||||
bool HasTexcoord() const; // texcoord not null
|
bool HasTexcoord() const; // texcoord not null
|
||||||
@@ -927,6 +930,8 @@ class mjCMesh: public mjCMesh_, private mjsMesh {
|
|||||||
float Vert(int i) const { return vert_[i]; }
|
float Vert(int i) const { return vert_[i]; }
|
||||||
const std::vector<float>& UserVert() const { return spec_vert_; }
|
const std::vector<float>& UserVert() const { return spec_vert_; }
|
||||||
const std::vector<float>& UserNormal() const { return spec_normal_; }
|
const std::vector<float>& UserNormal() const { return spec_normal_; }
|
||||||
|
const std::vector<float>& Texcoord() const { return texcoord_; }
|
||||||
|
const std::vector<int>& FaceTexcoord() const { return facetexcoord_; }
|
||||||
const std::vector<float>& UserTexcoord() const { return spec_texcoord_; }
|
const std::vector<float>& UserTexcoord() const { return spec_texcoord_; }
|
||||||
const std::vector<int>& Face() const { return face_; }
|
const std::vector<int>& Face() const { return face_; }
|
||||||
const std::vector<int>& UserFace() const { return spec_face_; }
|
const std::vector<int>& UserFace() const { return spec_face_; }
|
||||||
|
|||||||
@@ -324,8 +324,8 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
|
|||||||
|
|
||||||
{"deformable", "*", "0"},
|
{"deformable", "*", "0"},
|
||||||
{"<"},
|
{"<"},
|
||||||
{"flex", "*", "12", "name", "group", "dim", "radius", "material",
|
{"flex", "*", "13", "name", "group", "dim", "radius", "material",
|
||||||
"rgba", "flatskin", "body", "vertex", "element", "texcoord", "node"},
|
"rgba", "flatskin", "body", "vertex", "element", "texcoord", "facetexcoord", "node"},
|
||||||
{"<"},
|
{"<"},
|
||||||
{"contact", "?", "13", "contype", "conaffinity", "condim", "priority",
|
{"contact", "?", "13", "contype", "conaffinity", "condim", "priority",
|
||||||
"friction", "solmix", "solref", "solimp", "margin", "gap",
|
"friction", "solmix", "solref", "solimp", "margin", "gap",
|
||||||
@@ -1354,6 +1354,10 @@ void mjXReader::OneFlex(XMLElement* elem, mjsFlex* flex) {
|
|||||||
if (texcoord.has_value()) {
|
if (texcoord.has_value()) {
|
||||||
mjs_setFloat(flex->texcoord, texcoord->data(), texcoord->size());
|
mjs_setFloat(flex->texcoord, texcoord->data(), texcoord->size());
|
||||||
}
|
}
|
||||||
|
auto facetexcoord = ReadAttrVec<int>(elem, "facetexcoord");
|
||||||
|
if (facetexcoord.has_value()) {
|
||||||
|
mjs_setInt(flex->facetexcoord, facetexcoord->data(), facetexcoord->size());
|
||||||
|
}
|
||||||
|
|
||||||
// contact subelement
|
// contact subelement
|
||||||
XMLElement* cont = FirstChildElement(elem, "contact");
|
XMLElement* cont = FirstChildElement(elem, "contact");
|
||||||
|
|||||||
@@ -158,6 +158,10 @@ void mjXWriter::OneFlex(XMLElement* elem, const mjCFlex* flex) {
|
|||||||
text = VectorToString(flex->get_texcoord());
|
text = VectorToString(flex->get_texcoord());
|
||||||
WriteAttrTxt(elem, "texcoord", text);
|
WriteAttrTxt(elem, "texcoord", text);
|
||||||
}
|
}
|
||||||
|
if (!flex->get_facetexcoord().empty()) {
|
||||||
|
text = VectorToString(flex->get_facetexcoord());
|
||||||
|
WriteAttrTxt(elem, "facetexcoord", text);
|
||||||
|
}
|
||||||
if (!flex->get_nodebody().empty()) {
|
if (!flex->get_nodebody().empty()) {
|
||||||
text = VectorToString(flex->get_nodebody());
|
text = VectorToString(flex->get_nodebody());
|
||||||
WriteAttrTxt(elem, "node", text);
|
WriteAttrTxt(elem, "node", text);
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
<mujoco>
|
||||||
|
<compiler assetdir="textured_torus"/>
|
||||||
|
<asset>
|
||||||
|
<texture file="carpet.png" type="2d"/>
|
||||||
|
<material name="carpet" texture="carpet"/>
|
||||||
|
</asset>
|
||||||
|
<worldbody>
|
||||||
|
<flexcomp name="torus" type="mesh" file="textured_torus.obj"
|
||||||
|
radius="0.01" dim="2" material="carpet">
|
||||||
|
<contact internal="false" selfcollide="none"/>
|
||||||
|
<edge equality="true" />
|
||||||
|
</flexcomp>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
@@ -435,6 +435,22 @@ TEST_F(UserFlexTest, StiffnessMatrix) {
|
|||||||
mj_deleteModel(m);
|
mj_deleteModel(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(UserFlexTest, LoadTexture) {
|
||||||
|
const std::string xml_path =
|
||||||
|
GetTestDataFilePath("user/testdata/textured_torus_flex.xml");
|
||||||
|
std::array<char, 1024> error;
|
||||||
|
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||||
|
ASSERT_THAT(m, NotNull()) << error.data();
|
||||||
|
EXPECT_THAT(m->nflextexcoord, 637);
|
||||||
|
EXPECT_THAT(m->flex_elemtexcoord[0], 0);
|
||||||
|
EXPECT_THAT(m->flex_elemtexcoord[1], 1);
|
||||||
|
EXPECT_THAT(m->flex_elemtexcoord[2], 2);
|
||||||
|
EXPECT_THAT(m->flex_elemtexcoord[3], 0);
|
||||||
|
EXPECT_THAT(m->flex_elemtexcoord[4], 2);
|
||||||
|
EXPECT_THAT(m->flex_elemtexcoord[5], 3);
|
||||||
|
mj_deleteModel(m);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(UserFlexTest, LoadMSHBinary_41_Success) {
|
TEST_F(UserFlexTest, LoadMSHBinary_41_Success) {
|
||||||
const std::string xml_path =
|
const std::string xml_path =
|
||||||
GetTestDataFilePath("user/testdata/cube_41_binary_vol_gmshApp.xml");
|
GetTestDataFilePath("user/testdata/cube_41_binary_vol_gmshApp.xml");
|
||||||
|
|||||||
@@ -5437,6 +5437,7 @@ public unsafe struct mjModel_ {
|
|||||||
public int* flex_vertbodyid;
|
public int* flex_vertbodyid;
|
||||||
public int* flex_edge;
|
public int* flex_edge;
|
||||||
public int* flex_elem;
|
public int* flex_elem;
|
||||||
|
public int* flex_elemtexcoord;
|
||||||
public int* flex_elemedge;
|
public int* flex_elemedge;
|
||||||
public int* flex_elemlayer;
|
public int* flex_elemlayer;
|
||||||
public int* flex_shell;
|
public int* flex_shell;
|
||||||
@@ -6324,6 +6325,7 @@ public unsafe struct model {
|
|||||||
public int* flex_vertadr;
|
public int* flex_vertadr;
|
||||||
public int* flex_vertnum;
|
public int* flex_vertnum;
|
||||||
public int* flex_elem;
|
public int* flex_elem;
|
||||||
|
public int* flex_elemtexcoord;
|
||||||
public int* flex_elemlayer;
|
public int* flex_elemlayer;
|
||||||
public int* flex_elemadr;
|
public int* flex_elemadr;
|
||||||
public int* flex_elemnum;
|
public int* flex_elemnum;
|
||||||
|
|||||||
Reference in New Issue
Block a user