Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenXR-based VR integration #2124

Draft
wants to merge 28 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
bbfb82d
Starting working version of integrated VR into simulate
nishbo Feb 26, 2024
ba80a65
Reformatting
nishbo Feb 26, 2024
692f597
Some typo fixes and cleanups
nishbo Mar 5, 2024
5a517d9
Cleaning up cmake
nishbo Mar 8, 2024
c5e9e65
whitespace
nishbo Mar 8, 2024
ecbd752
Readme and VR OFF by default
nishbo Mar 8, 2024
2ec7870
readme links
nishbo Mar 8, 2024
db8415d
Typo
nishbo Mar 8, 2024
f285775
Setup should be ready
nishbo Sep 17, 2024
db423fa
Rendering, only left eye, and blinking, but still
nishbo Sep 18, 2024
c50adc2
Both eyes rendered but view weird
nishbo Sep 23, 2024
cfead37
both eyes different way
nishbo Sep 24, 2024
8e964bd
1 swapchain no blinking in vr
nishbo Sep 30, 2024
8d52860
No overlay, layer fix
nishbo Sep 30, 2024
30ed8c1
Works for display in vr, screen disp is a bit screwed
nishbo Oct 5, 2024
b4fae05
Single view in window
nishbo Oct 16, 2024
dff40c0
Blitting to the window respects proportions
nishbo Oct 16, 2024
c056e47
AR fix for now
nishbo Oct 21, 2024
8229698
Merge remote-tracking branch 'upstream/main' into open-xr-vr-base
nishbo Oct 21, 2024
e2e57a0
Rm not working default location
nishbo Oct 21, 2024
4c5f9c2
Clean up in progress
nishbo Oct 21, 2024
dfc8e31
Code cleanup and destruction
nishbo Oct 28, 2024
2c8a259
Modelless load
nishbo Oct 28, 2024
bc9efff
CMakes cleanup
nishbo Nov 5, 2024
fdd756b
Code cleanup
nishbo Nov 5, 2024
3c11b86
README and disabled XR by default
nishbo Nov 5, 2024
85c711f
Merge remote-tracking branch 'upstream/main' into open-xr-vr-base
nishbo Nov 5, 2024
2004cf7
Remove iostream dependency
nishbo Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion simulate/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ set(MUJOCO_DEP_VERSION_lodepng
CACHE STRING "Version of `lodepng` to be fetched."
)

set(MUJOCO_URL_openxr
https://github.com/KhronosGroup/OpenXR-SDK-Source/archive/refs/tags/release-1.0.34.zip
CACHE STRING "Link to fetch `openxr`."
)

set(MUJOCO_URL_HASH_openxr
924a94a2da0b5ef8e82154c623d88644 # 1.0.34
CACHE STRING "URL hash to check fetched `openxr`."
)

