Merge pull request #14528 from xiaofeng11/v3_3dtouch

Add 3d touch support to iOS 9.0 or higher version on iPhone6s or later device
This commit is contained in:
Ricardo Quesada 2015-12-03 22:21:48 -08:00
commit 0e34a864b2
9 changed files with 180 additions and 6 deletions

View File

@ -70,4 +70,16 @@ Vec2 Touch::getDelta() const
return getLocation() - getPreviousLocation();
}
// Returns the current touch force for 3d touch.
float Touch::getCurrentForce() const
{
return _curForce;
}
// Returns the maximum touch force for 3d touch.
float Touch::getMaxForce() const
{
return _maxForce;
}
NS_CC_END

View File

@ -57,7 +57,9 @@ public:
*/
Touch()
: _id(0),
_startPointCaptured(false)
_startPointCaptured(false),
_curForce(0.f),
_maxForce(0.f)
{}
/** Returns the current touch location in OpenGL coordinates.
@ -108,6 +110,32 @@ public:
_prevPoint = _point;
_point.x = x;
_point.y = y;
_curForce = 0.0f;
_maxForce = 0.0f;
if (!_startPointCaptured)
{
_startPoint = _point;
_startPointCaptured = true;
_prevPoint = _point;
}
}
/** Set the touch information. It always used to monitor touch event.
*
* @param id A given id
* @param x A given x coordinate.
* @param y A given y coordinate.
* @param force Current force for 3d touch.
* @param maxForce maximum possible force for 3d touch.
*/
void setTouchInfo(int id, float x, float y, float force, float maxForce)
{
_id = id;
_prevPoint = _point;
_point.x = x;
_point.y = y;
_curForce = force;
_maxForce = maxForce;
if (!_startPointCaptured)
{
_startPoint = _point;
@ -125,6 +153,16 @@ public:
{
return _id;
}
/** Returns the current touch force for 3d touch.
*
* @return The current touch force for 3d touch.
*/
float getCurrentForce() const;
/** Returns the maximum touch force for 3d touch.
*
* @return The maximum touch force for 3d touch.
*/
float getMaxForce() const;
private:
int _id;
@ -132,6 +170,8 @@ private:
Vec2 _startPoint;
Vec2 _point;
Vec2 _prevPoint;
float _curForce;
float _maxForce;
};
// end of base group

View File

@ -318,10 +318,17 @@ void GLView::handleTouchesBegin(int num, intptr_t ids[], float xs[], float ys[])
}
void GLView::handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[])
{
handleTouchesMove(num, ids, xs, ys, nullptr, nullptr);
}
void GLView::handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[], float fs[], float ms[])
{
intptr_t id = 0;
float x = 0.0f;
float y = 0.0f;
float force = 0.0f;
float maxForce = 0.0f;
EventTouch touchEvent;
for (int i = 0; i < num; ++i)
@ -329,6 +336,8 @@ void GLView::handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[])
id = ids[i];
x = xs[i];
y = ys[i];
force = fs ? fs[i] : 0.0f;
maxForce = ms ? ms[i] : 0.0f;
auto iter = g_touchIdReorderMap.find(id);
if (iter == g_touchIdReorderMap.end())
@ -337,12 +346,12 @@ void GLView::handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[])
continue;
}
CCLOGINFO("Moving touches with id: %d, x=%f, y=%f", id, x, y);
CCLOGINFO("Moving touches with id: %d, x=%f, y=%f, force=%f, maxFource=%f", id, x, y, force, maxForce);
Touch* touch = g_touches[iter->second];
if (touch)
{
touch->setTouchInfo(iter->second, (x - _viewPortRect.origin.x) / _scaleX,
(y - _viewPortRect.origin.y) / _scaleY);
(y - _viewPortRect.origin.y) / _scaleY, force, maxForce);
touchEvent._touches.push_back(touch);
}

View File

