I want to use mujoco with the visualization with GLFW. On mujoco i found the visualization example. In this example you build a mujoco model and show it in glfw. To move around with the camera in the simulations you need callback functions like here the mouse_button. But all this only works as long as this callback function is static and can directy access the global mujoco variables.
What i want is to create an own mujoco class calling a visualization class with the glfw stuff if visualization is needed. But in that case the callback functions need access to class member objects and that doesn't work in my case. Does someone know how to handle with these callback function problems?
#include <mujoco/mujoco.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
// MuJoCo data structures
mjModel* m = NULL; // MuJoCo model
mjData* d = NULL; // MuJoCo data
mjvCamera cam; // abstract camera
mjvOption opt; // visualization options
mjvScene scn; // abstract scene
mjrContext con; // custom GPU context
// 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);
// update mouse position
glfwGetCursorPos(window, &lastx, &lasty);
}
int
main(int argc, const char* argv[])
{
char error[1000];
std::string const filePath =
"robot_file.xml";
m = mj_loadXML(filePath.c_str(), nullptr, error, 1000);
d = mj_makeData(m);
// init GLFW, create window, make OpenGL context current, request v-sync
glfwInit();
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// initialize visualization data structures
mjv_defaultCamera(&cam);
// mjv_defaultPerturb(&pert);
mjv_defaultOption(&opt);
mjr_defaultContext(&con);
// create scene and context
mjv_makeScene(m, &scn, 1000);
mjr_makeContext(m, &con, mjFONTSCALE_100);
// 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);
}
// 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();
}
I already tried to directly call the callback function as member function of the class instance but that does not work.