Add optional azimuth and elevation to initial free camera.
- Add `azimuth` and `elevation` to `visual.global`. - Add `mjv_defaultFreeCamera`. - Use `mjv_defaultFreeCamera` in `simulate`. PiperOrigin-RevId: 465505244 Change-Id: I61e60f14a990d4e2d220958adb75c325001978ee
This commit is contained in:
committed by
Copybara-Service
parent
5ee184ddaa
commit
b966a37855
+12
-1
@@ -1230,7 +1230,7 @@ mjVisual
|
|||||||
{
|
{
|
||||||
struct // global parameters
|
struct // global parameters
|
||||||
{
|
{
|
||||||
float fovy; // y-field of view (deg) for free camera
|
float fovy; // y-field of view for free camera (degrees)
|
||||||
float ipd; // inter-pupilary distance for free camera
|
float ipd; // inter-pupilary distance for free camera
|
||||||
float linewidth; // line width for wireframe and ray rendering
|
float linewidth; // line width for wireframe and ray rendering
|
||||||
float glow; // glow coefficient for selected body
|
float glow; // glow coefficient for selected body
|
||||||
@@ -4722,6 +4722,17 @@ mjv_defaultCamera
|
|||||||
|
|
||||||
Set default camera.
|
Set default camera.
|
||||||
|
|
||||||
|
.. _mjv_defaultFreeCamera:
|
||||||
|
|
||||||
|
mjv_defaultFreeCamera
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. code-block:: C
|
||||||
|
|
||||||
|
void mjv_defaultFreeCamera(const mjModel* m, mjvCamera* cam);
|
||||||
|
|
||||||
|
Set default free camera.
|
||||||
|
|
||||||
.. _mjv_defaultPerturb:
|
.. _mjv_defaultPerturb:
|
||||||
|
|
||||||
mjv_defaultPerturb
|
mjv_defaultPerturb
|
||||||
|
|||||||
+14
-3
@@ -120,9 +120,11 @@ in the second column of the table have the following meaning:
|
|||||||
| | | :class: mjcf-attributes |
|
| | | :class: mjcf-attributes |
|
||||||
| | | |
|
| | | |
|
||||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||||
| | | | :at:`fovy` | :at:`ipd` | :at:`linewidth` | |
|
| | | | :at:`fovy` | :at:`ipd` | :at:`azimuth` | |
|
||||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||||
| | | | :at:`glow` | :at:`offwidth` | :at:`offheight` | |
|
| | | | :at:`elevation` | :at:`linewidth` | :at:`glow` | |
|
||||||
|
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||||
|
| | | | :at:`offwidth` | :at:`offheight` | | |
|
||||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||||
+--------------------------+----+------------------------------------------------------------------------------------+
|
+--------------------------+----+------------------------------------------------------------------------------------+
|
||||||
| |_2|:el:`quality` | ? | .. table:: |
|
| |_2|:el:`quality` | ? | .. table:: |
|
||||||
@@ -1960,6 +1962,14 @@ is effectively a miscellaneous subsection.
|
|||||||
:at:`ipd`: :at-val:`real, "0.068"`
|
:at:`ipd`: :at-val:`real, "0.068"`
|
||||||
This attribute specifies the inter-pupilary distance of the free camera. It only affects the rendering in
|
This attribute specifies the inter-pupilary distance of the free camera. It only affects the rendering in
|
||||||
stereoscopic mode. The left and right viewpoints are offset by half of this value in the corresponding direction.
|
stereoscopic mode. The left and right viewpoints are offset by half of this value in the corresponding direction.
|
||||||
|
:at:`azimuth`: :at-val:`real, "90"`
|
||||||
|
This attribute specifies the initial azimuth of the free camera around the vertical z-axis, in degrees. A value of 0
|
||||||
|
corresponds to looking in the positive x direction, while the default value of 90 corresponds to looking in the
|
||||||
|
positive y direction.
|
||||||
|
:at:`elevation`: :at-val:`real, "-45"`
|
||||||
|
This attribute specifies the initial elevation of the free camera with respect to the lookat point. Note that since
|
||||||
|
this is a rotation around a vector parallel to the camera's X-axis (right in pixel space), *negative* numbers
|
||||||
|
correspond to moving the camera *up* from the horizontal plane, and vice-versa.
|
||||||
:at:`linewidth`: :at-val:`real, "1"`
|
:at:`linewidth`: :at-val:`real, "1"`
|
||||||
This attribute specifies the line-width in the sense of OpenGL. It affects the rendering in wire-frame mode.
|
This attribute specifies the line-width in the sense of OpenGL. It affects the rendering in wire-frame mode.
|
||||||
:at:`glow`: :at-val:`real, "0.3"`
|
:at:`glow`: :at-val:`real, "0.3"`
|
||||||
@@ -2216,7 +2226,8 @@ parameters.
|
|||||||
:at:`extent`: :at-val:`real, optional`
|
:at:`extent`: :at-val:`real, optional`
|
||||||
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.
|
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`.
|
||||||
: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
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ General
|
|||||||
computations. This is currently supported only for meshes.
|
computations. This is currently supported only for meshes.
|
||||||
- Raise error if the orientation of mesh faces is not consistent, which causes the inertia computations to be
|
- Raise error if the orientation of mesh faces is not consistent, which causes the inertia computations to be
|
||||||
inaccurate. If this occurs, open the mesh in MeshLab or Blender and recalculate the faces.
|
inaccurate. If this occurs, open the mesh in MeshLab or Blender and recalculate the faces.
|
||||||
|
- Added ``azimuth`` and ``elevation`` attributes to :ref:`visual/global<global>`, defining the initial orientation of
|
||||||
|
the free camera at model load time.
|
||||||
|
- Added ``mjv_defaultFreeCamera`` which sets the default free camera, respecting the above attributes.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|||||||
@@ -418,8 +418,10 @@ typedef struct mjOption_ mjOption;
|
|||||||
|
|
||||||
struct mjVisual_ { // visualization options
|
struct mjVisual_ { // visualization options
|
||||||
struct { // global parameters
|
struct { // global parameters
|
||||||
float fovy; // y-field of view (deg) for free camera
|
float fovy; // y-field of view for free camera (degrees)
|
||||||
float ipd; // inter-pupilary distance for free camera
|
float ipd; // inter-pupilary distance for free camera
|
||||||
|
float azimuth; // initial azimuth of free camera (degrees)
|
||||||
|
float elevation; // initial elevation of free camera (degrees)
|
||||||
float linewidth; // line width for wireframe and ray rendering
|
float linewidth; // line width for wireframe and ray rendering
|
||||||
float glow; // glow coefficient for selected body
|
float glow; // glow coefficient for selected body
|
||||||
int offwidth; // width of offscreen buffer
|
int offwidth; // width of offscreen buffer
|
||||||
|
|||||||
@@ -492,6 +492,9 @@ MJAPI mjtNum mju_raySkin(int nface, int nvert, const int* face, const float* ver
|
|||||||
// Set default camera.
|
// Set default camera.
|
||||||
MJAPI void mjv_defaultCamera(mjvCamera* cam);
|
MJAPI void mjv_defaultCamera(mjvCamera* cam);
|
||||||
|
|
||||||
|
// Set default free camera.
|
||||||
|
MJAPI void mjv_defaultFreeCamera(const mjModel* m, mjvCamera* cam);
|
||||||
|
|
||||||
// Set default perturbation.
|
// Set default perturbation.
|
||||||
MJAPI void mjv_defaultPerturb(mjvPerturb* pert);
|
MJAPI void mjv_defaultPerturb(mjvPerturb* pert);
|
||||||
|
|
||||||
|
|||||||
@@ -2929,6 +2929,26 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='Set default camera.',
|
doc='Set default camera.',
|
||||||
)),
|
)),
|
||||||
|
('mjv_defaultFreeCamera',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjv_defaultFreeCamera',
|
||||||
|
return_type=ValueType(name='void'),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='m',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjModel', is_const=True),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='cam',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjvCamera'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Set default free camera.',
|
||||||
|
)),
|
||||||
('mjv_defaultPerturb',
|
('mjv_defaultPerturb',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mjv_defaultPerturb',
|
name='mjv_defaultPerturb',
|
||||||
|
|||||||
@@ -546,6 +546,7 @@ PYBIND11_MODULE(_functions, pymodule) {
|
|||||||
|
|
||||||
// Interaction
|
// Interaction
|
||||||
Def<traits::mjv_defaultCamera>(pymodule);
|
Def<traits::mjv_defaultCamera>(pymodule);
|
||||||
|
Def<traits::mjv_defaultFreeCamera>(pymodule);
|
||||||
Def<traits::mjv_defaultPerturb>(pymodule);
|
Def<traits::mjv_defaultPerturb>(pymodule);
|
||||||
Def<traits::mjv_room2model>(pymodule);
|
Def<traits::mjv_room2model>(pymodule);
|
||||||
Def<traits::mjv_model2room>(pymodule);
|
Def<traits::mjv_model2room>(pymodule);
|
||||||
|
|||||||
+2
-5
@@ -74,11 +74,8 @@ void initMuJoCo(const char* filename) {
|
|||||||
mjv_makeScene(m, &scn, 2000);
|
mjv_makeScene(m, &scn, 2000);
|
||||||
mjr_makeContext(m, &con, 200);
|
mjr_makeContext(m, &con, 200);
|
||||||
|
|
||||||
// center and scale view
|
// default free camera
|
||||||
cam.lookat[0] = m->stat.center[0];
|
mjv_defaultFreeCamera(m, &cam);
|
||||||
cam.lookat[1] = m->stat.center[1];
|
|
||||||
cam.lookat[2] = m->stat.center[2];
|
|
||||||
cam.distance = 1.5 * m->stat.extent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -904,16 +904,11 @@ void makesections(mj::Simulate* sim) {
|
|||||||
|
|
||||||
// align and scale view
|
// align and scale view
|
||||||
void alignscale(mj::Simulate* sim) {
|
void alignscale(mj::Simulate* sim) {
|
||||||
// autoscale
|
// use default free camera parameters
|
||||||
sim->cam.lookat[0] = sim->m->stat.center[0];
|
mjv_defaultFreeCamera(sim->m, &sim->cam);
|
||||||
sim->cam.lookat[1] = sim->m->stat.center[1];
|
|
||||||
sim->cam.lookat[2] = sim->m->stat.center[2];
|
|
||||||
sim->cam.distance = 1.5 * sim->m->stat.extent;
|
|
||||||
|
|
||||||
// set to free camera
|
|
||||||
sim->cam.type = mjCAMERA_FREE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// copy qpos to clipboard as key
|
// copy qpos to clipboard as key
|
||||||
void copykey(mj::Simulate* sim) {
|
void copykey(mj::Simulate* sim) {
|
||||||
char clipboard[5000] = "<key qpos='";
|
char clipboard[5000] = "<key qpos='";
|
||||||
|
|||||||
@@ -152,6 +152,8 @@ void mj_defaultVisual(mjVisual* vis) {
|
|||||||
// global
|
// global
|
||||||
vis->global.fovy = 45;
|
vis->global.fovy = 45;
|
||||||
vis->global.ipd = 0.068;
|
vis->global.ipd = 0.068;
|
||||||
|
vis->global.azimuth = 90;
|
||||||
|
vis->global.elevation = -45;
|
||||||
vis->global.linewidth = 1.0;
|
vis->global.linewidth = 1.0;
|
||||||
vis->global.glow = 0.3;
|
vis->global.glow = 0.3;
|
||||||
vis->global.offwidth = 640;
|
vis->global.offwidth = 640;
|
||||||
|
|||||||
@@ -241,6 +241,23 @@ void mjv_defaultCamera(mjvCamera* cam) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// set default free camera
|
||||||
|
void mjv_defaultFreeCamera(const mjModel* m, mjvCamera* cam) {
|
||||||
|
memset(cam, 0, sizeof(mjvCamera));
|
||||||
|
|
||||||
|
cam->type = mjCAMERA_FREE;
|
||||||
|
cam->fixedcamid = -1;
|
||||||
|
cam->trackbodyid = -1;
|
||||||
|
cam->lookat[0] = m->stat.center[0];
|
||||||
|
cam->lookat[1] = m->stat.center[1];
|
||||||
|
cam->lookat[2] = m->stat.center[2];
|
||||||
|
cam->distance = 1.5 * m->stat.extent;
|
||||||
|
cam->azimuth = m->vis.global.azimuth;
|
||||||
|
cam->elevation = m->vis.global.elevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// set default perturbation
|
// set default perturbation
|
||||||
void mjv_defaultPerturb(mjvPerturb* pert) {
|
void mjv_defaultPerturb(mjvPerturb* pert) {
|
||||||
memset(pert, 0, sizeof(mjvPerturb));
|
memset(pert, 0, sizeof(mjvPerturb));
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ MJAPI void mjv_freeScene(mjvScene* scn);
|
|||||||
// set default visualization options
|
// set default visualization options
|
||||||
MJAPI void mjv_defaultOption(mjvOption* vopt);
|
MJAPI void mjv_defaultOption(mjvOption* vopt);
|
||||||
|
|
||||||
|
// set default free camera
|
||||||
|
MJAPI void mjv_defaultFreeCamera(const mjModel* m, mjvCamera* cam);
|
||||||
|
|
||||||
// set default camera
|
// set default camera
|
||||||
MJAPI void mjv_defaultCamera(mjvCamera* cam);
|
MJAPI void mjv_defaultCamera(mjvCamera* cam);
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ static const char* MJCF[nMJCF][mjXATTRNUM] = {
|
|||||||
|
|
||||||
{"visual", "*", "0"},
|
{"visual", "*", "0"},
|
||||||
{"<"},
|
{"<"},
|
||||||
{"global", "?", "6", "fovy", "ipd", "linewidth", "glow", "offwidth", "offheight"},
|
{"global", "?", "8", "fovy", "ipd", "azimuth", "elevation", "linewidth", "glow", "offwidth",
|
||||||
|
"offheight"},
|
||||||
{"quality", "?", "5", "shadowsize", "offsamples", "numslices", "numstacks",
|
{"quality", "?", "5", "shadowsize", "offsamples", "numslices", "numstacks",
|
||||||
"numquads"},
|
"numquads"},
|
||||||
{"headlight", "?", "4", "ambient", "diffuse", "specular", "active"},
|
{"headlight", "?", "4", "ambient", "diffuse", "specular", "active"},
|
||||||
@@ -2034,6 +2035,8 @@ void mjXReader::Visual(XMLElement* section) {
|
|||||||
if (name=="global") {
|
if (name=="global") {
|
||||||
ReadAttr(elem, "fovy", 1, &vis->global.fovy, text);
|
ReadAttr(elem, "fovy", 1, &vis->global.fovy, text);
|
||||||
ReadAttr(elem, "ipd", 1, &vis->global.ipd, text);
|
ReadAttr(elem, "ipd", 1, &vis->global.ipd, text);
|
||||||
|
ReadAttr(elem, "azimuth", 1, &vis->global.azimuth, text);
|
||||||
|
ReadAttr(elem, "elevation", 1, &vis->global.elevation, text);
|
||||||
ReadAttr(elem, "linewidth", 1, &vis->global.linewidth, text);
|
ReadAttr(elem, "linewidth", 1, &vis->global.linewidth, text);
|
||||||
ReadAttr(elem, "glow", 1, &vis->global.glow, text);
|
ReadAttr(elem, "glow", 1, &vis->global.glow, text);
|
||||||
ReadAttrInt(elem, "offwidth", &vis->global.offwidth);
|
ReadAttrInt(elem, "offwidth", &vis->global.offwidth);
|
||||||
|
|||||||
@@ -796,6 +796,8 @@ void mjXWriter::Visual(XMLElement* root) {
|
|||||||
elem = InsertEnd(section, "global");
|
elem = InsertEnd(section, "global");
|
||||||
WriteAttr(elem, "fovy", 1, &vis->global.fovy, &visdef.global.fovy);
|
WriteAttr(elem, "fovy", 1, &vis->global.fovy, &visdef.global.fovy);
|
||||||
WriteAttr(elem, "ipd", 1, &vis->global.ipd, &visdef.global.ipd);
|
WriteAttr(elem, "ipd", 1, &vis->global.ipd, &visdef.global.ipd);
|
||||||
|
WriteAttr(elem, "azimuth", 1, &vis->global.azimuth, &visdef.global.azimuth);
|
||||||
|
WriteAttr(elem, "elevation", 1, &vis->global.elevation, &visdef.global.elevation);
|
||||||
WriteAttr(elem, "linewidth", 1, &vis->global.linewidth, &visdef.global.linewidth);
|
WriteAttr(elem, "linewidth", 1, &vis->global.linewidth, &visdef.global.linewidth);
|
||||||
WriteAttr(elem, "glow", 1, &vis->global.glow, &visdef.global.glow);
|
WriteAttr(elem, "glow", 1, &vis->global.glow, &visdef.global.glow);
|
||||||
WriteAttrInt(elem, "offwidth", vis->global.offwidth, visdef.global.offwidth);
|
WriteAttrInt(elem, "offwidth", vis->global.offwidth, visdef.global.offwidth);
|
||||||
|
|||||||
@@ -3009,6 +3009,9 @@ public static unsafe extern double mju_raySkin(int nface, int nvert, int* face,
|
|||||||
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static unsafe extern void mjv_defaultCamera(mjvCamera_* cam);
|
public static unsafe extern void mjv_defaultCamera(mjvCamera_* cam);
|
||||||
|
|
||||||
|
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static unsafe extern void mjv_defaultFreeCamera(mjModel_* m, mjvCamera_* cam);
|
||||||
|
|
||||||
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static unsafe extern void mjv_defaultPerturb(mjvPerturb_* pert);
|
public static unsafe extern void mjv_defaultPerturb(mjvPerturb_* pert);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user