...
 
Commits (142)
---
# Ideally we'd turn back on a few of these that are disabled near the end
Checks: 'clang-diagnostic-*,clang-analyzer-*,performance-*,bugprone-*,cert-*,readability-*,misc-*,-modernize-*,-clang-analyzer-security.insecureAPI.strcpy,-bugprone-macro-parentheses,-readability-braces-around-statements,-misc-unused-parameters,-readability-implicit-bool-conversion,-clang-diagnostic-missing-field-initializers,-clang-diagnostic-missing-braces'
WarningsAsErrors: ''
HeaderFilterRegex: 'src/xrt/.*'
AnalyzeTemporaryDtors: false
FormatStyle: file
...
......@@ -15,6 +15,10 @@ openxr_monado-dev.json
openxr_monado.json
src/xrt/compositor/shaders/*.vert.h
src/xrt/compositor/shaders/*.frag.h
src/xrt/targets/cli/monado-cli
src/xrt/targets/gui/monado-gui
src/xrt/targets/openxr/intermediate_manifest.json
src/xrt/targets/targets_enabled_drivers.h
# ignore build trees
build/
......@@ -29,3 +33,4 @@ build*/
# Ignore patches generated by scripts
patches/
......@@ -23,6 +23,8 @@ include:
stages:
- container_prep
- build
- pages
- deploy
debian:container_prep:
extends: .debian@container-ifnot-exists
......@@ -51,6 +53,9 @@ debian:build-cmake:
- pushd build
- cmake -GNinja ..
- ninja
artifacts:
paths:
- build/doc/html/
arch:build-cmake:
stage: build
......@@ -60,3 +65,18 @@ arch:build-cmake:
- pushd build
- cmake -GNinja ..
- ninja
###
# Pages
###
pages:
stage: pages
only:
- master
dependencies:
- debian:build-cmake
script:
- mv build/doc/html public
artifacts:
paths:
- public
......@@ -12,6 +12,7 @@ endif()
option(OPENXR_USE_LOADER "Application uses loader" ON)
option(OPENXR_INSTALL_ABSOLUTE_RUNTIME_PATH "Use the absolute path to the runtime in the installed manifest, rather than a bare filename." ON)
option(VULKAN_ENABLE_VALIDATION "Enable Vulkan validation for Compositor" ON)
option(INSTALL_ACTIVE_RUNTIME "Make Monado the default OpenXR runtime on install" ON)
###
# Dependencies
......@@ -28,6 +29,7 @@ find_package(OpenHMD)
find_package(OpenCV COMPONENTS core calib3d highgui imgproc imgcodecs features2d video)
find_package(Libusb1)
find_package(JPEG)
find_package(SDL2)
# @TODO Turn into a find_package LIBUVC file.
pkg_check_modules(LIBUVC libuvc)
......@@ -58,6 +60,7 @@ cmake_dependent_option(BUILD_WITH_LIBUVC "Enable libuvc video driver" ON "LIBUVC
cmake_dependent_option(BUILD_WITH_FFMPEG "Enable ffmpeg testing video driver" ON "FFMPEG_FOUND" OFF)
cmake_dependent_option(BUILD_WITH_HIDAPI "Enable HIDAPI-based driver(s) (OSVR HDK, PSVR)" ON "HIDAPI_FOUND" OFF)
cmake_dependent_option(BUILD_WITH_OPENHMD "Enable OpenHMD driver" ON "OPENHMD_FOUND" OFF)
cmake_dependent_option(BUILD_WITH_SDL2 "Enable SDL2 based test application" ON "SDL2_FOUND" OFF)
###
......@@ -83,6 +86,9 @@ endif()
if(BUILD_WITH_OPENCV)
add_definitions(-DXRT_HAVE_OPENCV)
# Tracking requires OpenCV
set(BUILD_TRACKING TRUE)
endif()
if(BUILD_WITH_JPEG)
......@@ -97,6 +103,18 @@ if(BUILD_WITH_FFMPEG)
add_definitions(-DXRT_HAVE_FFMPEG)
endif()
if(BUILD_WITH_SDL2)
add_definitions(-DXRT_HAVE_SDL2)
# Arch work around
if(NOT DEFINED SDL2_LIBRARIES)
set(SDL2_LIBRARIES SDL2::SDL2)
endif()
# SDL2 based gui
set(BUILD_TARGET_GUI TRUE)
endif()
if(BUILD_WITH_OPENHMD)
add_definitions(-DXRT_HAVE_OPENHMD)
......
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by this
license (the "Software") to use, reproduce, display, distribute, execute, and
transmit the Software, and to prepare derivative works of the Software, and to
permit third-parties to whom the Software is furnished to do so, all subject to
the following:
The copyright notices in the Software and this entire statement, including the
above license grant, this restriction and the following disclaimer, must be
included in all copies of the Software, in whole or in part, and all derivative
works of the Software, unless such copies or derivative works are solely in the
form of machine-executable object code generated by a source language
processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY
DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# Monado - XR Runtime (XRT)
> * Promotional homepage: <https://monado.dev>
> * Maintained at <https://gitlab.freedesktop.org/monado/monado>
> * Latest API documentation: <https://monado.pages.freedesktop.org/monado>
Monado is an open source XR runtime delivering immersive experiences such as VR
and AR on on mobile, PC/desktop, and any other device
(because gosh darn people
......@@ -26,30 +30,36 @@ and aims to support other operating systems in the near future.
Dependencies include:
* [CMake][] 3.10 or newer
* [OpenHMD][] (found using pkg-config)
* Vulkan headers
* OpenGL headers
* Eigen3
* glslang
* glslangValidator - Debian/Ubuntu package `glslang-tool`.
* libusb
* libudev
Optional (but recommended) dependencies:
* OpenGL headers for OpenGL graphics support
* libxcb and xcb-xrandr development packages
* [OpenHMD][] (found using pkg-config)
Truly optional dependencies:
Truly optional dependencies, useful for some drivers, app support, etc.:
* Doxygen
* Wayland development packages
* Xlib development pages
* libhidapi (for the HDK driver)
* Xlib development packages
* libhidapi
* OpenCV
* libuvc
* ffmpeg
* libjpeg
Tested distributions that are fully compatible,
on Intel and AMD graphics:
* Ubuntu 18.10 (18.04 does not work)
* Debian 10 `buster`
(currently the "testing" release -
current stable Stretch does not have new enough packages)
* Up-to-date package lists can be found in our CI config file,
`.gitlab-ci.yml`
These distributions include recent-enough versions of all the
software to use direct mode,
......
......@@ -20,6 +20,10 @@ PREDEFINED = VK_USE_PLATFORM_XCB_KHR \
VK_USE_PLATFORM_WAYLAND_KHR \
VK_USE_PLATFORM_XLIB_XRANDR_EXT \
XR_EXT_debug_utils \
XR_KHR_convert_timespec_time \
XR_KHR_opengl_enable \
XR_KHR_vulkan_enable \
XR_MND_headless \
XR_USE_GRAPHICS_API_OPENGL \
XR_USE_GRAPHICS_API_VULKAN \
XR_USE_PLATFORM_XLIB \
......@@ -40,6 +44,20 @@ ALWAYS_DETAILED_SEC = YES
WARN_IF_UNDOCUMENTED = @DOXYGEN_WARN_UNDOCUMENTED@
EXTRACT_ALL = @DOXYGEN_EXTRACT_ALL@
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
# header file to include in order to use a class. If left blank only the name of
# the header file containing the class definition is used. Otherwise one should
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH = \
@PROJECT_SOURCE_DIR@/src/xrt/include \
@PROJECT_SOURCE_DIR@/src/xrt/auxiliary \
@PROJECT_SOURCE_DIR@/src/xrt/compositor \
@PROJECT_SOURCE_DIR@/src/xrt/drivers \
@PROJECT_SOURCE_DIR@/src/xrt/state_trackers \
@PROJECT_SOURCE_DIR@/src/xrt/targets
# Doxyfile 1.8.13
# This file describes the settings to be used by the documentation system
......@@ -206,19 +224,6 @@ FULL_PATH_NAMES = YES
#STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
# header file to include in order to use a class. If left blank only the name of
# the header file containing the class definition is used. Otherwise one should
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH = src/xrt/auxiliary \
src/xrt/compositor \
src/xrt/drivers \
src/xrt/include \
src/xrt/state_trackers \
src/xrt/targets
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is yogur file systems doesn't
......@@ -1117,25 +1122,6 @@ USE_HTAGS = NO
VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
# cost of reduced performance. This can be particularly helpful with template
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse-libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
# the include paths will already be set by doxygen for the files and directories
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
......
# /usr/bin/env python3
# Copyright 2019, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
"""Simple script to update oxr_extension_support.h."""
from pathlib import Path
# Each extension that we implement gets an entry in this tuple.
# Each entry should be a list of defines that are checked for an extension:
# the first one must be the name of the extension itself.
# Keep sorted.
EXTENSIONS = (
['XR_EXT_debug_utils'],
['XR_KHR_convert_timespec_time', 'XR_USE_TIMESPEC'],
['XR_KHR_opengl_enable', 'XR_USE_GRAPHICS_API_OPENGL'],
['XR_KHR_vulkan_enable', 'XR_USE_GRAPHICS_API_VULKAN'],
['XR_MND_headless'],
)
ROOT = Path(__file__).resolve().parent.parent
FN = ROOT / 'src' / 'xrt'/'state_trackers' / 'oxr' / 'oxr_extension_support.h'
INVOCATION_PREFIX = 'OXR_EXTENSION_SUPPORT'
END_OF_PER_EXTENSION = '// end of per-extension defines - do not modify this comment - used by scripts'
CLANG_FORMAT_OFF = '// clang-format off'
CLANG_FORMAT_ON = '// clang-format on'
def trim_ext_name(name):
return name[3:]
def generate_first_chunk():
parts = []
for data in EXTENSIONS:
ext_name = data[0]
trimmed_name = trim_ext_name(ext_name)
upper_name = trimmed_name.upper()
condition = " && ".join("defined({})".format(x) for x in data)
parts.append(f"""
/*
* {ext_name}
*/
#if {condition}
#define OXR_HAVE_{trimmed_name}
#define {INVOCATION_PREFIX}_{trimmed_name}(_) \\
_({trimmed_name}, {upper_name})
#else
#define {INVOCATION_PREFIX}_{trimmed_name}(_)
#endif
""")
return '\n'.join(parts)
def generate_second_chunk():
trimmed_names = [trim_ext_name(data[0]) for data in EXTENSIONS]
invocations = ('{}_{}(_)'.format(INVOCATION_PREFIX, name)
for name in trimmed_names)
macro_lines = ['#define OXR_EXTENSION_SUPPORT_GENERATE(_)']
macro_lines.extend(invocations)
lines = [CLANG_FORMAT_OFF]
lines.append(' \\\n '.join(macro_lines))
lines.append(CLANG_FORMAT_ON)
return '\n'.join(lines)
if __name__ == "__main__":
with open(str(FN), 'r', encoding='utf-8') as fp:
orig = [line.rstrip() for line in fp.readlines()]
beginning = orig[:orig.index('#pragma once')+1]
middle_start = orig.index(END_OF_PER_EXTENSION)
middle_end = orig.index(CLANG_FORMAT_OFF)
middle = orig[middle_start:middle_end]
new_contents = beginning
new_contents.append(generate_first_chunk())
new_contents.extend(middle)
new_contents.append(generate_second_chunk())
with open(str(FN), 'w', encoding='utf-8') as fp:
fp.write('\n'.join(new_contents))
fp.write('\n')
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
//-----------------------------------------------------------------------------
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//-----------------------------------------------------------------------------
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/branch with your modifications to imconfig.h)
// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h"
// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include
// the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//-----------------------------------------------------------------------------
#pragma once
//---- Monado specific things
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM "glad/gl.h"
//---- Define assertion handler. Defaults to calling assert().
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
// Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
//#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport )
//---- Don't define obsolete functions/enums names. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
// It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
//#define IMGUI_DISABLE_DEMO_WINDOWS
//#define IMGUI_DISABLE_METRICS_WINDOW
//---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices').
//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf.
//#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h.
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
//---- Include imgui_user.h at the end of imgui.h as a convenience
//#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
//#define IMGUI_USE_BGRA_PACKED_COLOR
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
/*
#define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
operator MyVec2() const { return MyVec2(x,y); }
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/
//---- Using 32-bits vertex indices (default is 16-bits) is one way to allow large meshes with more than 64K vertices.
// Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bits indices).
// Another way to allow large meshes while keeping 16-bits indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly)
//struct ImDrawList;
//struct ImDrawCmd;
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback
//---- Debug Tools
// Use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.
//#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak()
// Have the Item Picker break in the ItemAdd() function instead of ItemHoverable() - which is earlier in the code, will catch a few extra items, allow picking items other than Hovered one.
// This adds a small runtime cost which is why it is not enabled by default.
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
}
*/
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
// - Desktop GL: 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
// Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bits indices.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
// About Desktop OpenGL function loaders:
// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
// About GLSL version:
// The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string.
// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
// Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
#pragma once
// Specific OpenGL versions
//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
// Set default OpenGL3 loader to be gl3w
#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
#define IMGUI_IMPL_OPENGL_LOADER_GL3W
#endif
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
// Called by Init/NewFrame/Shutdown
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
This diff is collapsed.
// dear imgui: Platform Binding for SDL2
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
// Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Clipboard support.
// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
#pragma once
struct SDL_Window;
typedef union SDL_Event SDL_Event;
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window);
IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(SDL_Window* window);
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -14,6 +14,17 @@ set(OS_SOURCE_FILES
os/os_documentation.h
os/os_hid.h
os/os_hid_hidraw.c
os/os_threading.h
)
set(TRACKING_SOURCE_FILES
tracking/t_calibration.cpp
tracking/t_convert.cpp
tracking/t_debug_hsv_filter.cpp
tracking/t_debug_hsv_picker.cpp
tracking/t_debug_hsv_viewer.cpp
tracking/t_hsv_filter.c
tracking/t_tracking.h
)
set(UTIL_SOURCE_FILES
......@@ -26,14 +37,20 @@ set(UTIL_SOURCE_FILES
util/u_documentation.h
util/u_format.c
util/u_format.h
util/u_frame.c
util/u_frame.h
util/u_hashmap.cpp
util/u_hashmap.h
util/u_hashset.cpp
util/u_hashset.h
util/u_sink.c
util/u_sink.h
util/u_sink_converter.c
util/u_sink_queue.c
util/u_sink_split.c
util/u_time.cpp
util/u_time.h
util/u_var.cpp
util/u_var.h
)
# Common includes
......@@ -60,3 +77,18 @@ set_property(TARGET aux_math PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(aux_math SYSTEM
PRIVATE ${EIGEN3_INCLUDE_DIR}
)
if(BUILD_TRACKING)
# Tracking library.
# Use OBJECT to not create a archive, since it just gets in the way.
add_library(aux_tracking OBJECT ${TRACKING_SOURCE_FILES})
set_property(TARGET aux_tracking PROPERTY POSITION_INDEPENDENT_CODE ON)
# Math files has extra include(s).
target_include_directories(aux_tracking SYSTEM
PRIVATE
${EIGEN3_INCLUDE_DIR}
${OpenCV_INCLUDE_DIRS}
)
endif()
......@@ -35,6 +35,19 @@ extern "C" {
* @brief C interface to some transform-related math functions.
*/
/*
*
* Defines.
*
*/
/*!
* Standard gravity acceleration constant.
*
* @ingroup aux_math
*/
#define MATH_GRAVITY_M_S2 (9.8066)
/*
*
......@@ -96,7 +109,7 @@ math_vec3_accum(const struct xrt_vec3 *additional, struct xrt_vec3 *inAndOut);
* @ingroup aux_math
*/
bool
math_quat_validate(const struct xrt_quat *qaut);
math_quat_validate(const struct xrt_quat *quat);
/*!
* Normalize a quaternion.
......
......@@ -61,10 +61,7 @@ math_vec3_validate(const struct xrt_vec3* vec3)
{
assert(vec3 != NULL);
if (!map_vec3(*vec3).allFinite()) {
return false;
}
return true;
return map_vec3(*vec3).allFinite();
}
extern "C" void
......
......@@ -52,7 +52,8 @@ os_hidraw_read(struct os_hid_device *ohdev,
if (ret == -1 || ret == 0) {
// Error or timeout.
return ret;
} else if (fds.revents & (POLLERR | POLLHUP | POLLNVAL)) {
}
if (fds.revents & (POLLERR | POLLHUP | POLLNVAL)) {
// Device disconnect?
return -1;
}
......@@ -109,7 +110,7 @@ os_hidraw_destroy(struct os_hid_device *ohdev)
}
int
os_hid_open_hidraw(const char *path, struct os_hid_device **out_ohdev)
os_hid_open_hidraw(const char *path, struct os_hid_device **out_hid)
{
struct hid_hidraw *hrdev = U_TYPED_CALLOC(struct hid_hidraw);
......@@ -124,7 +125,7 @@ os_hid_open_hidraw(const char *path, struct os_hid_device **out_ohdev)
return -1;
}
*out_ohdev = &hrdev->base;
*out_hid = &hrdev->base;
return 0;
}
......
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Wrapper around OS threading native functions.
* @author Jakob Bornecrantz <jakob@collabora.com>
*
* @ingroup aux_os
*/
#include "xrt/xrt_compiler.h"
#include "xrt/xrt_config.h"
#include "util/u_misc.h"
#ifdef XRT_OS_LINUX
#include <pthread.h>
#else
#error "OS not supported"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @ingroup aux_os
* @{
*/
/*
*
* Mutex
*
*/
/*!
* A wrapper around a native mutex.
*/
struct os_mutex
{
pthread_mutex_t mutex;
};
/*!
* Init.
*/
XRT_MAYBE_UNUSED static int
os_mutex_init(struct os_mutex *om)
{
return pthread_mutex_init(&om->mutex, NULL);
}
/*!
* Lock.
*/
XRT_MAYBE_UNUSED static void
os_mutex_lock(struct os_mutex *om)
{
pthread_mutex_lock(&om->mutex);
}
/*!
* Unlock.
*/
XRT_MAYBE_UNUSED static void
os_mutex_unlock(struct os_mutex *om)
{
pthread_mutex_unlock(&om->mutex);
}
/*!
* Clean up.
*/
XRT_MAYBE_UNUSED static void
os_mutex_destroy(struct os_mutex *om)
{
pthread_mutex_destroy(&om->mutex);
}
/*
*
* Thread.
*
*/
/*!
* A wrapper around a native mutex.
*/
struct os_thread
{
pthread_t thread;
};
/*!
* Run function.
*/
typedef void *(*os_run_func)(void *);
/*!
* Init.
*/
XRT_MAYBE_UNUSED static int
os_thread_init(struct os_thread *ost)
{
return 0;
}
/*!
* Start thread.
*/
XRT_MAYBE_UNUSED static int
os_thread_start(struct os_thread *ost, os_run_func func, void *ptr)
{
return pthread_create(&ost->thread, NULL, func, ptr);
}
/*!
* Join.
*/
XRT_MAYBE_UNUSED static void
os_thread_join(struct os_thread *ost)
{
void *retval;
pthread_join(ost->thread, &retval);
U_ZERO(&ost->thread);
}
/*!
* Destruction.
*/
XRT_MAYBE_UNUSED static void
os_thread_destroy(struct os_thread *ost)
{}
/*
*
* Fancy helper.
*
*/
/*!
* All in one helper that handles locking, waiting for change and starting a
* thread.
*/
struct os_thread_helper
{
pthread_t thread;
pthread_mutex_t mutex;
pthread_cond_t cond;
bool running;
};
/*!
* Initialize the thread helper.
*/
XRT_MAYBE_UNUSED static int
os_thread_helper_init(struct os_thread_helper *oth)
{
int ret = pthread_mutex_init(&oth->mutex, NULL);
if (ret != 0) {
return ret;
}
ret = pthread_cond_init(&oth->cond, NULL);
if (ret) {
pthread_mutex_destroy(&oth->mutex);
return ret;
}
return 0;
}
/*!
* Start the internal thread.
*/
XRT_MAYBE_UNUSED static int
os_thread_helper_start(struct os_thread_helper *oth,
os_run_func func,
void *ptr)
{
pthread_mutex_lock(&oth->mutex);
if (oth->running) {
pthread_mutex_unlock(&oth->mutex);
return -1;
}
int ret = pthread_create(&oth->thread, NULL, func, ptr);
if (ret != 0) {
pthread_mutex_unlock(&oth->mutex);
return ret;
}
oth->running = true;
pthread_mutex_unlock(&oth->mutex);
return 0;
}
/*!
* Stop the thread.
*/
XRT_MAYBE_UNUSED static int
os_thread_helper_stop(struct os_thread_helper *oth)
{
void *retval = NULL;
// The fields are protected.
pthread_mutex_lock(&oth->mutex);
if (!oth->running) {
pthread_mutex_unlock(&oth->mutex);
return 0;
}
// Stop the thread.
oth->running = false;
// Wake up the thread if it is waiting.
pthread_cond_signal(&oth->cond);
// No longer need to protect fields.
pthread_mutex_unlock(&oth->mutex);
// Wait for thread to finish.
pthread_join(oth->thread, &retval);
return 0;
}
/*!
* Destroy the thread helper, externally syncronizable.
*/
XRT_MAYBE_UNUSED static void
os_thread_helper_destroy(struct os_thread_helper *oth)
{
// Stop the thread.
os_thread_helper_stop(oth);
// Destroy resources.
pthread_mutex_destroy(&oth->mutex);
pthread_cond_destroy(&oth->cond);
}
/*!
* Lock the helper.
*/
XRT_MAYBE_UNUSED static void
os_thread_helper_lock(struct os_thread_helper *oth)
{
pthread_mutex_lock(&oth->mutex);
}
/*!
* Unlock the helper.
*/
XRT_MAYBE_UNUSED static void
os_thread_helper_unlock(struct os_thread_helper *oth)
{
pthread_mutex_unlock(&oth->mutex);
}
/*!
* Is the thread running, or suppised to be running.
*
* Must be called with the helper locked.
*/
XRT_MAYBE_UNUSED static bool
os_thread_helper_is_running_locked(struct os_thread_helper *oth)
{
return oth->running;
}
/*!
* Wait for a signal.
*
* Must be called with the helper locked.
*/
XRT_MAYBE_UNUSED static void
os_thread_helper_wait_locked(struct os_thread_helper *oth)
{
pthread_cond_wait(&oth->cond, &oth->mutex);
}
/*!
* Signal a waiting thread to wake up.
*
* Must be called with the helper locked.
*/
XRT_MAYBE_UNUSED static void
os_thread_helper_signal_locked(struct os_thread_helper *oth)
{
pthread_cond_signal(&oth->cond);
}
/*!
* @}
*/
#ifdef __cplusplus
} // extern "C"
#endif
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Calibration code.
* @author Pete Black <pblack@collabora.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
*/
#include "util/u_sink.h"
#include "util/u_misc.h"
#include "util/u_debug.h"
#include "util/u_format.h"
#include "tracking/t_tracking.h"
#include <opencv2/opencv.hpp>
DEBUG_GET_ONCE_BOOL_OPTION(hsv_filter, "T_DEBUG_HSV_FILTER", false)
DEBUG_GET_ONCE_BOOL_OPTION(hsv_picker, "T_DEBUG_HSV_PICKER", false)
DEBUG_GET_ONCE_BOOL_OPTION(hsv_viewer, "T_DEBUG_HSV_VIEWER", false)
/*
*
* Structs
*
*/
class Calibration
{
public:
struct xrt_frame_sink base = {};
struct
{
cv::Mat rgb = {};
struct xrt_frame_sink *sink = {};
} gui;
cv::Mat grey;
char text[512];
};
/*!
* Holds `cv::Mat`s used during frame processing when processing a yuyv frame.
*/
struct t_frame_yuyv
{
public:
//! Full frame size, each block is split across two cols.
cv::Mat data_full = {};
//! Half horizontal width covering a complete block of two pixels.
cv::Mat data_half = {};
};
/*
*
* Small helpers.
*
*/
static void
send_rgb_frame(struct xrt_frame_sink *xsink, cv::Mat &rgb)
{
struct xrt_frame xf = {};
xf.format = XRT_FORMAT_R8G8B8;
xf.width = rgb.cols;
xf.height = rgb.rows;
xf.data = rgb.data;
u_format_size_for_dimensions(xf.format, xf.width, xf.height, &xf.stride,
&xf.size);
xsink->push_frame(xsink, &xf);
}
static void
ensure_buffers_are_allocated(class Calibration &c, int rows, int cols)
{
if (c.gui.rgb.cols == cols && c.gui.rgb.rows == rows) {
return;
}
c.grey = cv::Mat(rows, cols, CV_8UC1, cv::Scalar(0));
c.gui.rgb = cv::Mat(rows, cols, CV_8UC3, cv::Scalar(0, 0, 0));
}
static void
print_txt(cv::Mat &rgb, const char *text, double fontScale)
{
int fontFace = 0;
int thickness = 2;
cv::Size textSize =
cv::getTextSize(text, fontFace, fontScale, thickness, NULL);
cv::Point textOrg((rgb.cols - textSize.width) / 2, textSize.height * 2);
cv::putText(rgb, text, textOrg, fontFace, fontScale,
cv::Scalar(192, 192, 192), thickness);
}
static void
make_gui_str(class Calibration &c)
{
auto &rgb = c.gui.rgb;
int cols = 800;
int rows = 100;
ensure_buffers_are_allocated(c, rows, cols);
cv::rectangle(rgb, cv::Point2f(0, 0), cv::Point2f(cols, rows),
cv::Scalar(0, 0, 0), -1, 0);
print_txt(rgb, c.text, 1.0);
send_rgb_frame(c.gui.sink, c.gui.rgb);
}
static void
make_calibration_frame(class Calibration &c)
{
auto &rgb = c.gui.rgb;
if (rgb.rows == 0 || rgb.cols == 0) {
ensure_buffers_are_allocated(c, 480, 640);
cv::rectangle(c.gui.rgb, cv::Point2f(0, 0),
cv::Point2f(rgb.cols, rgb.rows),
cv::Scalar(0, 0, 0), -1, 0);
}
/*
* Draw text
*/
print_txt(rgb, "CALIBRATION MODE", 1.5);
send_rgb_frame(c.gui.sink, rgb);
}
/*
*
* Main functions.
*
*/
static void
process_frame_yuv(class Calibration &c, struct xrt_frame *xf)
{
int w = (int)xf->width;
int h = (int)xf->height;
cv::Mat data(h, w, CV_8UC3, xf->data, xf->stride);
ensure_buffers_are_allocated(c, data.rows, data.cols);
cv::cvtColor(data, c.gui.rgb, cv::COLOR_YUV2RGB);
cv::cvtColor(c.gui.rgb, c.grey, cv::COLOR_RGB2GRAY);
}
static void
process_frame_yuyv(class Calibration &c, struct xrt_frame *xf)
{
/*
* Cleverly extract the different channels.
* Cr/Cb are extracted at half width.
*/
int w = (int)xf->width;
int half_w = w / 2;
int h = (int)xf->height;
struct t_frame_yuyv f = {};
f.data_half = cv::Mat(h, half_w, CV_8UC4, xf->data, xf->stride);
f.data_full = cv::Mat(h, w, CV_8UC2, xf->data, xf->stride);
ensure_buffers_are_allocated(c, f.data_full.rows, f.data_full.cols);
cv::cvtColor(f.data_full, c.gui.rgb, cv::COLOR_YUV2RGB_YUYV);
cv::cvtColor(f.data_full, c.grey, cv::COLOR_YUV2GRAY_YUYV);
}
/*
*
* Interface functions.
*
*/
extern "C" void
t_calibration_frame(struct xrt_frame_sink *xsink, struct xrt_frame *xf)
{
auto &c = *(class Calibration *)xsink;
#if 0
if (xf->stereo_format != XRT_FS_STEREO_SBS) {
snprintf(c.text, sizeof(c.text),
"ERROR: Not side by side stereo!");
make_gui_str(c);
return;
}
#endif
// Fill both c.gui.rgb and c.grey with the data we got.
switch (xf->format) {
case XRT_FORMAT_YUV888: process_frame_yuv(c, xf); break;
case XRT_FORMAT_YUV422: process_frame_yuyv(c, xf); break;
default:
snprintf(c.text, sizeof(c.text), "ERROR: Bad format '%s'",
u_format_str(xf->format));
make_gui_str(c);
return;
}
make_calibration_frame(c);
}
/*
*
* Exported functions.
*
*/
extern "C" int
t_calibration_create(struct xrt_frame_context *xfctx,
struct xrt_frame_sink *gui,
struct xrt_frame_sink **out_sink)
{
auto &c = *(new Calibration());
c.gui.sink = gui;
c.base.push_frame = t_calibration_frame;
*out_sink = &c.base;
snprintf(c.text, sizeof(c.text), "Waiting for camera");
make_gui_str(c);
int ret = 0;
if (debug_get_bool_option_hsv_filter()) {
ret = t_debug_hsv_filter_create(xfctx, *out_sink, out_sink);
}
if (debug_get_bool_option_hsv_picker()) {
ret = t_debug_hsv_picker_create(xfctx, *out_sink, out_sink);
}
if (debug_get_bool_option_hsv_viewer()) {
ret = t_debug_hsv_viewer_create(xfctx, *out_sink, out_sink);
}
// Ensure we only get yuv or yuyv frames.
u_sink_create_to_yuv_or_yuyv(xfctx, *out_sink, out_sink);
return ret;
}
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Code to build conversion tables and convert images.
* @author Jakob Bornecrantz <jakob@collabora.com>
*/
#include "tracking/t_tracking.h"
#include <opencv2/opencv.hpp>
/*
*
* 'Exported' functions.
*
*/
extern "C" void
t_convert_fill_table(struct t_convert_table *t)
{
for (int y = 0; y < 256; y++) {
for (int u = 0; u < 256; u++) {
uint8_t *dst = &t->v[y][u][0][0];
for (int v = 0; v < 256; v++) {
dst[0] = y;
dst[1] = u;
dst[2] = v;
dst += 3;
}
}
}
}
extern "C" void
t_convert_make_y8u8v8_to_r8g8b8(struct t_convert_table *t)
{
size_t size = 256 * 256 * 256;
t_convert_fill_table(t);
t_convert_in_place_y8u8v8_to_r8g8b8(size, 1, 0, t);
}
extern "C" void
t_convert_make_y8u8v8_to_h8s8v8(struct t_convert_table *t)
{
size_t size = 256 * 256 * 256;
t_convert_fill_table(t);
t_convert_in_place_y8u8v8_to_h8s8v8(size, 1, 0, &t->v);
}
extern "C" void
t_convert_make_h8s8v8_to_r8g8b8(struct t_convert_table *t)
{
size_t size = 256 * 256 * 256;
t_convert_fill_table(t);
t_convert_in_place_h8s8v8_to_r8g8b8(size, 1, 0, &t->v);
}
extern "C" void
t_convert_in_place_y8u8v8_to_r8g8b8(uint32_t width,
uint32_t height,
size_t stride,
void *data_ptr)
{
cv::Mat data(height, width, CV_8UC3, data_ptr, stride);
cv::cvtColor(data, data, cv::COLOR_YUV2RGB);
}
extern "C" void
t_convert_in_place_y8u8v8_to_h8s8v8(uint32_t width,
uint32_t height,
size_t stride,
void *data_ptr)
{
cv::Mat data(height, width, CV_8UC3, data_ptr, stride);
cv::Mat temp(height, width, CV_32FC3);
cv::cvtColor(data, temp, cv::COLOR_YUV2RGB);
cv::cvtColor(temp, data, cv::COLOR_RGB2HSV);
}
extern "C" void
t_convert_in_place_h8s8v8_to_r8g8b8(uint32_t width,
uint32_t height,
size_t stride,
void *data_ptr)
{
cv::Mat data(height, width, CV_8UC3, data_ptr, stride);
cv::cvtColor(data, data, cv::COLOR_YUV2RGB);
}
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief HSV filter debug code.
* @author Jakob Bornecrantz <jakob@collabora.com>
*/
#include "util/u_misc.h"
#include "util/u_debug.h"
#include "util/u_format.h"
#include "tracking/t_tracking.h"
#include <opencv2/opencv.hpp>
/*
*
* Defines and structs
*
*/
#define HSV0_WIN "HSV Channel #1 (Red)"
#define HSV1_WIN "HSV Channel #2 (Purple)"
#define HSV2_WIN "HSV Channel #3 (Blue)"
#define HSV3_WIN "HSV Channel #4 (White)"
class DebugHSV
{
public:
struct xrt_frame_sink base = {};
struct xrt_frame_node node = {};
struct xrt_frame_sink sinks[4] = {};
struct xrt_frame_sink *sink;
struct xrt_frame_sink *passthrough;
};
/*
*
* Exported functions.
*
*/
extern "C" void
t_debug_hsv_filter_frame0(struct xrt_frame_sink *xsink, struct xrt_frame *xf)
{
cv::Mat tmp(xf->height, xf->width, CV_8UC1, xf->data, xf->stride);
cv::imshow(HSV0_WIN, tmp);
}
extern "C" void
t_debug_hsv_filter_frame1(struct xrt_frame_sink *xsink, struct xrt_frame *xf)
{
cv::Mat tmp(xf->height, xf->width, CV_8UC1, xf->data, xf->stride);
cv::imshow(HSV1_WIN, tmp);
}
extern "C" void
t_debug_hsv_filter_frame2(struct xrt_frame_sink *xsink, struct xrt_frame *xf)
{
cv::Mat tmp(xf->height, xf->width, CV_8UC1, xf->data, xf->stride);
cv::imshow(HSV2_WIN, tmp);
}
extern "C" void
t_debug_hsv_filter_frame3(struct xrt_frame_sink *xsink, struct xrt_frame *xf)
{
cv::Mat tmp(xf->height, xf->width, CV_8UC1, xf->data, xf->stride);
cv::imshow(HSV3_WIN, tmp);
}
extern "C" void
t_debug_hsv_filter_frame(struct xrt_frame_sink *xsink, struct xrt_frame *xf)
{
auto &d = *(class DebugHSV *)xsink;
d.sink->push_frame(d.sink, xf);
d.passthrough->push_frame(d.passthrough, xf);
}
extern "C" void
t_debug_hsv_filter_break_apart(struct xrt_frame_node *node)
{}
extern "C" void
t_debug_hsv_filter_destroy(struct xrt_frame_node *node)
{
auto d = container_of(node, DebugHSV, node);
delete d;
}
extern "C" int
t_debug_hsv_filter_create(struct xrt_frame_context *xfctx,
struct xrt_frame_sink *passthrough,
struct xrt_frame_sink **