project(
mujoco_simulate
VERSION 3.2.5
Expand All @@ -43,6 +53,7 @@ endif()

option(SIMULATE_BUILD_EXECUTABLE "Build the simulate executable binary." ON)
option(SIMULATE_GLFW_DYNAMIC_SYMBOLS "Whether to resolve GLFW symbols dynamically." OFF)
option(SIMULATE_BUILD_XR "Build XR-enabled simulate executable binary." OFF)

# Check if we are building as standalone project.
set(SIMULATE_STANDALONE OFF)
Expand Down Expand Up @@ -79,6 +90,7 @@ if(MUJOCO_HARDEN)
endif()
endif()


# Fetch lodepng dependency.
if(NOT TARGET lodepng)
FetchContent_Declare(
Expand All @@ -100,6 +112,19 @@ if(NOT TARGET lodepng)
endif()
endif()


# Fetch OpenXR dependency.
if(NOT TARGET openxr)
FetchContent_Declare(
openxr
URL_HASH MD5=${MUJOCO_URL_HASH_openxr}
URL ${MUJOCO_URL_openxr}
SOURCE_DIR
openxr
)
FetchContent_MakeAvailable(OpenXR)
endif()

# Simulate library
add_library(platform_ui_adapter OBJECT)
target_sources(
Expand Down Expand Up @@ -131,11 +156,35 @@ target_sources(
PUBLIC simulate.h
PRIVATE simulate.cc array_safety.h
)
target_include_directories(libsimulate PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_options(libsimulate PRIVATE ${MUJOCO_SIMULATE_COMPILE_OPTIONS})
target_include_directories(libsimulate PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(libsimulate PUBLIC lodepng mujoco::platform_ui_adapter mujoco::mujoco)
target_link_options(libsimulate PRIVATE ${MUJOCO_SIMULATE_LINK_OPTIONS})

if(SIMULATE_BUILD_XR)
set(SIMULATE_OPENXR_HEADERS
simulate_xr/simulate_xr.h)
set(SIMULATE_OPENXR_SOURCES
simulate_xr/simulate_xr.cc)
set(SIMULATE_OPENXR_GLAD
simulate_xr/glad/glad.h simulate_xr/glad/glad.c)
target_include_directories(libsimulate PUBLIC
${SIMULATE_OPENXR_HEADERS} ${SIMULATE_OPENXR_SOURCES}
# From OpenXR repo
"${openxr_SOURCE_DIR}/src/common"
"${openxr_SOURCE_DIR}/external/include"
)
target_link_libraries(libsimulate PUBLIC openxr_loader)
target_sources(
libsimulate
PUBLIC ${SIMULATE_OPENXR_HEADERS}
PRIVATE ${SIMULATE_OPENXR_SOURCES} ${SIMULATE_OPENXR_GLAD}
)

# DEFINE to change the code
target_compile_definitions(mujoco PUBLIC mjBUILDSIMULATEXR)
endif()

if(APPLE)
target_sources(libsimulate PRIVATE macos_gui.mm)
target_link_libraries(libsimulate PUBLIC "-framework Cocoa")
Expand Down
13 changes: 13 additions & 0 deletions simulate/cmake/SimulateDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,20 @@ set(MUJOCO_DEP_VERSION_glfw3
7482de6071d21db77a7236155da44c172a7f6c9e # 3.3.8
CACHE STRING "Version of `glfw` to be fetched."
)

set(MUJOCO_URL_openxr
https://github.com/KhronosGroup/OpenXR-SDK-Source/archive/refs/tags/release-1.0.34.zip
CACHE STRING "Link to fetch `openxr`."
)

set(MUJOCO_URL_HASH_openxr
924a94a2da0b5ef8e82154c623d88644 # 1.0.34
CACHE STRING "URL hash to check fetched `openxr`."
)

mark_as_advanced(MUJOCO_DEP_VERSION_glfw3)
mark_as_advanced(MUJOCO_URL_openxr)
mark_as_advanced(MUJOCO_URL_HASH_openxr)

find_package(Threads REQUIRED)

Expand Down
13 changes: 13 additions & 0 deletions simulate/glfw_adapter.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "glfw_adapter.h"
// Copyright 2023 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -50,7 +51,13 @@ GlfwAdapter::GlfwAdapter() {
}

// multisampling
#ifdef mjBUILDSIMULATEXR
// window resampling must be disabled to allow different resolutions on monitor and VR headset
Glfw().glfwWindowHint(GLFW_SAMPLES, 0);
#else
Glfw().glfwWindowHint(GLFW_SAMPLES, 4);
#endif // mjBUILDSIMULATEXR

Glfw().glfwWindowHint(GLFW_VISIBLE, 1);

// get video mode and save
Expand Down Expand Up @@ -161,7 +168,13 @@ void GlfwAdapter::SetVSync(bool enabled){
core_video_.reset();
}
#else
#ifdef mjBUILDSIMULATEXR
// might interfere with frame loop timing
// TODO(AS) consider disabling it somewhere else?
Glfw().glfwSwapInterval(0);
#else // mjBUILDSIMULATEXR
Glfw().glfwSwapInterval(enabled);
#endif // mjBUILDSIMULATEXR
#endif
}

Expand Down
37 changes: 37 additions & 0 deletions simulate/simulate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2256,6 +2256,10 @@ void Simulate::LoadOnRenderThread() {
}
}

#ifdef mjBUILDSIMULATEXR
if (simXr.is_initialized()) simXr.set_vis_params(this->m_);
#endif // mjBUILDSIMULATEXR

// re-create scene and context
mjv_makeScene(this->m_, &this->scn, kMaxGeom);
if (this->is_passive_) {
Expand Down Expand Up @@ -2301,6 +2305,11 @@ void Simulate::LoadOnRenderThread() {
mjv_updateSceneState(this->m_, this->d_, &this->opt, &this->scnstate_);
}

#ifdef mjBUILDSIMULATEXR
if (simXr.is_initialized())
simXr.set_scn_params(&this->scn);
#endif // mjBUILDSIMULATEXR

// set window title to model name
if (this->m_->names) {
char title[200] = "MuJoCo : ";
Expand Down Expand Up @@ -2476,7 +2485,23 @@ void Simulate::Render() {
}

// render scene
#ifdef mjBUILDSIMULATEXR
if (simXr.is_initialized()) {
simXr.before_render(&this->scn, this->m_);
mjrRect rectXR = {0, 0, 0, 0};
rectXR.width = (int)simXr.width_render;
rectXR.height = (int)simXr.height;
// render in offscreen buffer
mjr_setBuffer(mjFB_OFFSCREEN, &this->platform_ui->mjr_context());
mjr_render(rectXR, &this->scn, &this->platform_ui->mjr_context());
simXr.after_render(&this->platform_ui->mjr_context());
mjr_setBuffer(mjFB_WINDOW, &this->platform_ui->mjr_context());
} else {
mjr_render(rect, &this->scn, &this->platform_ui->mjr_context());
}
#else //mjBUILDSIMULATEXR
mjr_render(rect, &this->scn, &this->platform_ui->mjr_context());
#endif //mjBUILDSIMULATEXR

// show last loading error
if (this->load_error[0]) {
Expand Down Expand Up @@ -2595,6 +2620,14 @@ void Simulate::Render() {


void Simulate::RenderLoop() {
#ifdef mjBUILDSIMULATEXR
simXr.init();
if (simXr.is_initialized()) {
simXr.set_scn_params(&this->scn);
simXr.set_vis_params(this->m_);
}
#endif // mjBUILDSIMULATEXR

// Set timer callback (milliseconds)
mjcb_time = Timer;

Expand Down Expand Up @@ -2733,6 +2766,10 @@ void Simulate::RenderLoop() {
mjv_freeSceneState(&scnstate_);
}

#ifdef mjBUILDSIMULATEXR
simXr.deinit();
#endif // mjBUILDSIMULATEXR

this->exitrequest.store(2);
}

Expand Down
8 changes: 8 additions & 0 deletions simulate/simulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include <mujoco/mujoco.h>
#include "platform_ui_adapter.h"

#ifdef mjBUILDSIMULATEXR
#include "simulate_xr/simulate_xr.h"
#endif // mjBUILDSIMULATEXR

namespace mujoco {

// The viewer itself doesn't require a reentrant mutex, however we use it in
Expand Down Expand Up @@ -249,6 +253,10 @@ class Simulate {
mjvFigure figsize = {};
mjvFigure figsensor = {};

#ifdef mjBUILDSIMULATEXR
SimulateXr simXr;
#endif // mjBUILDSIMULATEXR

// additional user-defined visualization geoms (used in passive mode)
mjvScene* user_scn = nullptr;
mjtByte user_scn_flags_prev_[mjNRNDFLAG];
Expand Down
Loading