Add mjModel.mesh_scale: scaling applied to asset vertices.
PiperOrigin-RevId: 625083195 Change-Id: I36290282379e57ad23ec771d65d1bd6bf2a75b07
This commit is contained in:
committed by
Copybara-Service
parent
9f1651b7bd
commit
7b3f1a0261
@@ -2,6 +2,15 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
Upcoming version (not yet released)
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
General
|
||||||
|
^^^^^^^
|
||||||
|
1. Added `mjModel.mesh_scale`: the scaling applied to asset vertices, as specified in the :ref:`scale<asset-mesh-scale>`
|
||||||
|
attribute.
|
||||||
|
|
||||||
|
|
||||||
Version 3.1.4 (April 10th, 2024)
|
Version 3.1.4 (April 10th, 2024)
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -1165,6 +1165,7 @@ struct mjModel_ {
|
|||||||
int* mesh_facenormal; // normal face data (nmeshface x 3)
|
int* mesh_facenormal; // normal face data (nmeshface x 3)
|
||||||
int* mesh_facetexcoord; // texture face data (nmeshface x 3)
|
int* mesh_facetexcoord; // texture face data (nmeshface x 3)
|
||||||
int* mesh_graph; // convex graph data (nmeshgraph x 1)
|
int* mesh_graph; // convex graph data (nmeshgraph x 1)
|
||||||
|
mjtNum* mesh_scale; // scaling applied to asset vertices (nmesh x 3)
|
||||||
mjtNum* mesh_pos; // translation applied to asset vertices (nmesh x 3)
|
mjtNum* mesh_pos; // translation applied to asset vertices (nmesh x 3)
|
||||||
mjtNum* mesh_quat; // rotation applied to asset vertices (nmesh x 4)
|
mjtNum* mesh_quat; // rotation applied to asset vertices (nmesh x 4)
|
||||||
int* mesh_pathadr; // address of asset path for mesh; -1: none (nmesh x 1)
|
int* mesh_pathadr; // address of asset path for mesh; -1: none (nmesh x 1)
|
||||||
|
|||||||
@@ -880,6 +880,7 @@ struct mjModel_ {
|
|||||||
int* mesh_facenormal; // normal face data (nmeshface x 3)
|
int* mesh_facenormal; // normal face data (nmeshface x 3)
|
||||||
int* mesh_facetexcoord; // texture face data (nmeshface x 3)
|
int* mesh_facetexcoord; // texture face data (nmeshface x 3)
|
||||||
int* mesh_graph; // convex graph data (nmeshgraph x 1)
|
int* mesh_graph; // convex graph data (nmeshgraph x 1)
|
||||||
|
mjtNum* mesh_scale; // scaling applied to asset vertices (nmesh x 3)
|
||||||
mjtNum* mesh_pos; // translation applied to asset vertices (nmesh x 3)
|
mjtNum* mesh_pos; // translation applied to asset vertices (nmesh x 3)
|
||||||
mjtNum* mesh_quat; // rotation applied to asset vertices (nmesh x 4)
|
mjtNum* mesh_quat; // rotation applied to asset vertices (nmesh x 4)
|
||||||
int* mesh_pathadr; // address of asset path for mesh; -1: none (nmesh x 1)
|
int* mesh_pathadr; // address of asset path for mesh; -1: none (nmesh x 1)
|
||||||
|
|||||||
@@ -365,6 +365,7 @@
|
|||||||
XMJV( int, mesh_bvhadr, nmesh, 1 ) \
|
XMJV( int, mesh_bvhadr, nmesh, 1 ) \
|
||||||
XMJV( int, mesh_bvhnum, nmesh, 1 ) \
|
XMJV( int, mesh_bvhnum, nmesh, 1 ) \
|
||||||
XMJV( int, mesh_graphadr, nmesh, 1 ) \
|
XMJV( int, mesh_graphadr, nmesh, 1 ) \
|
||||||
|
X ( mjtNum, mesh_scale, nmesh, 3 ) \
|
||||||
X ( mjtNum, mesh_pos, nmesh, 3 ) \
|
X ( mjtNum, mesh_pos, nmesh, 3 ) \
|
||||||
X ( mjtNum, mesh_quat, nmesh, 4 ) \
|
X ( mjtNum, mesh_quat, nmesh, 4 ) \
|
||||||
X ( float, mesh_vert, nmeshvert, 3 ) \
|
X ( float, mesh_vert, nmeshvert, 3 ) \
|
||||||
|
|||||||
@@ -2655,6 +2655,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='convex graph data (nmeshgraph x 1)', # pylint: disable=line-too-long
|
doc='convex graph data (nmeshgraph x 1)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mesh_scale',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjtNum'),
|
||||||
|
),
|
||||||
|
doc='scaling applied to asset vertices (nmesh x 3)',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='mesh_pos',
|
name='mesh_pos',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
|
|||||||
@@ -534,11 +534,15 @@ mjModel* mj_makeModel(
|
|||||||
m->nuser_actuator = nuser_actuator;
|
m->nuser_actuator = nuser_actuator;
|
||||||
m->nuser_sensor = nuser_sensor;
|
m->nuser_sensor = nuser_sensor;
|
||||||
m->nnames = nnames;
|
m->nnames = nnames;
|
||||||
m->nnames_map = mjLOAD_MULTIPLE
|
long nnames_map = (long)nbody + njnt + ngeom + nsite + ncam + nlight + nflex + nmesh + nskin +
|
||||||
* (nbody + njnt + ngeom + nsite + ncam + nlight + nflex + nmesh
|
nhfield + ntex + nmat + npair + nexclude + neq + ntendon + nu + nsensor +
|
||||||
+ nskin + nhfield + ntex + nmat + npair + nexclude + neq
|
nnumeric + ntext + ntuple + nkey + nplugin;
|
||||||
+ ntendon + nu + nsensor + nnumeric + ntext + ntuple
|
if (nnames_map >= INT_MAX / mjLOAD_MULTIPLE) {
|
||||||
+ nkey + nplugin);
|
mju_free(m);
|
||||||
|
mju_warning("Invalid model: size of nnames_map is larger than INT_MAX");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
m->nnames_map = mjLOAD_MULTIPLE * nnames_map;
|
||||||
m->npaths = npaths;
|
m->npaths = npaths;
|
||||||
|
|
||||||
#define X(name) \
|
#define X(name) \
|
||||||
|
|||||||
@@ -2123,6 +2123,7 @@ void mjCModel::CopyObjects(mjModel* m) {
|
|||||||
m->mesh_graphadr[i] = (pme->szgraph() ? graph_adr : -1);
|
m->mesh_graphadr[i] = (pme->szgraph() ? graph_adr : -1);
|
||||||
m->mesh_bvhnum[i] = pme->tree().nbvh;
|
m->mesh_bvhnum[i] = pme->tree().nbvh;
|
||||||
m->mesh_bvhadr[i] = pme->tree().nbvh ? bvh_adr : -1;
|
m->mesh_bvhadr[i] = pme->tree().nbvh ? bvh_adr : -1;
|
||||||
|
copyvec(&m->mesh_scale[3 * i], pme->get_scale(), 3);
|
||||||
copyvec(&m->mesh_pos[3 * i], pme->GetOffsetPosPtr(), 3);
|
copyvec(&m->mesh_pos[3 * i], pme->GetOffsetPosPtr(), 3);
|
||||||
copyvec(&m->mesh_quat[4 * i], pme->GetOffsetQuatPtr(), 4);
|
copyvec(&m->mesh_quat[4 * i], pme->GetOffsetQuatPtr(), 4);
|
||||||
|
|
||||||
|
|||||||
@@ -815,12 +815,12 @@ class mjCMesh: public mjCMesh_, private mjsMesh {
|
|||||||
const mjCBoundingVolumeHierarchy& tree() { return tree_; }
|
const mjCBoundingVolumeHierarchy& tree() { return tree_; }
|
||||||
|
|
||||||
void Compile(const mjVFS* vfs); // compiler
|
void Compile(const mjVFS* vfs); // compiler
|
||||||
double* GetPosPtr(mjtGeomInertia type); // get position
|
double* GetPosPtr(mjtGeomInertia type); // get position
|
||||||
double* GetQuatPtr(mjtGeomInertia type); // get orientation
|
double* GetQuatPtr(mjtGeomInertia type); // get orientation
|
||||||
double* GetOffsetPosPtr(); // get position offset for geom
|
double* GetOffsetPosPtr(); // get position offset for geom
|
||||||
double* GetOffsetQuatPtr(); // get orientation offset for geom
|
double* GetOffsetQuatPtr(); // get orientation offset for geom
|
||||||
double* GetInertiaBoxPtr(mjtGeomInertia type); // get inertia box
|
double* GetInertiaBoxPtr(mjtGeomInertia type); // get inertia box
|
||||||
double& GetVolumeRef(mjtGeomInertia type); // get volume
|
double& GetVolumeRef(mjtGeomInertia type); // get volume
|
||||||
void FitGeom(mjCGeom* geom, double* meshpos); // approximate mesh with simple geom
|
void FitGeom(mjCGeom* geom, double* meshpos); // approximate mesh with simple geom
|
||||||
bool HasTexcoord() const; // texcoord not null
|
bool HasTexcoord() const; // texcoord not null
|
||||||
void DelTexcoord(); // delete texcoord
|
void DelTexcoord(); // delete texcoord
|
||||||
@@ -852,7 +852,7 @@ class mjCMesh: public mjCMesh_, private mjsMesh {
|
|||||||
void ApplyTransformations(); // apply user transformations
|
void ApplyTransformations(); // apply user transformations
|
||||||
void ComputeFaceCentroid(double[3]); // compute centroid of all faces
|
void ComputeFaceCentroid(double[3]); // compute centroid of all faces
|
||||||
void RemoveRepeated(void); // remove repeated vertices
|
void RemoveRepeated(void); // remove repeated vertices
|
||||||
void CheckMesh(mjtGeomInertia type); // check if the mesh is valid
|
void CheckMesh(mjtGeomInertia type); // check if the mesh is valid
|
||||||
|
|
||||||
// mesh data to be copied into mjModel
|
// mesh data to be copied into mjModel
|
||||||
float* vert_; // vertex data (3*nvert), relative to (pos, quat)
|
float* vert_; // vertex data (3*nvert), relative to (pos, quat)
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ static const char* const kDuplicateOBJPath =
|
|||||||
static const char* const kMalformedFaceOBJPath =
|
static const char* const kMalformedFaceOBJPath =
|
||||||
"user/testdata/malformed_face.xml";
|
"user/testdata/malformed_face.xml";
|
||||||
|
|
||||||
|
std::vector<mjtNum> AsVector(const mjtNum* array, int n) {
|
||||||
|
return std::vector<mjtNum>(array, array + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
using ::testing::ElementsAre;
|
||||||
using ::testing::HasSubstr;
|
using ::testing::HasSubstr;
|
||||||
using ::testing::IsNull;
|
using ::testing::IsNull;
|
||||||
using ::testing::NotNull;
|
using ::testing::NotNull;
|
||||||
@@ -863,6 +868,27 @@ TEST_F(MjCMeshTest, MeshPosQuat) {
|
|||||||
mj_deleteModel(model);
|
mj_deleteModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(MjCMeshTest, MeshScale) {
|
||||||
|
static constexpr char xml[] = R"(
|
||||||
|
<mujoco>
|
||||||
|
<asset>
|
||||||
|
<mesh name="pyramid" vertex="0 0 0 1 0 0 0 1 0 0 0 1"/>
|
||||||
|
<mesh name="pyramid_scaled" vertex="0 0 0 1 0 0 0 1 0 0 0 1" scale="0.9 1 -1"/>
|
||||||
|
</asset>
|
||||||
|
<worldbody>
|
||||||
|
<geom type="mesh" name="geom1" mesh="pyramid"/>
|
||||||
|
<geom type="mesh" name="geom2" mesh="pyramid_scaled"/>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
|
)";
|
||||||
|
mjModel* model = LoadModelFromString(xml);
|
||||||
|
ASSERT_THAT(model, NotNull());
|
||||||
|
|
||||||
|
EXPECT_THAT(AsVector(model->mesh_scale + 0, 3), ElementsAre(1, 1, 1));
|
||||||
|
EXPECT_THAT(AsVector(model->mesh_scale + 3, 3), ElementsAre(0.9, 1, -1));
|
||||||
|
mj_deleteModel(model);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------- texcoord -------------------------------------
|
// ----------------------------- texcoord -------------------------------------
|
||||||
|
|
||||||
TEST_F(MjCMeshTest, CreateFaceTexCoord) {
|
TEST_F(MjCMeshTest, CreateFaceTexCoord) {
|
||||||
|
|||||||
@@ -5374,6 +5374,7 @@ public unsafe struct mjModel_ {
|
|||||||
public int* mesh_facenormal;
|
public int* mesh_facenormal;
|
||||||
public int* mesh_facetexcoord;
|
public int* mesh_facetexcoord;
|
||||||
public int* mesh_graph;
|
public int* mesh_graph;
|
||||||
|
public double* mesh_scale;
|
||||||
public double* mesh_pos;
|
public double* mesh_pos;
|
||||||
public double* mesh_quat;
|
public double* mesh_quat;
|
||||||
public int* mesh_pathadr;
|
public int* mesh_pathadr;
|
||||||
|
|||||||
Reference in New Issue
Block a user