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

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

Merged
merged 3 commits into from
Sep 26, 2023
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
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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UNDEFINED?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as StickKeyCode:UNDEFINE / StickAxisCode::UNDEFINE

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