Skip to content

Refactor XR plugin #1395

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

Merged
merged 5 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 3 additions & 4 deletions Plugins/NativeXr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
set(SOURCES
"Include/Babylon/Plugins/NativeXr.h"
"Source/NativeXr.cpp")
set(HEADER "Include/Babylon/Plugins/NativeXr.h")
FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Source/*")

add_library(NativeXr ${SOURCES})
add_library(NativeXr ${SOURCES} ${HEADER})
warnings_as_errors(NativeXr)

target_include_directories(NativeXr
Expand Down
84 changes: 84 additions & 0 deletions Plugins/NativeXr/Source/Constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#pragma once

namespace Babylon
{
namespace Plugins
{
class XRFrame;
}

namespace
{
struct XRSessionType
{
static constexpr auto IMMERSIVE_VR{"immersive-vr"};
static constexpr auto IMMERSIVE_AR{"immersive-ar"};
static constexpr auto INLINE{"inline"};
};

struct XRReferenceSpaceType
{
static constexpr auto VIEWER{"viewer"};
// static constexpr auto LOCAL{"local"};
// static constexpr auto LOCAL_FLOOR{"local-floor"};
// static constexpr auto BOUNDED_FLOOR{"bounded-floor"};
static constexpr auto UNBOUNDED{"unbounded"};
};

struct XRHitTestTrackableType
{
static constexpr auto POINT{"point"};
static constexpr auto PLANE{"plane"};
static constexpr auto MESH{"mesh"};
};

struct XRImageTrackingState
{
//static constexpr auto UNTRACKED{"untracked"};
static constexpr auto TRACKED{"tracked"};
static constexpr auto EMULATED{"emulated"};
};

struct XREye
{
static constexpr auto NONE{"none"};
static constexpr auto LEFT{"left"};
static constexpr auto RIGHT{"right"};

static auto IndexToEye(size_t idx)
{
switch (idx)
{
case 0:
return LEFT;
case 1:
return RIGHT;
case 2:
return NONE;
default:
throw std::runtime_error{"Unsupported index"};
}
}

static uint32_t EyeToIndex(const std::string& eye)
{
if (eye == LEFT)
{
return 0;
}
else if (eye == RIGHT)
{
return 1;
}
else if (eye == NONE)
{
return 2;
}
else
{
throw std::runtime_error{"Unsupported eye"};
}
}
};
}
} // Babylon
52 changes: 52 additions & 0 deletions Plugins/NativeXr/Source/NativeRenderTargetProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

namespace Babylon
{
namespace
{
class NativeRenderTargetProvider : public Napi::ObjectWrap<NativeRenderTargetProvider>
{
static constexpr auto JS_CLASS_NAME = "NativeRenderTargetProvider";

public:
static void Initialize(Napi::Env env)
{
Napi::HandleScope scope{env};

Napi::Function func = DefineClass(
env,
JS_CLASS_NAME,
{
InstanceMethod("getRenderTargetForEye", &NativeRenderTargetProvider::GetRenderTargetForEye),
});

env.Global().Set(JS_CLASS_NAME, func);
}

static Napi::Object New(const Napi::CallbackInfo& info)
{
return info.Env().Global().Get(JS_CLASS_NAME).As<Napi::Function>().New({info[0], info[1], info[2]});
}

NativeRenderTargetProvider(const Napi::CallbackInfo& info)
: Napi::ObjectWrap<NativeRenderTargetProvider>{info}
, m_jsSession{Napi::Persistent(info[0].As<Napi::Object>())}
, m_session{*Plugins::XRSession::Unwrap(m_jsSession.Value())}
{
auto createRenderTexture{info[1].As<Napi::Function>()};
auto destroyRenderTexture{info[2].As<Napi::Function>()};
m_session.SetRenderTextureFunctions(createRenderTexture, destroyRenderTexture);
}

private:
Napi::ObjectReference m_jsSession{};
Plugins::XRSession& m_session;

Napi::Value GetRenderTargetForEye(const Napi::CallbackInfo& info)
{
const std::string eye{info[0].As<Napi::String>().Utf8Value()};
return m_session.GetRenderTargetForEye(eye);
}
};
}
} // Babylon
64 changes: 64 additions & 0 deletions Plugins/NativeXr/Source/NativeWebXRRenderTarget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#pragma once

#include "XRWebGLLayer.h"
#include "XRSession.h"

namespace Babylon
{
namespace
{
class NativeWebXRRenderTarget : public Napi::ObjectWrap<NativeWebXRRenderTarget>
{
static constexpr auto JS_CLASS_NAME = "NativeWebXRRenderTarget";

public:
static void Initialize(Napi::Env env)
{
Napi::HandleScope scope{env};

Napi::Function func = DefineClass(
env,
JS_CLASS_NAME,
{
InstanceMethod("initializeXRLayerAsync", &NativeWebXRRenderTarget::InitializeXRLayerAsync),
InstanceMethod("dispose", &NativeWebXRRenderTarget::Dispose),
});

env.Global().Set(JS_CLASS_NAME, func);
}

static Napi::Object New(const Napi::CallbackInfo& info)
{
return info.Env().Global().Get(JS_CLASS_NAME).As<Napi::Function>().New({info[0]});
}

NativeWebXRRenderTarget(const Napi::CallbackInfo& info)
: Napi::ObjectWrap<NativeWebXRRenderTarget>{info}
, m_jsEngineReference{Napi::Persistent(info[0].As<Napi::Object>())}
{
}

private:
// Lifetime control to prevent the cleanup of the NativeEngine while XR is still alive.
Napi::ObjectReference m_jsEngineReference{};

Napi::Value InitializeXRLayerAsync(const Napi::CallbackInfo& info)
{
auto& session = *Plugins::XRSession::Unwrap(info[0].As<Napi::Object>());

auto xrLayer = XRWebGLLayer::New(info);
session.InitializeXrLayer(xrLayer);
info.This().As<Napi::Object>().Set("xrLayer", xrLayer);

auto deferred = Napi::Promise::Deferred::New(info.Env());
deferred.Resolve(info.Env().Undefined());
return deferred.Promise();
}

Napi::Value Dispose(const Napi::CallbackInfo& info)
{
return info.Env().Undefined();
}
};
}
} // Babylon
Loading