Skip to content

Commit

Permalink
Refactor XR plugin (#1395)
Browse files Browse the repository at this point in the history
Splitting NativeXR into smaller chunks
  • Loading branch information
CedricGuillemet authored Jun 20, 2024
1 parent efb8fb2 commit b401d38
Show file tree
Hide file tree
Showing 27 changed files with 3,812 additions and 3,498 deletions.
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

0 comments on commit b401d38

Please sign in to comment.