Add maxhullvert.
PiperOrigin-RevId: 641092710 Change-Id: Ib4fa828a9c82531614f0a67de9990340dbb25406
This commit is contained in:
committed by
Copybara-Service
parent
fb8bf206d9
commit
ace0c8f0a3
@@ -1233,6 +1233,13 @@ The full list of processing steps applied by the compiler to each mesh is as fol
|
||||
faces at large angles relative to the average normal are excluded from the average. In this way, sharp edges (as in
|
||||
cube edges) are not smoothed.
|
||||
|
||||
.. _asset-mesh-maxhullvert:
|
||||
|
||||
:at:`maxhullvert`: :at-val:`int, "-1"`
|
||||
Maximum number of vertices in a mesh's convex hull. Currently this is implemented by asking qhull
|
||||
`to teminate <http://www.qhull.org/html/qh-optt.htm#TAn>`__ after :at:`maxhullvert` vertices. The default
|
||||
value of -1 means "unlimited". Positive values must be larger than 3.
|
||||
|
||||
.. _asset-mesh-vertex:
|
||||
|
||||
:at:`vertex`: :at-val:`real(3*nvert), optional`
|
||||
@@ -7666,6 +7673,8 @@ if omitted.
|
||||
|
||||
.. _default-mesh-scale:
|
||||
|
||||
.. _default-mesh-maxhullvert:
|
||||
|
||||
:el-prefix:`default/` |-| **mesh** (?)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
+3
-1
@@ -103,6 +103,8 @@
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`refpos<asset-mesh-refpos>` | :ref:`refquat<asset-mesh-refquat>` | :ref:`scale<asset-mesh-scale>` | :ref:`smoothnormal<asset-mesh-smoothnormal>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`maxhullvert<asset-mesh-maxhullvert>` | | | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |_2| mesh |br| |_2| |L| | | .. table:: |
|
||||
| :ref:`plugin | \* | :class: mjcf-attributes |
|
||||
@@ -1325,7 +1327,7 @@
|
||||
| :ref:`mesh | ? | :class: mjcf-attributes |
|
||||
| <default-mesh>` | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`scale<default-mesh-scale>` | | | | |
|
||||
| | | | :ref:`scale<default-mesh-scale>` | :ref:`maxhullvert<default-mesh-maxhullvert>` | | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |_| default |br| |_| |L| | | .. table:: |
|
||||
|
||||
@@ -2,6 +2,15 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Upcoming version (not yet released)
|
||||
-----------------------------------
|
||||
|
||||
General
|
||||
^^^^^^^
|
||||
|
||||
1. Added :ref:`maxhullvert<asset-mesh-maxhullvert>`, the maximum number of vertices in a mesh's convex hull.
|
||||
|
||||
|
||||
Version 3.1.6 (Jun 3, 2024)
|
||||
---------------------------
|
||||
|
||||
|
||||
@@ -446,6 +446,7 @@ typedef struct mjsMesh_ { // mesh specification
|
||||
double refquat[4]; // reference orientation
|
||||
double scale[3]; // rescale mesh
|
||||
mjtByte smoothnormal; // do not exclude large-angle faces from normals
|
||||
int maxhullvert; // maximum vertex count for the convex hull
|
||||
mjFloatVec* uservert; // user vertex data
|
||||
mjFloatVec* usernormal; // user normal data
|
||||
mjFloatVec* usertexcoord; // user texcoord data
|
||||
|
||||
@@ -243,6 +243,7 @@ void mjs_defaultMesh(mjsMesh* mesh) {
|
||||
memset(mesh, 0, sizeof(mjsMesh));
|
||||
mesh->refquat[0] = 1;
|
||||
mesh->scale[0] = mesh->scale[1] = mesh->scale[2] = 1;
|
||||
mesh->maxhullvert = -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+11
-6
@@ -50,8 +50,8 @@
|
||||
|
||||
#include <mujoco/mjmacro.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
#include <mujoco/mjplugin.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
#include "engine/engine_crossplatform.h"
|
||||
#include "engine/engine_io.h"
|
||||
#include "engine/engine_plugin.h"
|
||||
@@ -135,6 +135,7 @@ mjCMesh::mjCMesh(mjCModel* _model, mjCDef* _def) {
|
||||
center_ = NULL;
|
||||
graph_ = NULL;
|
||||
needhull_ = false;
|
||||
maxhullvert_ = -1;
|
||||
invalidorientation_.first = -1;
|
||||
invalidorientation_.second = -1;
|
||||
validarea_ = true;
|
||||
@@ -223,6 +224,7 @@ void mjCMesh::CopyFromSpec() {
|
||||
facetexcoord_ = spec_facetexcoord_;
|
||||
file = &file_;
|
||||
content_type = &content_type_;
|
||||
maxhullvert_ = spec.maxhullvert;
|
||||
uservert = &vert_;
|
||||
usernormal = &normal_;
|
||||
userface = &face_;
|
||||
@@ -1548,12 +1550,17 @@ double& mjCMesh::GetVolumeRef(mjtGeomInertia type) {
|
||||
|
||||
|
||||
// make graph describing convex hull
|
||||
void mjCMesh::MakeGraph(void) {
|
||||
void mjCMesh::MakeGraph() {
|
||||
int adr, ok, curlong, totlong, exitcode;
|
||||
double* data;
|
||||
facetT* facet, **facetp;
|
||||
vertexT* vertex, *vertex1, **vertex1p;
|
||||
char qhopt[10] = "qhull Qt";
|
||||
|
||||
std::string qhopt = "qhull Qt";
|
||||
if (maxhullvert_ > -1) {
|
||||
// qhull "TA" actually means "number of vertices added after the initial simplex"
|
||||
qhopt += " TA" + std::to_string(maxhullvert_ - 4);
|
||||
}
|
||||
|
||||
// graph not needed for small meshes
|
||||
if (nvert() < 4) {
|
||||
@@ -1585,7 +1592,7 @@ void mjCMesh::MakeGraph(void) {
|
||||
qh->NOerrexit = false;
|
||||
if (!exitcode) {
|
||||
// actual init
|
||||
qh_initflags(qh, qhopt);
|
||||
qh_initflags(qh, const_cast<char*>(qhopt.c_str()));
|
||||
qh_init_B(qh, data, nvert(), 3, False);
|
||||
|
||||
// construct convex hull
|
||||
@@ -1742,8 +1749,6 @@ void mjCMesh::MakeGraph(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// copy graph into face data
|
||||
void mjCMesh::CopyGraph(void) {
|
||||
// only if face data is missing
|
||||
|
||||
@@ -778,6 +778,7 @@ class mjCMesh_ : public mjCBase {
|
||||
// size of mesh data to be copied into mjModel
|
||||
int szgraph_; // size of graph data in ints
|
||||
bool needhull_; // needs convex hull for collisions
|
||||
int maxhullvert_; // max vertex count of convex hull
|
||||
|
||||
mjCBoundingVolumeHierarchy tree_; // bounding volume hierarchy
|
||||
std::vector<double> face_aabb_; // bounding boxes of all faces
|
||||
|
||||
@@ -145,7 +145,7 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||
|
||||
{"default", "R", "1", "class"},
|
||||
{"<"},
|
||||
{"mesh", "?", "1", "scale"},
|
||||
{"mesh", "?", "2", "scale", "maxhullvert"},
|
||||
{"material", "?", "10", "texture", "emission", "specular", "shininess",
|
||||
"reflectance", "metallic", "roughness", "rgba", "texrepeat", "texuniform"},
|
||||
{"joint", "?", "22", "type", "group", "pos", "axis", "springdamper",
|
||||
@@ -221,8 +221,9 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||
|
||||
{"asset", "*", "0"},
|
||||
{"<"},
|
||||
{"mesh", "*", "12", "name", "class", "content_type", "file", "vertex", "normal",
|
||||
"texcoord", "face", "refpos", "refquat", "scale", "smoothnormal"},
|
||||
{"mesh", "*", "13", "name", "class", "content_type", "file", "vertex", "normal",
|
||||
"texcoord", "face", "refpos", "refquat", "scale", "smoothnormal",
|
||||
"maxhullvert"},
|
||||
{"<"},
|
||||
{"plugin", "*", "2", "plugin", "instance"},
|
||||
{"<"},
|
||||
@@ -1391,6 +1392,11 @@ void mjXReader::OneMesh(XMLElement* elem, mjsMesh* pmesh) {
|
||||
pmesh->smoothnormal = (n==1);
|
||||
}
|
||||
|
||||
if (ReadAttrInt(elem, "maxhullvert", &n)) {
|
||||
if (n != 0 && n < 4) throw mjXError(elem, "maxhullvert must be larger than 3");
|
||||
pmesh->maxhullvert = n;
|
||||
}
|
||||
|
||||
// read user vertex data
|
||||
if (ReadAttrTxt(elem, "vertex", text)) {
|
||||
auto uservert = ReadAttrVec<float>(elem, "vertex");
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<mujoco>
|
||||
<asset>
|
||||
<mesh file="torus.obj" maxhullvert="4"/>
|
||||
</asset>
|
||||
<worldbody>
|
||||
<geom type="mesh" mesh="torus"/>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
@@ -0,0 +1,11 @@
|
||||
<mujoco>
|
||||
<default>
|
||||
<mesh maxhullvert="64"/>
|
||||
</default>
|
||||
<asset>
|
||||
<mesh file="torus.obj"/>
|
||||
</asset>
|
||||
<worldbody>
|
||||
<geom type="mesh" mesh="torus"/>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
@@ -41,6 +41,10 @@ static const char* const kCubePath =
|
||||
"user/testdata/cube.xml";
|
||||
static const char* const kTorusPath =
|
||||
"user/testdata/torus.xml";
|
||||
static const char* const kTorusMaxhullVertPath =
|
||||
"user/testdata/torus_maxhullvert.xml";
|
||||
static const char* const kTorusDefaultMaxhullVertPath =
|
||||
"user/testdata/torus_maxhullvert_default.xml";
|
||||
static const char* const kTorusShellPath =
|
||||
"user/testdata/torus_shell.xml";
|
||||
static const char* const kConvexInertiaPath =
|
||||
@@ -405,6 +409,25 @@ TEST_F(MjCMeshTest, TinyMeshLoads) {
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
// ------------- test max hull vert -------------------------------------------
|
||||
TEST_F(MjCMeshTest, MaxHullVert) {
|
||||
const std::string xml_path = GetTestDataFilePath(kTorusMaxhullVertPath);
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||
ASSERT_GT(model->ngeom, 0);
|
||||
ASSERT_EQ(model->mesh_graph[0], 4);
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
TEST_F(MjCMeshTest, MaxHullVertDefault) {
|
||||
const std::string xml_path = GetTestDataFilePath(kTorusDefaultMaxhullVertPath);
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||
ASSERT_GT(model->ngeom, 0);
|
||||
ASSERT_EQ(model->mesh_graph[0], 64);
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
// ------------- test inline loading ------------------------------------------
|
||||
TEST_F(MjCMeshTest, FaceNormalAutogenerated) {
|
||||
static constexpr char xml[] = R"(
|
||||
|
||||
Reference in New Issue
Block a user