Version 2.1.1: Binaries for ARM64, proper macOS bundles, minor bugfixes.
Closes #2 Closes #42 Closes #59 PiperOrigin-RevId: 416794598 Change-Id: I1306df1127d6acecf2323873c0da0910f35d31a0
This commit is contained in:
+125
-128
@@ -12,12 +12,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "mujoco.h"
|
||||
#include "glfw3.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "mujoco.h"
|
||||
|
||||
// MuJoCo data structures
|
||||
mjModel* m = NULL; // MuJoCo model
|
||||
@@ -36,158 +35,156 @@ double lasty = 0;
|
||||
|
||||
|
||||
// keyboard callback
|
||||
void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods)
|
||||
{
|
||||
// backspace: reset simulation
|
||||
if( act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE )
|
||||
{
|
||||
mj_resetData(m, d);
|
||||
mj_forward(m, d);
|
||||
}
|
||||
void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods) {
|
||||
// backspace: reset simulation
|
||||
if (act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE) {
|
||||
mj_resetData(m, d);
|
||||
mj_forward(m, d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// mouse button callback
|
||||
void mouse_button(GLFWwindow* window, int button, int act, int mods)
|
||||
{
|
||||
// update button state
|
||||
button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
|
||||
button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
|
||||
button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
|
||||
void mouse_button(GLFWwindow* window, int button, int act, int mods) {
|
||||
// update button state
|
||||
button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
|
||||
button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
|
||||
button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
|
||||
|
||||
// update mouse position
|
||||
glfwGetCursorPos(window, &lastx, &lasty);
|
||||
// update mouse position
|
||||
glfwGetCursorPos(window, &lastx, &lasty);
|
||||
}
|
||||
|
||||
|
||||
// mouse move callback
|
||||
void mouse_move(GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
// no buttons down: nothing to do
|
||||
if( !button_left && !button_middle && !button_right )
|
||||
return;
|
||||
void mouse_move(GLFWwindow* window, double xpos, double ypos) {
|
||||
// no buttons down: nothing to do
|
||||
if (!button_left && !button_middle && !button_right) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute mouse displacement, save
|
||||
double dx = xpos - lastx;
|
||||
double dy = ypos - lasty;
|
||||
lastx = xpos;
|
||||
lasty = ypos;
|
||||
// compute mouse displacement, save
|
||||
double dx = xpos - lastx;
|
||||
double dy = ypos - lasty;
|
||||
lastx = xpos;
|
||||
lasty = ypos;
|
||||
|
||||
// get current window size
|
||||
int width, height;
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
// get current window size
|
||||
int width, height;
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
|
||||
// get shift key state
|
||||
bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
|
||||
glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
|
||||
// get shift key state
|
||||
bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
|
||||
glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
|
||||
|
||||
// determine action based on mouse button
|
||||
mjtMouse action;
|
||||
if( button_right )
|
||||
action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
|
||||
else if( button_left )
|
||||
action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
|
||||
else
|
||||
action = mjMOUSE_ZOOM;
|
||||
// determine action based on mouse button
|
||||
mjtMouse action;
|
||||
if (button_right) {
|
||||
action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
|
||||
} else if (button_left) {
|
||||
action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
|
||||
} else {
|
||||
action = mjMOUSE_ZOOM;
|
||||
}
|
||||
|
||||
// move camera
|
||||
mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam);
|
||||
// move camera
|
||||
mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam);
|
||||
}
|
||||
|
||||
|
||||
// scroll callback
|
||||
void scroll(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
// emulate vertical mouse motion = 5% of window height
|
||||
mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam);
|
||||
void scroll(GLFWwindow* window, double xoffset, double yoffset) {
|
||||
// emulate vertical mouse motion = 5% of window height
|
||||
mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam);
|
||||
}
|
||||
|
||||
|
||||
// main function
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
// check command-line arguments
|
||||
if( argc!=2 )
|
||||
{
|
||||
printf(" USAGE: basic modelfile\n");
|
||||
return 0;
|
||||
int main(int argc, const char** argv) {
|
||||
// check command-line arguments
|
||||
if (argc!=2) {
|
||||
std::printf(" USAGE: basic modelfile\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// load and compile model
|
||||
char error[1000] = "Could not load binary model";
|
||||
if (std::strlen(argv[1])>4 && !std::strcmp(argv[1]+std::strlen(argv[1])-4, ".mjb")) {
|
||||
m = mj_loadModel(argv[1], 0);
|
||||
} else {
|
||||
m = mj_loadXML(argv[1], 0, error, 1000);
|
||||
}
|
||||
if (!m) {
|
||||
mju_error_s("Load model error: %s", error);
|
||||
}
|
||||
|
||||
// make data
|
||||
d = mj_makeData(m);
|
||||
|
||||
// init GLFW
|
||||
if (!glfwInit()) {
|
||||
mju_error("Could not initialize GLFW");
|
||||
}
|
||||
|
||||
// create window, make OpenGL context current, request v-sync
|
||||
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL);
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
// initialize visualization data structures
|
||||
mjv_defaultCamera(&cam);
|
||||
mjv_defaultOption(&opt);
|
||||
mjv_defaultScene(&scn);
|
||||
mjr_defaultContext(&con);
|
||||
|
||||
// create scene and context
|
||||
mjv_makeScene(m, &scn, 2000);
|
||||
mjr_makeContext(m, &con, mjFONTSCALE_150);
|
||||
|
||||
// install GLFW mouse and keyboard callbacks
|
||||
glfwSetKeyCallback(window, keyboard);
|
||||
glfwSetCursorPosCallback(window, mouse_move);
|
||||
glfwSetMouseButtonCallback(window, mouse_button);
|
||||
glfwSetScrollCallback(window, scroll);
|
||||
|
||||
// run main loop, target real-time simulation and 60 fps rendering
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
// advance interactive simulation for 1/60 sec
|
||||
// Assuming MuJoCo can simulate faster than real-time, which it usually can,
|
||||
// this loop will finish on time for the next frame to be rendered at 60 fps.
|
||||
// Otherwise add a cpu timer and exit this loop when it is time to render.
|
||||
mjtNum simstart = d->time;
|
||||
while (d->time - simstart < 1.0/60.0) {
|
||||
mj_step(m, d);
|
||||
}
|
||||
|
||||
// load and compile model
|
||||
char error[1000] = "Could not load binary model";
|
||||
if( strlen(argv[1])>4 && !strcmp(argv[1]+strlen(argv[1])-4, ".mjb") )
|
||||
m = mj_loadModel(argv[1], 0);
|
||||
else
|
||||
m = mj_loadXML(argv[1], 0, error, 1000);
|
||||
if( !m )
|
||||
mju_error_s("Load model error: %s", error);
|
||||
// get framebuffer viewport
|
||||
mjrRect viewport = {0, 0, 0, 0};
|
||||
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
|
||||
|
||||
// make data
|
||||
d = mj_makeData(m);
|
||||
// update scene and render
|
||||
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
||||
mjr_render(viewport, &scn, &con);
|
||||
|
||||
// init GLFW
|
||||
if( !glfwInit() )
|
||||
mju_error("Could not initialize GLFW");
|
||||
// swap OpenGL buffers (blocking call due to v-sync)
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
// create window, make OpenGL context current, request v-sync
|
||||
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL);
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
// process pending GUI events, call GLFW callbacks
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// initialize visualization data structures
|
||||
mjv_defaultCamera(&cam);
|
||||
mjv_defaultOption(&opt);
|
||||
mjv_defaultScene(&scn);
|
||||
mjr_defaultContext(&con);
|
||||
//free visualization storage
|
||||
mjv_freeScene(&scn);
|
||||
mjr_freeContext(&con);
|
||||
|
||||
// create scene and context
|
||||
mjv_makeScene(m, &scn, 2000);
|
||||
mjr_makeContext(m, &con, mjFONTSCALE_150);
|
||||
// free MuJoCo model and data
|
||||
mj_deleteData(d);
|
||||
mj_deleteModel(m);
|
||||
|
||||
// install GLFW mouse and keyboard callbacks
|
||||
glfwSetKeyCallback(window, keyboard);
|
||||
glfwSetCursorPosCallback(window, mouse_move);
|
||||
glfwSetMouseButtonCallback(window, mouse_button);
|
||||
glfwSetScrollCallback(window, scroll);
|
||||
// terminate GLFW (crashes with Linux NVidia drivers)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
glfwTerminate();
|
||||
#endif
|
||||
|
||||
// run main loop, target real-time simulation and 60 fps rendering
|
||||
while( !glfwWindowShouldClose(window) )
|
||||
{
|
||||
// advance interactive simulation for 1/60 sec
|
||||
// Assuming MuJoCo can simulate faster than real-time, which it usually can,
|
||||
// this loop will finish on time for the next frame to be rendered at 60 fps.
|
||||
// Otherwise add a cpu timer and exit this loop when it is time to render.
|
||||
mjtNum simstart = d->time;
|
||||
while( d->time - simstart < 1.0/60.0 )
|
||||
mj_step(m, d);
|
||||
|
||||
// get framebuffer viewport
|
||||
mjrRect viewport = {0, 0, 0, 0};
|
||||
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
|
||||
|
||||
// update scene and render
|
||||
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
||||
mjr_render(viewport, &scn, &con);
|
||||
|
||||
// swap OpenGL buffers (blocking call due to v-sync)
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
// process pending GUI events, call GLFW callbacks
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
//free visualization storage
|
||||
mjv_freeScene(&scn);
|
||||
mjr_freeContext(&con);
|
||||
|
||||
// free MuJoCo model and data
|
||||
mj_deleteData(d);
|
||||
mj_deleteModel(m);
|
||||
|
||||
// terminate GLFW (crashes with Linux NVidia drivers)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
glfwTerminate();
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user