From 9a62b97a6727acfb43a2c9c8dd7d58cedad6ea41 Mon Sep 17 00:00:00 2001 From: Benau Date: Tue, 16 Jul 2019 00:55:25 +0800 Subject: [PATCH] Fix multitouch in iOS --- lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.h | 38 +++++++++++++++++++ lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm | 24 ++++++------ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.h index 1b76b8807..0e4840f18 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.h +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.h @@ -14,6 +14,8 @@ #include "CIrrDeviceStub.h" #include "IrrlichtDevice.h" #include "IImagePresenter.h" +#include +#include namespace irr { @@ -75,6 +77,40 @@ namespace irr //! Returns true if system has native on screen keyboard virtual bool hasOnScreenKeyboard() const { return false; } + + //! Get a unique touch id per touch, create one if it's a new touch + size_t getTouchId(void* touch) + { + auto it = m_touch_id_map.find(touch); + if (it == m_touch_id_map.end()) + { + std::set ids; + for (auto& p : m_touch_id_map) + ids.insert(p.second); + size_t cur_id = 0; + while (true) + { + if (ids.find(cur_id) == ids.end()) + break; + cur_id++; + } + m_touch_id_map[touch] = cur_id; + return cur_id; + } + return it->second; + } + + //! Remove a unique touch id, free it for future usage + void removeTouchId(void* touch) + { + m_touch_id_map.erase(touch); + } + + //! Clear all unique touch ids, used when the app out focused + void clearAllTouchIds() + { + m_touch_id_map.clear(); + } private: void createWindow(); void createViewAndDriver(); @@ -82,6 +118,8 @@ namespace irr void* DataStorage; bool Close; + + std::map m_touch_id_map; }; } diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm b/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm index 7bc6a3c0c..a31b74e14 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceiOS.mm @@ -90,6 +90,7 @@ namespace irr { if (Device != nil) { + Device->clearAllTouchIds(); irr::SEvent ev; ev.EventType = irr::EET_APPLICATION_EVENT; ev.ApplicationEvent.EventType = irr::EAET_WILL_PAUSE; @@ -104,6 +105,7 @@ namespace irr { if (Device != nil) { + Device->clearAllTouchIds(); irr::SEvent ev; ev.EventType = irr::EET_APPLICATION_EVENT; ev.ApplicationEvent.EventType = irr::EAET_DID_PAUSE; @@ -118,6 +120,7 @@ namespace irr { if (Device != nil) { + Device->clearAllTouchIds(); irr::SEvent ev; ev.EventType = irr::EET_APPLICATION_EVENT; ev.ApplicationEvent.EventType = irr::EAET_WILL_RESUME; @@ -132,6 +135,7 @@ namespace irr { if (Device != nil) { + Device->clearAllTouchIds(); irr::SEvent ev; ev.EventType = irr::EET_APPLICATION_EVENT; ev.ApplicationEvent.EventType = irr::EAET_DID_RESUME; @@ -178,6 +182,7 @@ namespace irr @implementation CIrrViewiOS { irr::CIrrDeviceiOS* Device; + std::map m_touch_id_map; } - (id)initWithFrame:(CGRect)frame forDevice:(irr::CIrrDeviceiOS*)device forContext:(EAGLContext*)eagl_context @@ -187,16 +192,13 @@ namespace irr { self.drawableDepthFormat = GLKViewDrawableDepthFormat24; self.drawableStencilFormat = GLKViewDrawableStencilFormat8; + self.multipleTouchEnabled = YES; Device = device; } return self; } -- (BOOL)isMultipleTouchEnabled -{ - return YES; -} - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { @@ -206,11 +208,10 @@ namespace irr irr::core::position2d mouse_pos = irr::core::position2d(0, 0); bool simulate_mouse = false; - size_t id = 0; for (UITouch* touch in touches) { - ev.TouchInput.ID = id++; + ev.TouchInput.ID = Device->getTouchId(touch); CGPoint touchPoint = [touch locationInView:self]; @@ -237,11 +238,10 @@ namespace irr irr::core::position2d mouse_pos = irr::core::position2d(0, 0); bool simulate_mouse = false; - size_t id = 0; for (UITouch* touch in touches) { - ev.TouchInput.ID = id++; + ev.TouchInput.ID = Device->getTouchId(touch); CGPoint touchPoint = [touch locationInView:self]; @@ -268,11 +268,11 @@ namespace irr irr::core::position2d mouse_pos = irr::core::position2d(0, 0); bool simulate_mouse = false; - size_t id = 0; for (UITouch* touch in touches) { - ev.TouchInput.ID = id++; + ev.TouchInput.ID = Device->getTouchId(touch); + Device->removeTouchId(touch); CGPoint touchPoint = [touch locationInView:self]; @@ -299,11 +299,11 @@ namespace irr irr::core::position2d mouse_pos = irr::core::position2d(0, 0); bool simulate_mouse = false; - size_t id = 0; for (UITouch* touch in touches) { - ev.TouchInput.ID = id++; + ev.TouchInput.ID = Device->getTouchId(touch); + Device->removeTouchId(touch); CGPoint touchPoint = [touch locationInView:self];