Enforce strict positivity of extent and znear attributes at parse time.
PiperOrigin-RevId: 477597498 Change-Id: Ic927655cd5ba2fd8fdb1a1a5f7e54ff5040c3370
This commit is contained in:
committed by
Copybara-Service
parent
d3dbc554b9
commit
48f2ed99a5
@@ -2086,7 +2086,7 @@ miscellaneous.
|
|||||||
This and the next attribute determine the clipping planes of the OpenGL projection. The near clipping plane is
|
This and the next attribute determine the clipping planes of the OpenGL projection. The near clipping plane is
|
||||||
particularly important: setting it too close causes (often severe) loss of resolution in the depth buffer, while
|
particularly important: setting it too close causes (often severe) loss of resolution in the depth buffer, while
|
||||||
setting it too far causes objects of interest to be clipped, making it impossible to zoom in. The distance to the
|
setting it too far causes objects of interest to be clipped, making it impossible to zoom in. The distance to the
|
||||||
near clipping plane is the model extent multiplied by the value of this attribute.
|
near clipping plane is the model extent multiplied by the value of this attribute. Must be strictly positive.
|
||||||
:at:`zfar`: :at-val:`real, "50"`
|
:at:`zfar`: :at-val:`real, "50"`
|
||||||
The distance to the far clipping plane is the model extent multiplied by the value of this attribute.
|
The distance to the far clipping plane is the model extent multiplied by the value of this attribute.
|
||||||
:at:`haze`: :at-val:`real, "0.3"`
|
:at:`haze`: :at-val:`real, "0.3"`
|
||||||
@@ -2243,7 +2243,7 @@ parameters.
|
|||||||
If this attribute is specified, it replaces the value of mjModel.stat.extent computed by the compiler. The computed
|
If this attribute is specified, it replaces the value of mjModel.stat.extent computed by the compiler. The computed
|
||||||
value is half the side of the bounding box of the model in the initial configuration. At runtime this value is
|
value is half the side of the bounding box of the model in the initial configuration. At runtime this value is
|
||||||
multiplied by some of the attributes of the :ref:`map <map>` element above. When the model is first loaded, the free
|
multiplied by some of the attributes of the :ref:`map <map>` element above. When the model is first loaded, the free
|
||||||
camera's initial distance from the :at:`center` (see below) is 1.5 times the :at:`extent`.
|
camera's initial distance from the :at:`center` (see below) is 1.5 times the :at:`extent`. Must be strictly positive.
|
||||||
:at:`center`: :at-val:`real(3), optional`
|
:at:`center`: :at-val:`real(3), optional`
|
||||||
If this attribute is specified, it replaces the value of mjModel.stat.center computed by the compiler. The computed
|
If this attribute is specified, it replaces the value of mjModel.stat.center computed by the compiler. The computed
|
||||||
value is the center of the bounding box of the entire model in the initial configuration. This 3D vector is used to
|
value is the center of the bounding box of the entire model in the initial configuration. This 3D vector is used to
|
||||||
|
|||||||
@@ -1016,6 +1016,9 @@ void mjXReader::Statistic(XMLElement* section) {
|
|||||||
ReadAttr(section, "meanmass", 1, &model->meanmass, text);
|
ReadAttr(section, "meanmass", 1, &model->meanmass, text);
|
||||||
ReadAttr(section, "meansize", 1, &model->meansize, text);
|
ReadAttr(section, "meansize", 1, &model->meansize, text);
|
||||||
ReadAttr(section, "extent", 1, &model->extent, text);
|
ReadAttr(section, "extent", 1, &model->extent, text);
|
||||||
|
if (mjuu_defined(model->extent) && model->extent<=0) {
|
||||||
|
throw mjXError(section, "extent must be strictly positive");
|
||||||
|
}
|
||||||
ReadAttr(section, "center", 3, model->center, text);
|
ReadAttr(section, "center", 3, model->center, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2192,6 +2195,9 @@ void mjXReader::Visual(XMLElement* section) {
|
|||||||
ReadAttr(elem, "fogstart", 1, &vis->map.fogstart, text);
|
ReadAttr(elem, "fogstart", 1, &vis->map.fogstart, text);
|
||||||
ReadAttr(elem, "fogend", 1, &vis->map.fogend, text);
|
ReadAttr(elem, "fogend", 1, &vis->map.fogend, text);
|
||||||
ReadAttr(elem, "znear", 1, &vis->map.znear, text);
|
ReadAttr(elem, "znear", 1, &vis->map.znear, text);
|
||||||
|
if (vis->map.znear<=0) {
|
||||||
|
throw mjXError(elem, "znear must be strictly positive");
|
||||||
|
}
|
||||||
ReadAttr(elem, "zfar", 1, &vis->map.zfar, text);
|
ReadAttr(elem, "zfar", 1, &vis->map.zfar, text);
|
||||||
ReadAttr(elem, "haze", 1, &vis->map.haze, text);
|
ReadAttr(elem, "haze", 1, &vis->map.haze, text);
|
||||||
ReadAttr(elem, "shadowclip", 1, &vis->map.shadowclip, text);
|
ReadAttr(elem, "shadowclip", 1, &vis->map.shadowclip, text);
|
||||||
|
|||||||
@@ -762,6 +762,58 @@ TEST_F(ActuatorParseTest, DampersDontRequireRange) {
|
|||||||
mj_deleteModel(model);
|
mj_deleteModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(UserDataTest, ZnearZeroNotAllowed) {
|
||||||
|
static constexpr char xml[] = R"(
|
||||||
|
<mujoco>
|
||||||
|
<visual>
|
||||||
|
<map znear="0"/>
|
||||||
|
</visual>
|
||||||
|
</mujoco>
|
||||||
|
)";
|
||||||
|
std::array<char, 1024> error;
|
||||||
|
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||||
|
ASSERT_THAT(model, IsNull());
|
||||||
|
EXPECT_THAT(error.data(), HasSubstr("znear must be strictly positive"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UserDataTest, ZnearNegativeNotAllowed) {
|
||||||
|
static constexpr char xml[] = R"(
|
||||||
|
<mujoco>
|
||||||
|
<visual>
|
||||||
|
<map znear="-1"/>
|
||||||
|
</visual>
|
||||||
|
</mujoco>
|
||||||
|
)";
|
||||||
|
std::array<char, 1024> error;
|
||||||
|
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||||
|
ASSERT_THAT(model, IsNull());
|
||||||
|
EXPECT_THAT(error.data(), HasSubstr("znear must be strictly positive"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UserDataTest, ExtentZeroNotAllowed) {
|
||||||
|
static constexpr char xml[] = R"(
|
||||||
|
<mujoco>
|
||||||
|
<statistic extent="0"/>
|
||||||
|
</mujoco>
|
||||||
|
)";
|
||||||
|
std::array<char, 1024> error;
|
||||||
|
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||||
|
ASSERT_THAT(model, IsNull());
|
||||||
|
EXPECT_THAT(error.data(), HasSubstr("extent must be strictly positive"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UserDataTest, ExtentNegativeNotAllowed) {
|
||||||
|
static constexpr char xml[] = R"(
|
||||||
|
<mujoco>
|
||||||
|
<statistic extent="-1"/>
|
||||||
|
</mujoco>
|
||||||
|
)";
|
||||||
|
std::array<char, 1024> error;
|
||||||
|
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||||
|
ASSERT_THAT(model, IsNull());
|
||||||
|
EXPECT_THAT(error.data(), HasSubstr("extent must be strictly positive"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|||||||
Reference in New Issue
Block a user