From ef5440f738cdfb45469708a0c7ca13d03af5fc3e Mon Sep 17 00:00:00 2001 From: boyu0 Date: Thu, 7 Nov 2013 16:23:50 +0800 Subject: [PATCH] issue #2771: change rayCast and rectQuery callback class to std::function --- cocos/physics/CCPhysicsWorld.cpp | 28 +++-- cocos/physics/CCPhysicsWorld.h | 68 +++++------- .../Classes/PhysicsTest/PhysicsTest.cpp | 101 ++++++------------ .../TestCpp/Classes/PhysicsTest/PhysicsTest.h | 4 +- 4 files changed, 74 insertions(+), 127 deletions(-) diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index 976fb29e04..5b223bb798 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -73,7 +73,7 @@ namespace typedef struct RayCastCallbackInfo { PhysicsWorld* world; - PhysicsRayCastCallback* callback; + PhysicsRayCastCallbackFunc func; Point p1; Point p2; void* data; @@ -82,7 +82,7 @@ namespace typedef struct RectQueryCallbackInfo { PhysicsWorld* world; - PhysicsRectQueryCallback* callback; + PhysicsRectQueryCallbackFunc func; void* data; }RectQueryCallbackInfo; } @@ -148,7 +148,7 @@ void PhysicsWorldCallback::rayCastCallbackFunc(cpShape *shape, cpFloat t, cpVect auto it = PhysicsShapeInfo::getMap().find(shape); CC_ASSERT(it != PhysicsShapeInfo::getMap().end()); - PhysicsRayCastCallback::Info callbackInfo = + PhysicsRayCastInfo callbackInfo = { it->second->getShape(), info->p1, @@ -158,7 +158,7 @@ void PhysicsWorldCallback::rayCastCallbackFunc(cpShape *shape, cpFloat t, cpVect (float)t, }; - PhysicsWorldCallback::continues = info->callback->report(*info->world, callbackInfo, info->data); + PhysicsWorldCallback::continues = info->func(*info->world, callbackInfo, info->data); } void PhysicsWorldCallback::rectQueryCallbackFunc(cpShape *shape, RectQueryCallbackInfo *info) @@ -172,9 +172,7 @@ void PhysicsWorldCallback::rectQueryCallbackFunc(cpShape *shape, RectQueryCallba return; } - PhysicsWorldCallback::continues = info->callback->report(*info->world, - *it->second->getShape(), - info->data); + PhysicsWorldCallback::continues = info->func(*info->world, *it->second->getShape(), info->data); } void PhysicsWorldCallback::nearestPointQueryFunc(cpShape *shape, cpFloat distance, cpVect point, Array *arr) @@ -883,13 +881,13 @@ void PhysicsWorld::setGravity(const Vect& gravity) } -void PhysicsWorld::rayCast(PhysicsRayCastCallback& callback, const Point& point1, const Point& point2, void* data) +void PhysicsWorld::rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, const Point& point2, void* data) { - CCASSERT(callback.report != nullptr, "callback.report shouldn't be nullptr"); + CCASSERT(func != nullptr, "callback.report shouldn't be nullptr"); - if (callback.report != nullptr) + if (func != nullptr) { - RayCastCallbackInfo info = { this, &callback, point1, point2, data }; + RayCastCallbackInfo info = { this, func, point1, point2, data }; PhysicsWorldCallback::continues = true; cpSpaceSegmentQuery(this->_info->getSpace(), @@ -903,13 +901,13 @@ void PhysicsWorld::rayCast(PhysicsRayCastCallback& callback, const Point& point1 } -void PhysicsWorld::rectQuery(PhysicsRectQueryCallback& callback, const Rect& rect, void* data) +void PhysicsWorld::rectQuery(PhysicsRectQueryCallbackFunc func, const Rect& rect, void* data) { - CCASSERT(callback.report != nullptr, "callback.report shouldn't be nullptr"); + CCASSERT(func != nullptr, "callback.report shouldn't be nullptr"); - if (callback.report != nullptr) + if (func != nullptr) { - RectQueryCallbackInfo info = {this, &callback, data}; + RectQueryCallbackInfo info = {this, func, data}; PhysicsWorldCallback::continues = true; cpSpaceBBQuery(this->_info->getSpace(), diff --git a/cocos/physics/CCPhysicsWorld.h b/cocos/physics/CCPhysicsWorld.h index aee0dfefbd..240e3fa660 100644 --- a/cocos/physics/CCPhysicsWorld.h +++ b/cocos/physics/CCPhysicsWorld.h @@ -48,49 +48,31 @@ class Scene; class DrawNode; class PhysicsWorld; -class PhysicsRayCastCallback -{ -public: - typedef struct Info - { - PhysicsShape* shape; - Point start; - Point end; - Point contact; - Vect normal; - float fraction; - void* data; - }Info; - -public: - PhysicsRayCastCallback() - : report(nullptr) - {} - virtual ~PhysicsRayCastCallback(){} - /** - * @brief Called for each fixture found in the query. You control how the ray cast - * proceeds by returning a float: - * return true: continue - * return false: terminate the ray cast - * @param fixture the fixture hit by the ray - * @param point the point of initial intersection - * @param normal the normal vector at the point of intersection - * @return true to continue, false to terminate - */ - std::function report; -}; -class PhysicsRectQueryCallback + +typedef struct PhysicsRayCastInfo { -public: - PhysicsRectQueryCallback() - : report(nullptr) - {} - virtual ~PhysicsRectQueryCallback(){} - -public: - std::function report; -}; + PhysicsShape* shape; + Point start; + Point end; + Point contact; + Vect normal; + float fraction; + void* data; +}PhysicsRayCastInfo; + +/** + * @brief Called for each fixture found in the query. You control how the ray cast + * proceeds by returning a float: + * return true: continue + * return false: terminate the ray cast + * @param fixture the fixture hit by the ray + * @param point the point of initial intersection + * @param normal the normal vector at the point of intersection + * @return true to continue, false to terminate + */ +typedef std::function PhysicsRayCastCallbackFunc; +typedef std::function PhysicsRectQueryCallbackFunc; /** * @brief An PhysicsWorld object simulates collisions and other physical properties. You do not create PhysicsWorld objects directly; instead, you can get it from an Scene object. @@ -109,8 +91,8 @@ public: virtual void removeBody(int tag); virtual void removeAllBodies(); - void rayCast(PhysicsRayCastCallback& callback, const Point& point1, const Point& point2, void* data); - void rectQuery(PhysicsRectQueryCallback& callback, const Rect& rect, void* data); + void rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, const Point& point2, void* data); + void rectQuery(PhysicsRectQueryCallbackFunc func, const Rect& rect, void* data); Array* getShapes(const Point& point) const; PhysicsShape* getShape(const Point& point) const; Array* getAllBodies() const; diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 0885218d9a..af27626949 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -602,65 +602,12 @@ void PhysicsDemoRayCast::changeModeCallback(Object* sender) } } -bool PhysicsDemoRayCast::anyRay(PhysicsWorld& world, const PhysicsRayCastCallback::Info& info, void* data) +bool PhysicsDemoRayCast::anyRay(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data) { *((Point*)data) = info.contact; return false; } -class PhysicsDemoNearestRayCastCallback : public PhysicsRayCastCallback -{ -public: - PhysicsDemoNearestRayCastCallback(); - -private: - float _friction; -}; - -PhysicsDemoNearestRayCastCallback::PhysicsDemoNearestRayCastCallback() -: _friction(1.0f) -{ - report = [this](PhysicsWorld& world, const PhysicsRayCastCallback::Info& info, void* data)->bool - { - if (_friction > info.fraction) - { - *((Point*)data) = info.contact; - _friction = info.fraction; - } - - return true; - }; -} - -namespace -{ - static const int MAX_MULTI_RAYCAST_NUM = 5; -} - -class PhysicsDemoMultiRayCastCallback : public PhysicsRayCastCallback -{ -public: - PhysicsDemoMultiRayCastCallback(); - -public: - Point points[MAX_MULTI_RAYCAST_NUM]; - int num; -}; - -PhysicsDemoMultiRayCastCallback::PhysicsDemoMultiRayCastCallback() -: num(0) -{ - report = [this](PhysicsWorld& world, const PhysicsRayCastCallback::Info& info, void* data)->bool - { - if (num < MAX_MULTI_RAYCAST_NUM) - { - points[num++] = info.contact; - } - - return true; - }; -} - void PhysicsDemoRayCast::update(float delta) { float L = 150.0f; @@ -674,11 +621,10 @@ void PhysicsDemoRayCast::update(float delta) { case 0: { - PhysicsRayCastCallback callback; Point point3 = point2; - callback.report = CC_CALLBACK_3(PhysicsDemoRayCast::anyRay, this); + auto func = CC_CALLBACK_3(PhysicsDemoRayCast::anyRay, this); - _scene->getPhysicsWorld()->rayCast(callback, point1, point2, &point3); + _scene->getPhysicsWorld()->rayCast(func, point1, point2, &point3); _node->drawSegment(point1, point3, 1, STATIC_COLOR); if (point2 != point3) @@ -691,10 +637,20 @@ void PhysicsDemoRayCast::update(float delta) } case 1: { - PhysicsDemoNearestRayCastCallback callback; Point point3 = point2; + float friction = 1.0f; + PhysicsRayCastCallbackFunc func = [&point3, &friction](PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)->bool + { + if (friction > info.fraction) + { + point3 = info.contact; + friction = info.fraction; + } + + return true; + }; - _scene->getPhysicsWorld()->rayCast(callback, point1, point2, &point3); + _scene->getPhysicsWorld()->rayCast(func, point1, point2, nullptr); _node->drawSegment(point1, point3, 1, STATIC_COLOR); if (point2 != point3) @@ -707,15 +663,27 @@ void PhysicsDemoRayCast::update(float delta) } case 2: { - PhysicsDemoMultiRayCastCallback callback; +#define MAX_MULTI_RAYCAST_NUM 5 + Point points[MAX_MULTI_RAYCAST_NUM]; + int num = 0; - _scene->getPhysicsWorld()->rayCast(callback, point1, point2, nullptr); + PhysicsRayCastCallbackFunc func = [&points, &num](PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)->bool + { + if (num < MAX_MULTI_RAYCAST_NUM) + { + points[num++] = info.contact; + } + + return true; + }; + + _scene->getPhysicsWorld()->rayCast(func, point1, point2, nullptr); _node->drawSegment(point1, point2, 1, STATIC_COLOR); - for (int i = 0; i < callback.num; ++i) + for (int i = 0; i < num; ++i) { - _node->drawDot(callback.points[i], 2, Color4F(1.0f, 1.0f, 1.0f, 1.0f)); + _node->drawDot(points[i], 2, Color4F(1.0f, 1.0f, 1.0f, 1.0f)); } addChild(_node); @@ -1089,7 +1057,7 @@ void PhysicsDemoSlice::onEnter() addChild(box); } -bool PhysicsDemoSlice::slice(PhysicsWorld &world, const PhysicsRayCastCallback::Info &info, void *data) +bool PhysicsDemoSlice::slice(PhysicsWorld &world, const PhysicsRayCastInfo& info, void *data) { if (info.shape->getBody()->getTag() != _sliceTag) { @@ -1156,9 +1124,8 @@ void PhysicsDemoSlice::clipPoly(PhysicsShapePolygon* shape, Point normal, float void PhysicsDemoSlice::onTouchEnded(Touch *touch, Event *event) { - PhysicsRayCastCallback callback; - callback.report = CC_CALLBACK_3(PhysicsDemoSlice::slice, this); - _scene->getPhysicsWorld()->rayCast(callback, touch->getStartLocation(), touch->getLocation(), nullptr); + auto func = CC_CALLBACK_3(PhysicsDemoSlice::slice, this); + _scene->getPhysicsWorld()->rayCast(func, touch->getStartLocation(), touch->getLocation(), nullptr); } std::string PhysicsDemoSlice::title() diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h index 7355045cad..5235f92e34 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h @@ -96,7 +96,7 @@ public: void changeModeCallback(Object* sender); - bool anyRay(PhysicsWorld& world, const PhysicsRayCastCallback::Info& info, void* data); + bool anyRay(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data); private: float _angle; @@ -150,7 +150,7 @@ public: std::string title() override; std::string subtitle() override; - bool slice(PhysicsWorld& world, const PhysicsRayCastCallback::Info& info, void* data); + bool slice(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data); void clipPoly(PhysicsShapePolygon* shape, Point normal, float distance); bool onTouchBegan(Touch *touch, Event *event);