Skip to content

Commit

Permalink
feat:support xr controller a/b/x/y/trigger/thumbstick touch event (#1…
Browse files Browse the repository at this point in the history
…6293)

* feat:support xr controller a/b/x/y/trigger/thumbstick touch event

* fix:eslint problem

* refactor:add new enum/struct for touch event info
  • Loading branch information
oahc09 authored Sep 26, 2023
1 parent 9a42164 commit 2928e74
Show file tree
Hide file tree
Showing 11 changed files with 513 additions and 133 deletions.
6 changes: 6 additions & 0 deletions @types/jsb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ declare namespace jsb {
id: number;
axisInfoList: AxisInfo[],
buttonInfoList: ButtonInfo[],
touchInfoList: TouchInfo[],
}

export interface AxisInfo {
Expand All @@ -92,6 +93,11 @@ declare namespace jsb {
isPressed: boolean,
}

export interface TouchInfo {
code: number,
value: number,
}

export let onControllerInput: (infoList: ControllerInfo[]) => void | undefined;
export let onHandleInput: (infoList: ControllerInfo[]) => void | undefined;
export let onControllerChange: (controllerIds: number[]) => void | undefined;
Expand Down
12 changes: 12 additions & 0 deletions native/cocos/bindings/event/EventDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,20 @@ void EventDispatcher::dispatchControllerEvent(const ControllerEvent &controllerE
jsAxisInfoList->setArrayElement(axisIndex, se::Value(jsAxisInfo));
axisIndex++;
}

se::HandleObject jsTouchInfoList{se::Object::createArrayObject(static_cast<uint32_t>(controller->touchInfos.size()))};

uint32_t touchIndex = 0;
for (const auto &touchInfo : controller->touchInfos) {
se::HandleObject jsTouchInfo{se::Object::createPlainObject()};
jsTouchInfo->setProperty("code", se::Value(static_cast<uint32_t>(touchInfo.key)));
jsTouchInfo->setProperty("value", se::Value(touchInfo.value));
jsTouchInfoList->setArrayElement(touchIndex, se::Value(jsTouchInfo));
touchIndex++;
}
jsController->setProperty("axisInfoList", se::Value(jsAxisInfoList));
jsController->setProperty("buttonInfoList", se::Value(jsButtonInfoList));
jsController->setProperty("touchInfoList", se::Value(jsTouchInfoList));

jsControllerEventArray->setArrayElement(controllerIndex, se::Value(jsController));
controllerIndex++;
Expand Down
19 changes: 18 additions & 1 deletion native/cocos/engine/EngineEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,18 @@ enum class StickAxisCode {
RIGHT_GRIP,
};

enum class StickTouchCode {
UNDEFINE = 0,
A,
B,
X,
Y,
LEFT_TRIGGER,
RIGHT_TRIGGER,
LEFT_THUMBSTICK,
RIGHT_THUMBSTICK,
};

struct ControllerInfo {
struct AxisInfo {
StickAxisCode axis{StickAxisCode::UNDEFINE};
Expand All @@ -137,10 +149,15 @@ struct ControllerInfo {
bool isPress{false};
ButtonInfo(StickKeyCode key, bool isPress) : key(key), isPress(isPress) {}
};

struct TouchInfo {
StickTouchCode key{StickTouchCode::UNDEFINE};
float value{0.F};
TouchInfo(StickTouchCode key, float value) : key(key), value(value) {}
};
int napdId{0};
std::vector<AxisInfo> axisInfos;
std::vector<ButtonInfo> buttonInfos;
std::vector<TouchInfo> touchInfos;
};

struct ControllerEvent {
Expand Down
34 changes: 34 additions & 0 deletions native/cocos/platform/interfaces/modules/XRCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ enum class XRConfigKey {
EYE_RENDER_JS_CALLBACK = 54,
ASYNC_LOAD_ASSETS_IMAGE = 55,
ASYNC_LOAD_ASSETS_IMAGE_RESULTS = 56,
LEFT_CONTROLLER_ACTIVE = 57,
RIGHT_CONTROLLER_ACTIVE= 58,
MAX_COUNT
};

Expand Down Expand Up @@ -211,6 +213,7 @@ enum class XREventType {
STICK,
GRAB,
POSE,
TOUCH,
UNKNOWN
};

Expand Down Expand Up @@ -308,6 +311,37 @@ struct XRGrab : public XRControllerInfo {
}
};

struct XRTouch : public XRControllerInfo {
enum class Type {
TOUCH_A,
TOUCH_B,
TOUCH_X,
TOUCH_Y,
TOUCH_TRIGGER_LEFT,
TOUCH_TRIGGER_RIGHT,
TOUCH_THUMBSTICK_LEFT,
TOUCH_THUMBSTICK_RIGHT,
UNKNOWN
};

bool isActive = false;
float value = 0.F;
Type type = Type::UNKNOWN;

XRTouch(Type type, bool isActive)
: type(type),
isActive(isActive) {}

XRTouch(Type type, float value)
: type(type),
isActive(true),
value(value) {}

XREventType getXREventType() const override {
return XREventType::TOUCH;
}
};

struct XRPose : public XRControllerInfo {
enum class Type {
VIEW_LEFT,
Expand Down
197 changes: 110 additions & 87 deletions native/cocos/platform/java/modules/XRInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@ const static ccstd::unordered_map<xr::XRGrab::Type, StickAxisCode> GRAB_TYPE_TO_
{xr::XRGrab::Type::GRIP_RIGHT, StickAxisCode::RIGHT_GRIP},
};

const static ccstd::unordered_map<xr::XRTouch::Type, StickTouchCode> TOUCH_TYPE_TO_AXIS_CODE = {
{xr::XRTouch::Type::TOUCH_A, StickTouchCode::A},
{xr::XRTouch::Type::TOUCH_B, StickTouchCode::B},
{xr::XRTouch::Type::TOUCH_X, StickTouchCode::X},
{xr::XRTouch::Type::TOUCH_Y, StickTouchCode::Y},
{xr::XRTouch::Type::TOUCH_TRIGGER_LEFT, StickTouchCode::LEFT_TRIGGER},
{xr::XRTouch::Type::TOUCH_TRIGGER_RIGHT, StickTouchCode::RIGHT_TRIGGER},
{xr::XRTouch::Type::TOUCH_THUMBSTICK_LEFT, StickTouchCode::LEFT_THUMBSTICK},
{xr::XRTouch::Type::TOUCH_THUMBSTICK_RIGHT, StickTouchCode::RIGHT_THUMBSTICK},
};

void XRInterface::dispatchGamepadEventInternal(const xr::XRControllerEvent &xrControllerEvent) {
if (xrControllerEvent.xrControllerInfos.empty()) {
return;
Expand All @@ -102,48 +113,50 @@ void XRInterface::dispatchGamepadEventInternal(const xr::XRControllerEvent &xrCo
switch (xrControllerEvent.xrControllerInfos.at(i)->getXREventType()) {
case xr::XREventType::CLICK: {
auto *xrClick = static_cast<xr::XRClick *>(xrControllerEvent.xrControllerInfos.at(i).get());
StickKeyCode stickKeyCode = CLICK_TYPE_TO_KEY_CODE.at(xrClick->type);

switch (xrClick->type) {
case xr::XRClick::Type::MENU:
case xr::XRClick::Type::TRIGGER_LEFT:
case xr::XRClick::Type::SHOULDER_LEFT:
case xr::XRClick::Type::THUMBSTICK_LEFT:
case xr::XRClick::Type::X:
case xr::XRClick::Type::Y:
case xr::XRClick::Type::TRIGGER_RIGHT:
case xr::XRClick::Type::SHOULDER_RIGHT:
case xr::XRClick::Type::THUMBSTICK_RIGHT:
case xr::XRClick::Type::A:
case xr::XRClick::Type::B:
case xr::XRClick::Type::START: {
controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(stickKeyCode, xrClick->isPress));
break;
}
case xr::XRClick::Type::HOME: {
CC_LOG_INFO("[XRInterface] dispatchGamepadEventInternal exit when home click in rokid.");
if(CLICK_TYPE_TO_KEY_CODE.count(xrClick->type) > 0) {
StickKeyCode stickKeyCode = CLICK_TYPE_TO_KEY_CODE.at(xrClick->type);

switch (xrClick->type) {
case xr::XRClick::Type::MENU:
case xr::XRClick::Type::TRIGGER_LEFT:
case xr::XRClick::Type::SHOULDER_LEFT:
case xr::XRClick::Type::THUMBSTICK_LEFT:
case xr::XRClick::Type::X:
case xr::XRClick::Type::Y:
case xr::XRClick::Type::TRIGGER_RIGHT:
case xr::XRClick::Type::SHOULDER_RIGHT:
case xr::XRClick::Type::THUMBSTICK_RIGHT:
case xr::XRClick::Type::A:
case xr::XRClick::Type::B:
case xr::XRClick::Type::START: {
controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(stickKeyCode, xrClick->isPress));
break;
}
case xr::XRClick::Type::HOME: {
CC_LOG_INFO("[XRInterface] dispatchGamepadEventInternal exit when home click in rokid.");
#if CC_USE_XR
xr::XrEntry::getInstance()->destroyXrInstance();
xr::XrEntry::destroyInstance();
_isXrEntryInstanceValid = false;
xr::XrEntry::getInstance()->destroyXrInstance();
xr::XrEntry::destroyInstance();
_isXrEntryInstanceValid = false;
#endif
CC_CURRENT_APPLICATION_SAFE()->close();
break;
CC_CURRENT_APPLICATION_SAFE()->close();
break;
}
case xr::XRClick::Type::DPAD_UP:
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::Y, xrClick->isPress ? 1.F : 0.F));
break;
case xr::XRClick::Type::DPAD_DOWN:
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::Y, xrClick->isPress ? -1.F : 0.F));
break;
case xr::XRClick::Type::DPAD_LEFT:
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::X, xrClick->isPress ? -1.F : 0.F));
break;
case xr::XRClick::Type::DPAD_RIGHT:
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::X, xrClick->isPress ? 1.F : 0.F));
break;
default:
break;
}
case xr::XRClick::Type::DPAD_UP:
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::Y, xrClick->isPress ? 1.F : 0.F));
break;
case xr::XRClick::Type::DPAD_DOWN:
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::Y, xrClick->isPress ? -1.F : 0.F));
break;
case xr::XRClick::Type::DPAD_LEFT:
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::X, xrClick->isPress ? -1.F : 0.F));
break;
case xr::XRClick::Type::DPAD_RIGHT:
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(StickAxisCode::X, xrClick->isPress ? 1.F : 0.F));
break;
default:
break;
}
} break;
case xr::XREventType::STICK: {
Expand All @@ -163,15 +176,17 @@ void XRInterface::dispatchGamepadEventInternal(const xr::XRControllerEvent &xrCo
} break;
case xr::XREventType::GRAB: {
auto *xrGrab = static_cast<xr::XRGrab *>(xrControllerEvent.xrControllerInfos.at(i).get());
StickAxisCode stickAxisCode = GRAB_TYPE_TO_AXIS_CODE.at(xrGrab->type);
switch (xrGrab->type) {
case xr::XRGrab::Type::TRIGGER_LEFT:
case xr::XRGrab::Type::TRIGGER_RIGHT: {
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(stickAxisCode, xrGrab->value));
break;
if(GRAB_TYPE_TO_AXIS_CODE.count(xrGrab->type) > 0) {
StickAxisCode stickAxisCode = GRAB_TYPE_TO_AXIS_CODE.at(xrGrab->type);
switch (xrGrab->type) {
case xr::XRGrab::Type::TRIGGER_LEFT:
case xr::XRGrab::Type::TRIGGER_RIGHT: {
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(stickAxisCode, xrGrab->value));
break;
}
default:
break;
}
default:
break;
}
} break;
default:
Expand Down Expand Up @@ -219,41 +234,43 @@ void XRInterface::dispatchHandleEventInternal(const xr::XRControllerEvent &xrCon
switch (xrControllerEvent.xrControllerInfos.at(i)->getXREventType()) {
case xr::XREventType::CLICK: {
auto *xrClick = static_cast<xr::XRClick *>(xrControllerEvent.xrControllerInfos.at(i).get());
StickKeyCode stickKeyCode = CLICK_TYPE_TO_KEY_CODE.at(xrClick->type);
switch (xrClick->type) {
case xr::XRClick::Type::MENU: {
if(CLICK_TYPE_TO_KEY_CODE.count(xrClick->type) > 0) {
StickKeyCode stickKeyCode = CLICK_TYPE_TO_KEY_CODE.at(xrClick->type);
switch (xrClick->type) {
case xr::XRClick::Type::MENU: {
#if !XR_OEM_SEED
controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(StickKeyCode::MENU, xrClick->isPress));
controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(StickKeyCode::MENU, xrClick->isPress));
#else
CC_LOG_INFO("[XRInterface] exit when menu click in seed.");
CC_LOG_INFO("[XRInterface] exit when menu click in seed.");
CC_CURRENT_APPLICATION_SAFE()->close();
#endif
break;
}
case xr::XRClick::Type::TRIGGER_LEFT:
case xr::XRClick::Type::THUMBSTICK_LEFT:
case xr::XRClick::Type::X:
case xr::XRClick::Type::Y:
case xr::XRClick::Type::TRIGGER_RIGHT:
case xr::XRClick::Type::THUMBSTICK_RIGHT:
case xr::XRClick::Type::A:
case xr::XRClick::Type::B:
case xr::XRClick::Type::START: {
controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(stickKeyCode, xrClick->isPress));
break;
}
case xr::XRClick::Type::HOME: {
CC_LOG_INFO("[XRInterface] dispatchHandleEventInternal exit when home click in rokid.");
break;
}
case xr::XRClick::Type::TRIGGER_LEFT:
case xr::XRClick::Type::THUMBSTICK_LEFT:
case xr::XRClick::Type::X:
case xr::XRClick::Type::Y:
case xr::XRClick::Type::TRIGGER_RIGHT:
case xr::XRClick::Type::THUMBSTICK_RIGHT:
case xr::XRClick::Type::A:
case xr::XRClick::Type::B:
case xr::XRClick::Type::START: {
controllerInfo->buttonInfos.emplace_back(ControllerInfo::ButtonInfo(stickKeyCode, xrClick->isPress));
break;
}
case xr::XRClick::Type::HOME: {
CC_LOG_INFO("[XRInterface] dispatchHandleEventInternal exit when home click in rokid.");
#if CC_USE_XR
xr::XrEntry::getInstance()->destroyXrInstance();
xr::XrEntry::destroyInstance();
_isXrEntryInstanceValid = false;
xr::XrEntry::getInstance()->destroyXrInstance();
xr::XrEntry::destroyInstance();
_isXrEntryInstanceValid = false;
#endif
CC_CURRENT_APPLICATION_SAFE()->close();
break;
CC_CURRENT_APPLICATION_SAFE()->close();
break;
}
default:
break;
}
default:
break;
}
} break;
case xr::XREventType::STICK: {
Expand All @@ -273,19 +290,19 @@ void XRInterface::dispatchHandleEventInternal(const xr::XRControllerEvent &xrCon
} break;
case xr::XREventType::GRAB: {
auto *xrGrab = static_cast<xr::XRGrab *>(xrControllerEvent.xrControllerInfos.at(i).get());
StickAxisCode stickAxisCode = GRAB_TYPE_TO_AXIS_CODE.at(xrGrab->type);
switch (xrGrab->type) {
case xr::XRGrab::Type::TRIGGER_LEFT:
case xr::XRGrab::Type::TRIGGER_RIGHT:
case xr::XRGrab::Type::GRIP_LEFT:
case xr::XRGrab::Type::GRIP_RIGHT: {
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(stickAxisCode, xrGrab->value));
break;
}
default:
break;
if(GRAB_TYPE_TO_AXIS_CODE.count(xrGrab->type) > 0) {
StickAxisCode stickAxisCode = GRAB_TYPE_TO_AXIS_CODE.at(xrGrab->type);
controllerInfo->axisInfos.emplace_back(ControllerInfo::AxisInfo(stickAxisCode, xrGrab->value));
}
} break;
case xr::XREventType::TOUCH: {
auto *xrTouch = static_cast<xr::XRTouch *>(xrControllerEvent.xrControllerInfos.at(i).get());
if(TOUCH_TYPE_TO_AXIS_CODE.count(xrTouch->type) > 0) {
StickTouchCode stickTouchCode = TOUCH_TYPE_TO_AXIS_CODE.at(xrTouch->type);
controllerInfo->touchInfos.emplace_back(ControllerInfo::TouchInfo(stickTouchCode, xrTouch->value));
}
break;
}
case xr::XREventType::POSE: {
auto *xrPose = static_cast<xr::XRPose *>(xrControllerEvent.xrControllerInfos.at(i).get());
switch (xrPose->type) {
Expand Down Expand Up @@ -325,7 +342,7 @@ void XRInterface::dispatchHandleEventInternal(const xr::XRControllerEvent &xrCon
EventDispatcher::doDispatchJsEvent("onHandlePoseInput", args);
}

if (!controllerInfo->buttonInfos.empty() || !controllerInfo->axisInfos.empty()) {
if (!controllerInfo->buttonInfos.empty() || !controllerInfo->axisInfos.empty() || !controllerInfo->touchInfos.empty()) {
controllerInfo->napdId = 0; // xr only one handle connection
_controllerEvent.controllerInfos.emplace_back(controllerInfo);
_controllerEvent.type = ControllerEvent::Type::HANDLE;
Expand All @@ -342,6 +359,12 @@ void XRInterface::dispatchHandleEventInternal(const xr::XRControllerEvent &xrCon
_xrRemotePreviewManager->sendControllerKeyInfo(axisInfo);
}
}

if (!controllerInfo->touchInfos.empty()) {
for (const auto &touchInfo : controllerInfo->touchInfos) {
_xrRemotePreviewManager->sendControllerKeyInfo(touchInfo);
}
}
}
#endif
events::Controller::broadcast(_controllerEvent);
Expand Down
Loading

0 comments on commit 2928e74

Please sign in to comment.