diff --git a/doc/programming/samples.rst b/doc/programming/samples.rst index c62d6987..92987a49 100644 --- a/doc/programming/samples.rst +++ b/doc/programming/samples.rst @@ -150,21 +150,60 @@ This code sample simulates the passive dynamics of a given model, renders it off values, and saves them into a raw data file that can then be converted into a movie file with tools such as ffmpeg. The rendering is simplified compared to :ref:`simulate.cc ` because there is no user interaction, visualization options or timing; instead we simply render with the default settings as fast as possible. The dimensions and number of -multi-samples for the offscreen buffer are specified in the MuJoCo model, while the simulation duration, frames-per- -second to be rendered (usually much less than the physics simulation rate), and output file name are specified as -command-line arguments. For example, a 5 second animation at 60 frames per second is created with: +multi-samples for the offscreen buffer are specified in the MuJoCo model with the visual/global/{`offwidth +`__, `offheight +`__} and visual/quality/`offsamples +`_ attributes, while the simulation +duration, frames-per-second to be rendered (usually much less than the physics simulation rate), and output file name +are specified as command-line arguments. .. code-block:: Shell - render humanoid.xml 5 60 rgb.out + record modelfile duration fps rgbfile [adddepth] -The default humanoid.xml model specifies offscreen rendering with 800x800 resolution. With this information in hand, we -can compress the (large) raw date file into a playable movie file: +Where the command line arguments are + +.. list-table:: + :width: 95% + :align: left + :widths: 1 1 5 + :header-rows: 1 + + * - Argument + - Default + - Meaning + * - ``modelfile`` + - (required) + - path to model + * - ``duration`` + - (required) + - duration of the recording in seconds + * - ``fps`` + - (required) + - number of frames per second + * - ``rgbfile`` + - (required) + - path to raw recording file + * - ``adddepth`` + - 1 + - overlay depth image in the lower left corner (0: none) + +For example, a 5 second animation at 60 frames per second is created with: .. code-block:: Shell - ffmpeg -f rawvideo -pixel_format rgb24 -video_size 800x800 - -framerate 60 -i rgb.out -vf "vflip" video.mp4 + record humanoid.xml 5 60 rgb.out + +The default `humanoid.xml `__ model +specifies offscreen rendering with 2560x1440 resolution. With this information in hand, we can compress the (large) raw +data file into a playable movie file: + +.. code-block:: Shell + + ffmpeg -f rawvideo -pixel_format rgb24 -video_size 2560x1440 + -framerate 60 -i rgb.out -vf "vflip,format=yuv420p" video.mp4 + +Note that the offscreen rendering resolution of the model and ffmpeg's video_size must be the identical. This sample can be compiled in three ways which differ in how the OpenGL context is created: using GLFW with an invisible window, using OSMesa, or using EGL. The latter two options are only available on Linux and are envoked by diff --git a/sample/record.cc b/sample/record.cc index dd07411a..522057f0 100644 --- a/sample/record.cc +++ b/sample/record.cc @@ -217,8 +217,8 @@ void closeOpenGL(void) { int main(int argc, const char** argv) { // check command-line arguments - if (argc!=5) { - std::printf(" USAGE: record modelfile duration fps rgbfile\n"); + if (argc < 5 || argc > 6) { + std::printf(" USAGE: record modelfile duration fps rgbfile [adddepth]\n"); return 0; } @@ -255,6 +255,11 @@ int main(int argc, const char** argv) { mju_error("Could not open rgbfile for writing"); } + int adddepth = 1; + if (argc > 5 && std::sscanf(argv[5], "%d", &adddepth) != 1) { + mju_error("Invalid adddepth argument"); + } + // main loop double frametime = 0; int framecount = 0; @@ -276,12 +281,15 @@ int main(int argc, const char** argv) { mjr_readPixels(rgb, depth, viewport, &con); // insert subsampled depth image in lower-left corner of rgb image - const int NS = 3; // depth image sub-sampling - for (int r=0; r