mirror of https://github.com/axmolengine/axmol.git
issue #2771: change rayCast and rectQuery callback class to std::function
This commit is contained in:
parent
eb508e4728
commit
ef5440f738
|
@ -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(),
|
||||
|
|
|
@ -48,49 +48,31 @@ class Scene;
|
|||
class DrawNode;
|
||||
|
||||
class PhysicsWorld;
|
||||
class PhysicsRayCastCallback
|
||||
|
||||
|
||||
typedef struct PhysicsRayCastInfo
|
||||
{
|
||||
public:
|
||||
typedef struct Info
|
||||
{
|
||||
PhysicsShape* shape;
|
||||
Point start;
|
||||
Point end;
|
||||
Point contact;
|
||||
Vect normal;
|
||||
float fraction;
|
||||
void* data;
|
||||
}Info;
|
||||
PhysicsShape* shape;
|
||||
Point start;
|
||||
Point end;
|
||||
Point contact;
|
||||
Vect normal;
|
||||
float fraction;
|
||||
void* data;
|
||||
}PhysicsRayCastInfo;
|
||||
|
||||
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<bool(PhysicsWorld& world, const Info& info, void* data)> report;
|
||||
};
|
||||
|
||||
class PhysicsRectQueryCallback
|
||||
{
|
||||
public:
|
||||
PhysicsRectQueryCallback()
|
||||
: report(nullptr)
|
||||
{}
|
||||
virtual ~PhysicsRectQueryCallback(){}
|
||||
|
||||
public:
|
||||
std::function<bool(PhysicsWorld&, PhysicsShape&, void*)> report;
|
||||
};
|
||||
/**
|
||||
* @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<bool(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)> PhysicsRayCastCallbackFunc;
|
||||
typedef std::function<bool(PhysicsWorld&, PhysicsShape&, void*)> 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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
_scene->getPhysicsWorld()->rayCast(callback, point1, point2, &point3);
|
||||
return true;
|
||||
};
|
||||
|
||||
_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()
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue