Add orthographic cameras.

Orthographic cameras are specified by setting the `orthographic` attribute of the `<camera>` element. The `fovy` attribute is still used to specify the field-of-view, but its semantic is different for orthographic cameras. For orthographic cameras, the field-of-view is expressed in units of length, rather than degrees.

Other related changes:

* Fix bug in the ordering of `cam_xxx` elements in `mjModel`.
* Make camera visualization translucent only when the frustum is visualized.
* Added a button to `simulate` to toggle between perspective and orthographic free cameras.

https://youtu.be/ZXBTEIDWHhs

PiperOrigin-RevId: 642293435
Change-Id: Id090a421ad88ab404b5b27ddbbd6bfc81ad49bc5
This commit is contained in:
Yuval Tassa
2024-06-11 09:21:39 -07:00
committed by Copybara-Service
parent 171b0d6e06
commit 07fc95ca9a
23 changed files with 490 additions and 235 deletions
+15 -5
View File
@@ -694,7 +694,7 @@ static void initLights(mjvScene* scn) {
// set projection and modelview
static void setView(int view, mjrRect viewport, const mjvScene* scn, const mjrContext* con,
float* camProject, float* camView) {
float camProject[16], float camView[16]) {
mjvGLCamera cam;
// copy specified camera for stereo, average for mono (view = -1)
@@ -709,24 +709,34 @@ static void setView(int view, mjrRect viewport, const mjvScene* scn, const mjrCo
: 0.5f * (float)viewport.width / (float)viewport.height *
(cam.frustum_top - cam.frustum_bottom);
// set projection
// prepare projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (mjGLAD_GL_ARB_clip_control) {
// reverse Z rendering mapping [znear, zfar] -> [1, 0] (ndc)
glTranslatef(0.0f, 0.0f, 0.5f);
glScalef(1.0f, 1.0f, -0.5f);
}
else {
} else {
// reverse Z rendering mapping without shift [znear, zfar] -> [1, -1] (ndc)
glScalef(1.0f, 1.0f, -1.0f);
}
glFrustum(cam.frustum_center - halfwidth,
// set projection, orthographic or perspective
if (cam.orthographic) {
glOrtho(cam.frustum_center - halfwidth,
cam.frustum_center + halfwidth,
cam.frustum_bottom,
cam.frustum_top,
cam.frustum_near,
cam.frustum_far);
} else {
glFrustum(cam.frustum_center - halfwidth,
cam.frustum_center + halfwidth,
cam.frustum_bottom,
cam.frustum_top,
cam.frustum_near,
cam.frustum_far);
}
// save projection matrix if requested
if (camProject) {