@ -313,6 +313,17 @@ public:
* @param ys The points of y.
*/
virtual void handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[]);
/** Touch events are handled by default; if you want to customize your handlers, please override this function.
*
* @param num The number of touch.
* @param ids The identity of the touch.
* @param xs The points of x.
* @param ys The points of y.
* @param fs The force of 3d touches.
# @param ms The maximum force of 3d touches
*/
virtual void handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[], float fs[], float ms[]);
/** Touch events are handled by default; if you want to customize your handlers, please override this function.
*

View File

@ -419,17 +419,27 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
UITouch* ids[IOS_MAX_TOUCHES_COUNT] = {0};
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
float fs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
float ms[IOS_MAX_TOUCHES_COUNT] = {0.0f};
int i = 0;
for (UITouch *touch in touches) {
ids[i] = touch;
xs[i] = [touch locationInView: [touch view]].x * self.contentScaleFactor;;
ys[i] = [touch locationInView: [touch view]].y * self.contentScaleFactor;;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 // Use 9.0 or higher SDK to compile
// running on iOS 9.0 or higher version
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0f) {
fs[i] = touch.force;
ms[i] = touch.maximumPossibleForce;
}
#endif
++i;
}
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
glview->handleTouchesMove(i, (intptr_t*)ids, xs, ys);
glview->handleTouchesMove(i, (intptr_t*)ids, xs, ys, fs, ms);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

View File

@ -22,6 +22,9 @@ enum
TouchesTests::TouchesTests()
{
ADD_TEST_CASE(PongScene);
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 // Use 9.0 or higher SDK to compile
ADD_TEST_CASE(ForceTouchTest);
#endif
}
//------------------------------------------------------------------
//
@ -111,3 +114,60 @@ void PongLayer::doStep(float delta)
else if (_ball->getPosition().y < VisibleRect::bottom().y-_ball->radius())
resetAndScoreBallForPlayer( kHighPlayer );
}
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 // Use 9.0 or higher SDK to compile
const char * _Info_Formatter = "Current force value : %0.02f, maximum possible force : %0.02f";
char formatBuffer[256] = {0, };
ForceTouchTest::ForceTouchTest()
{
auto s = Director::getInstance()->getWinSize();
_infoLabel = Label::createWithTTF(TTFConfig("fonts/arial.ttf"), "Current force value : 0.00, maximum possible force : 0.00");
_infoLabel->setPosition(s.width / 2, s.height / 2);
addChild(_infoLabel);
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan = CC_CALLBACK_2(ForceTouchTest::onTouchesBegan, this);
listener->onTouchesMoved = CC_CALLBACK_2(ForceTouchTest::onTouchesMoved, this);
listener->onTouchesEnded = CC_CALLBACK_2(ForceTouchTest::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
ForceTouchTest::~ForceTouchTest()
{
}
std::string ForceTouchTest::title() const
{
return std::string("3D Touch Test");
}
std::string ForceTouchTest::subtitle() const
{
return std::string("Touch with force to see info label changes");
}
void ForceTouchTest::onTouchesBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
{
}
void ForceTouchTest::onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
{
for(auto& t : touches)
{
float currentForce = t->getCurrentForce();
float maxForce = t->getMaxForce();
sprintf(formatBuffer, _Info_Formatter, currentForce, maxForce);
_infoLabel->setString(std::string(formatBuffer));
}
}
void ForceTouchTest::onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
{
sprintf(formatBuffer, _Info_Formatter, 0.0f, 0.0f);
_infoLabel->setString(std::string(formatBuffer));
}
#endif

View File

@ -31,4 +31,25 @@ public:
void doStep(float delta);
};
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 // Use 9.0 or higher SDK to compile
class ForceTouchTest : public TestCase
{
public:
CREATE_FUNC(ForceTouchTest);
virtual std::string title() const override;
virtual std::string subtitle() const override;
void onTouchesBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
void onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
void onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
protected:
ForceTouchTest();
virtual ~ForceTouchTest();
cocos2d::Label * _infoLabel;
};
#endif
#endif

View File

@ -253,7 +253,9 @@ var TouchAllAtOnce = EventTest.extend({
var touch = touches[i];
var pos = touch.getLocation();
var id = touch.getID();
cc.log("Touch #" + i + ". onTouchesMoved at: " + pos.x + " " + pos.y + " Id:" + id);
var force = touch.getCurrentForce();
var maxForce = touch.getMaxForce();
cc.log("Touch #" + i + ". onTouchesMoved at: " + pos.x + " " + pos.y + " Id:" + id + " current force:" + force + " maximum postible force:" + maxForce);
target.update_id(id, pos);
}
},

View File

@ -818,7 +818,16 @@ function RemoveAndRetainNodeTest:onEnter()
local target = event:getCurrentTarget()
local posX,posY = target:getPosition()
local delta = touch:getDelta()
target:setPosition(cc.p(posX + delta.x, posY + delta.y))
local force = touch:getCurrentForce()
local maxForce = touch:getMaxForce()
if force > 0.0 and (force / maxForce) > 0.8 then
local origin = cc.Director:getInstance():getVisibleOrigin()
local size = cc.Director:getInstance():getVisibleSize()
target:setPosition(cc.p(origin.x + size.width/2, origin.y + size.height/2))
print(string.format("3D touch detected, reset to default position. force = %f, max force = %f", force, maxForce))
else
target:setPosition(cc.p(posX + delta.x, posY + delta.y))
end
end
local function onTouchEnded(touch,event)