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
|
typedef struct RayCastCallbackInfo
|
||||||
{
|
{
|
||||||
PhysicsWorld* world;
|
PhysicsWorld* world;
|
||||||
PhysicsRayCastCallback* callback;
|
PhysicsRayCastCallbackFunc func;
|
||||||
Point p1;
|
Point p1;
|
||||||
Point p2;
|
Point p2;
|
||||||
void* data;
|
void* data;
|
||||||
|
@ -82,7 +82,7 @@ namespace
|
||||||
typedef struct RectQueryCallbackInfo
|
typedef struct RectQueryCallbackInfo
|
||||||
{
|
{
|
||||||
PhysicsWorld* world;
|
PhysicsWorld* world;
|
||||||
PhysicsRectQueryCallback* callback;
|
PhysicsRectQueryCallbackFunc func;
|
||||||
void* data;
|
void* data;
|
||||||
}RectQueryCallbackInfo;
|
}RectQueryCallbackInfo;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ void PhysicsWorldCallback::rayCastCallbackFunc(cpShape *shape, cpFloat t, cpVect
|
||||||
auto it = PhysicsShapeInfo::getMap().find(shape);
|
auto it = PhysicsShapeInfo::getMap().find(shape);
|
||||||
CC_ASSERT(it != PhysicsShapeInfo::getMap().end());
|
CC_ASSERT(it != PhysicsShapeInfo::getMap().end());
|
||||||
|
|
||||||
PhysicsRayCastCallback::Info callbackInfo =
|
PhysicsRayCastInfo callbackInfo =
|
||||||
{
|
{
|
||||||
it->second->getShape(),
|
it->second->getShape(),
|
||||||
info->p1,
|
info->p1,
|
||||||
|
@ -158,7 +158,7 @@ void PhysicsWorldCallback::rayCastCallbackFunc(cpShape *shape, cpFloat t, cpVect
|
||||||
(float)t,
|
(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)
|
void PhysicsWorldCallback::rectQueryCallbackFunc(cpShape *shape, RectQueryCallbackInfo *info)
|
||||||
|
@ -172,9 +172,7 @@ void PhysicsWorldCallback::rectQueryCallbackFunc(cpShape *shape, RectQueryCallba
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicsWorldCallback::continues = info->callback->report(*info->world,
|
PhysicsWorldCallback::continues = info->func(*info->world, *it->second->getShape(), info->data);
|
||||||
*it->second->getShape(),
|
|
||||||
info->data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsWorldCallback::nearestPointQueryFunc(cpShape *shape, cpFloat distance, cpVect point, Array *arr)
|
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;
|
PhysicsWorldCallback::continues = true;
|
||||||
cpSpaceSegmentQuery(this->_info->getSpace(),
|
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;
|
PhysicsWorldCallback::continues = true;
|
||||||
cpSpaceBBQuery(this->_info->getSpace(),
|
cpSpaceBBQuery(this->_info->getSpace(),
|
||||||
|
|
|
@ -48,11 +48,10 @@ class Scene;
|
||||||
class DrawNode;
|
class DrawNode;
|
||||||
|
|
||||||
class PhysicsWorld;
|
class PhysicsWorld;
|
||||||
class PhysicsRayCastCallback
|
|
||||||
|
|
||||||
|
typedef struct PhysicsRayCastInfo
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef struct Info
|
|
||||||
{
|
|
||||||
PhysicsShape* shape;
|
PhysicsShape* shape;
|
||||||
Point start;
|
Point start;
|
||||||
Point end;
|
Point end;
|
||||||
|
@ -60,14 +59,9 @@ public:
|
||||||
Vect normal;
|
Vect normal;
|
||||||
float fraction;
|
float fraction;
|
||||||
void* data;
|
void* data;
|
||||||
}Info;
|
}PhysicsRayCastInfo;
|
||||||
|
|
||||||
public:
|
/**
|
||||||
PhysicsRayCastCallback()
|
|
||||||
: report(nullptr)
|
|
||||||
{}
|
|
||||||
virtual ~PhysicsRayCastCallback(){}
|
|
||||||
/**
|
|
||||||
* @brief Called for each fixture found in the query. You control how the ray cast
|
* @brief Called for each fixture found in the query. You control how the ray cast
|
||||||
* proceeds by returning a float:
|
* proceeds by returning a float:
|
||||||
* return true: continue
|
* return true: continue
|
||||||
|
@ -77,20 +71,8 @@ public:
|
||||||
* @param normal the normal vector at the point of intersection
|
* @param normal the normal vector at the point of intersection
|
||||||
* @return true to continue, false to terminate
|
* @return true to continue, false to terminate
|
||||||
*/
|
*/
|
||||||
std::function<bool(PhysicsWorld& world, const Info& info, void* data)> report;
|
typedef std::function<bool(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)> PhysicsRayCastCallbackFunc;
|
||||||
};
|
typedef std::function<bool(PhysicsWorld&, PhysicsShape&, void*)> PhysicsRectQueryCallbackFunc;
|
||||||
|
|
||||||
class PhysicsRectQueryCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PhysicsRectQueryCallback()
|
|
||||||
: report(nullptr)
|
|
||||||
{}
|
|
||||||
virtual ~PhysicsRectQueryCallback(){}
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::function<bool(PhysicsWorld&, PhysicsShape&, void*)> report;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
* @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 removeBody(int tag);
|
||||||
virtual void removeAllBodies();
|
virtual void removeAllBodies();
|
||||||
|
|
||||||
void rayCast(PhysicsRayCastCallback& callback, const Point& point1, const Point& point2, void* data);
|
void rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, const Point& point2, void* data);
|
||||||
void rectQuery(PhysicsRectQueryCallback& callback, const Rect& rect, void* data);
|
void rectQuery(PhysicsRectQueryCallbackFunc func, const Rect& rect, void* data);
|
||||||
Array* getShapes(const Point& point) const;
|
Array* getShapes(const Point& point) const;
|
||||||
PhysicsShape* getShape(const Point& point) const;
|
PhysicsShape* getShape(const Point& point) const;
|
||||||
Array* getAllBodies() 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;
|
*((Point*)data) = info.contact;
|
||||||
return false;
|
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)
|
void PhysicsDemoRayCast::update(float delta)
|
||||||
{
|
{
|
||||||
float L = 150.0f;
|
float L = 150.0f;
|
||||||
|
@ -674,11 +621,10 @@ void PhysicsDemoRayCast::update(float delta)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
PhysicsRayCastCallback callback;
|
|
||||||
Point point3 = point2;
|
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);
|
_node->drawSegment(point1, point3, 1, STATIC_COLOR);
|
||||||
|
|
||||||
if (point2 != point3)
|
if (point2 != point3)
|
||||||
|
@ -691,10 +637,20 @@ void PhysicsDemoRayCast::update(float delta)
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
PhysicsDemoNearestRayCastCallback callback;
|
|
||||||
Point point3 = point2;
|
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);
|
_node->drawSegment(point1, point3, 1, STATIC_COLOR);
|
||||||
|
|
||||||
if (point2 != point3)
|
if (point2 != point3)
|
||||||
|
@ -707,15 +663,27 @@ void PhysicsDemoRayCast::update(float delta)
|
||||||
}
|
}
|
||||||
case 2:
|
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);
|
_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);
|
addChild(_node);
|
||||||
|
@ -1089,7 +1057,7 @@ void PhysicsDemoSlice::onEnter()
|
||||||
addChild(box);
|
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)
|
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)
|
void PhysicsDemoSlice::onTouchEnded(Touch *touch, Event *event)
|
||||||
{
|
{
|
||||||
PhysicsRayCastCallback callback;
|
auto func = CC_CALLBACK_3(PhysicsDemoSlice::slice, this);
|
||||||
callback.report = CC_CALLBACK_3(PhysicsDemoSlice::slice, this);
|
_scene->getPhysicsWorld()->rayCast(func, touch->getStartLocation(), touch->getLocation(), nullptr);
|
||||||
_scene->getPhysicsWorld()->rayCast(callback, touch->getStartLocation(), touch->getLocation(), nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PhysicsDemoSlice::title()
|
std::string PhysicsDemoSlice::title()
|
||||||
|
|
|
@ -96,7 +96,7 @@ public:
|
||||||
|
|
||||||
void changeModeCallback(Object* sender);
|
void changeModeCallback(Object* sender);
|
||||||
|
|
||||||
bool anyRay(PhysicsWorld& world, const PhysicsRayCastCallback::Info& info, void* data);
|
bool anyRay(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _angle;
|
float _angle;
|
||||||
|
@ -150,7 +150,7 @@ public:
|
||||||
std::string title() override;
|
std::string title() override;
|
||||||
std::string subtitle() 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);
|
void clipPoly(PhysicsShapePolygon* shape, Point normal, float distance);
|
||||||
|
|
||||||
bool onTouchBegan(Touch *touch, Event *event);
|
bool onTouchBegan(Touch *touch, Event *event);
|
||||||
|
|
Loading…
Reference in New Issue