mirror of https://github.com/axmolengine/axmol.git
issue #2771: add ray cast test
This commit is contained in:
parent
e99b80b304
commit
24561860f0
|
@ -97,7 +97,7 @@ public:
|
||||||
virtual Point getOffset() { return Point::ZERO; }
|
virtual Point getOffset() { return Point::ZERO; }
|
||||||
virtual Point getCenter() { return getOffset(); }
|
virtual Point getCenter() { return getOffset(); }
|
||||||
|
|
||||||
static Point* recenterPoints(Point* points, int count, Point center);
|
static Point* recenterPoints(Point* points, int count, Point center = Point::ZERO);
|
||||||
static Point getPolyonCenter(Point* points, int count);
|
static Point getPolyonCenter(Point* points, int count);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
static void rayCastCallbackFunc(cpShape *shape, cpFloat t, cpVect n, RayCastCallbackInfo *info);
|
static void rayCastCallbackFunc(cpShape *shape, cpFloat t, cpVect n, RayCastCallbackInfo *info);
|
||||||
static void rectQueryCallbackFunc(cpShape *shape, RectQueryCallbackInfo *info);
|
static void rectQueryCallbackFunc(cpShape *shape, RectQueryCallbackInfo *info);
|
||||||
|
|
||||||
private:
|
public:
|
||||||
static bool continues;
|
static bool continues;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -391,12 +391,16 @@ void PhysicsWorld::drawWithShape(DrawNode* node, PhysicsShape* shape)
|
||||||
Point centre = PhysicsHelper::cpv2point(cpBodyGetPos(cpShapeGetBody(shape)))
|
Point centre = PhysicsHelper::cpv2point(cpBodyGetPos(cpShapeGetBody(shape)))
|
||||||
+ PhysicsHelper::cpv2point(cpCircleShapeGetOffset(shape));
|
+ PhysicsHelper::cpv2point(cpCircleShapeGetOffset(shape));
|
||||||
|
|
||||||
Point seg[4] = {};
|
static const int CIRCLE_SEG_NUM = 12;
|
||||||
seg[0] = Point(centre.x - radius, centre.y - radius);
|
Point seg[CIRCLE_SEG_NUM] = {};
|
||||||
seg[1] = Point(centre.x - radius, centre.y + radius);
|
|
||||||
seg[2] = Point(centre.x + radius, centre.y + radius);
|
for (int i = 0; i < CIRCLE_SEG_NUM; ++i)
|
||||||
seg[3] = Point(centre.x + radius, centre.y - radius);
|
{
|
||||||
node->drawPolygon(seg, 4, Color4F(), 1, Color4F(1, 0, 0, 1));
|
float angle = (float)i * M_PI / (float)CIRCLE_SEG_NUM * 2.0f;
|
||||||
|
Point d(radius * cosf(angle), radius * sinf(angle));
|
||||||
|
seg[i] = centre + d;
|
||||||
|
}
|
||||||
|
node->drawPolygon(seg, CIRCLE_SEG_NUM, Color4F(1.0f, 0.0f, 0.0f, 0.3f), 1, Color4F(1, 0, 0, 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CP_SEGMENT_SHAPE:
|
case CP_SEGMENT_SHAPE:
|
||||||
|
@ -525,7 +529,11 @@ void PhysicsWorld::setGravity(Point gravity)
|
||||||
|
|
||||||
void PhysicsWorld::rayCast(PhysicsRayCastCallback& callback, Point point1, Point point2, void* data)
|
void PhysicsWorld::rayCast(PhysicsRayCastCallback& callback, Point point1, Point point2, void* data)
|
||||||
{
|
{
|
||||||
|
if (callback.report != nullptr)
|
||||||
|
{
|
||||||
RayCastCallbackInfo info = {this, &callback, point1, point2, data};
|
RayCastCallbackInfo info = {this, &callback, point1, point2, data};
|
||||||
|
|
||||||
|
PhysicsWorldCallback::continues = true;
|
||||||
cpSpaceSegmentQuery(this->_info->space,
|
cpSpaceSegmentQuery(this->_info->space,
|
||||||
PhysicsHelper::point2cpv(point1),
|
PhysicsHelper::point2cpv(point1),
|
||||||
PhysicsHelper::point2cpv(point2),
|
PhysicsHelper::point2cpv(point2),
|
||||||
|
@ -533,18 +541,24 @@ void PhysicsWorld::rayCast(PhysicsRayCastCallback& callback, Point point1, Point
|
||||||
CP_NO_GROUP,
|
CP_NO_GROUP,
|
||||||
(cpSpaceSegmentQueryFunc)PhysicsWorldCallback::rayCastCallbackFunc,
|
(cpSpaceSegmentQueryFunc)PhysicsWorldCallback::rayCastCallbackFunc,
|
||||||
&info);
|
&info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PhysicsWorld::rectQuery(PhysicsRectQueryCallback& callback, Rect rect, void* data)
|
void PhysicsWorld::rectQuery(PhysicsRectQueryCallback& callback, Rect rect, void* data)
|
||||||
{
|
{
|
||||||
|
if (callback.report != nullptr)
|
||||||
|
{
|
||||||
RectQueryCallbackInfo info = {this, &callback, data};
|
RectQueryCallbackInfo info = {this, &callback, data};
|
||||||
|
|
||||||
|
PhysicsWorldCallback::continues = true;
|
||||||
cpSpaceBBQuery(this->_info->space,
|
cpSpaceBBQuery(this->_info->space,
|
||||||
PhysicsHelper::rect2cpbb(rect),
|
PhysicsHelper::rect2cpbb(rect),
|
||||||
CP_ALL_LAYERS,
|
CP_ALL_LAYERS,
|
||||||
CP_NO_GROUP,
|
CP_NO_GROUP,
|
||||||
(cpSpaceBBQueryFunc)PhysicsWorldCallback::rectQueryCallbackFunc,
|
(cpSpaceBBQueryFunc)PhysicsWorldCallback::rectQueryCallbackFunc,
|
||||||
&info);
|
&info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Array* PhysicsWorld::getAllBody() const
|
Array* PhysicsWorld::getAllBody() const
|
||||||
|
|
|
@ -53,6 +53,10 @@ class PhysicsWorld;
|
||||||
class PhysicsRayCastCallback
|
class PhysicsRayCastCallback
|
||||||
{
|
{
|
||||||
public:
|
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:
|
||||||
|
@ -63,13 +67,19 @@ 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&, PhysicsShape&, Point point, Point normal, float fraction, void* data)> report;
|
std::function<bool(PhysicsWorld&, PhysicsShape&, Point, Point, float, void*)> report;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PhysicsRectQueryCallback
|
class PhysicsRectQueryCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::function<bool(PhysicsWorld&, PhysicsShape&, void* data)> report;
|
PhysicsRectQueryCallback()
|
||||||
|
: report(nullptr)
|
||||||
|
{}
|
||||||
|
virtual ~PhysicsRectQueryCallback(){}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::function<bool(PhysicsWorld&, PhysicsShape&, void*)> report;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace
|
||||||
CL(PhysicsDemoPyramidStack),
|
CL(PhysicsDemoPyramidStack),
|
||||||
CL(PhysicsDemoPlink),
|
CL(PhysicsDemoPlink),
|
||||||
CL(PhysicsDemoClickAdd),
|
CL(PhysicsDemoClickAdd),
|
||||||
|
CL(PhysicsDemoRayCast),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sceneIdx=-1;
|
static int sceneIdx=-1;
|
||||||
|
@ -48,6 +49,8 @@ namespace
|
||||||
|
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const Color4F STATIC_COLOR = {1.0f, 0.0f, 0.0f, 1.0f};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,6 +90,8 @@ void PhysicsTestScene::toggleDebug()
|
||||||
|
|
||||||
PhysicsDemo::PhysicsDemo()
|
PhysicsDemo::PhysicsDemo()
|
||||||
: _scene(nullptr)
|
: _scene(nullptr)
|
||||||
|
, _ball(nullptr)
|
||||||
|
, _spriteTexture(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -304,22 +309,62 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* PhysicsDemoLogoSmash::makeBall(float x, float y)
|
Sprite* PhysicsDemo::makeBall(float x, float y, float radius, PhysicsMaterial material)
|
||||||
{
|
{
|
||||||
auto ball = Sprite::createWithTexture(_ball->getTexture());
|
Sprite* ball = nullptr;
|
||||||
ball->setScale(0.1);
|
if (_ball != nullptr)
|
||||||
|
{
|
||||||
|
ball = Sprite::createWithTexture(_ball->getTexture());
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
ball = Sprite::create("Images/ball.png");
|
||||||
|
}
|
||||||
|
|
||||||
auto body = PhysicsBody::createCircle(0.95, PhysicsMaterial(1, 0, 0));
|
ball->setScale(0.13f * radius);
|
||||||
body->setMass(1.0);
|
|
||||||
body->setMoment(PHYSICS_INFINITY);
|
|
||||||
|
|
||||||
|
auto body = PhysicsBody::createCircle(radius, material);
|
||||||
ball->setPhysicsBody(body);
|
ball->setPhysicsBody(body);
|
||||||
|
|
||||||
ball->setPosition(Point(x, y));
|
ball->setPosition(Point(x, y));
|
||||||
|
|
||||||
return ball;
|
return ball;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sprite* PhysicsDemo::makeBox(float x, float y, Size size, PhysicsMaterial material)
|
||||||
|
{
|
||||||
|
auto box = CCRANDOM_0_1() > 0.5f ? Sprite::create("Images/YellowSquare.png") : Sprite::create("Images/CyanSquare.png");
|
||||||
|
|
||||||
|
box->setScaleX(size.width/100.0f);
|
||||||
|
box->setScaleY(size.height/100.0f);
|
||||||
|
|
||||||
|
auto body = PhysicsBody::createBox(size);
|
||||||
|
box->setPhysicsBody(body);
|
||||||
|
box->setPosition(Point(x, y));
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sprite* PhysicsDemo::makeTriangle(float x, float y, Size size, PhysicsMaterial material)
|
||||||
|
{
|
||||||
|
auto triangle = CCRANDOM_0_1() > 0.5f ? Sprite::create("Images/YellowTriangle.png") : Sprite::create("Images/CyanTriangle.png");
|
||||||
|
|
||||||
|
if(size.height == 0)
|
||||||
|
{
|
||||||
|
triangle->setScale(size.width/100.0f);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
triangle->setScaleX(size.width/50.0f);
|
||||||
|
triangle->setScaleY(size.height/43.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point vers[] = { Point(0, size.height/2), Point(size.width/2, -size.height/2), Point(-size.width/2, -size.height/2)};
|
||||||
|
|
||||||
|
auto body = PhysicsBody::createPolygon(vers, 3);
|
||||||
|
triangle->setPhysicsBody(body);
|
||||||
|
triangle->setPosition(Point(x, y));
|
||||||
|
|
||||||
|
return triangle;
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicsDemoLogoSmash::onEnter()
|
void PhysicsDemoLogoSmash::onEnter()
|
||||||
{
|
{
|
||||||
PhysicsDemo::onEnter();
|
PhysicsDemo::onEnter();
|
||||||
|
@ -337,19 +382,22 @@ void PhysicsDemoLogoSmash::onEnter()
|
||||||
float x_jitter = 0.05*frand();
|
float x_jitter = 0.05*frand();
|
||||||
float y_jitter = 0.05*frand();
|
float y_jitter = 0.05*frand();
|
||||||
|
|
||||||
_ball->addChild(makeBall(2*(x - logo_width/2 + x_jitter) + VisibleRect::getVisibleRect().size.width/2,
|
Node* ball = makeBall(2*(x - logo_width/2 + x_jitter) + VisibleRect::getVisibleRect().size.width/2,
|
||||||
2*(logo_height-y + y_jitter) + VisibleRect::getVisibleRect().size.height/2 - logo_height/2));
|
2*(logo_height-y + y_jitter) + VisibleRect::getVisibleRect().size.height/2 - logo_height/2,
|
||||||
|
0.95f, PhysicsMaterial(1.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
ball->getPhysicsBody()->setMass(1.0);
|
||||||
|
ball->getPhysicsBody()->setMoment(PHYSICS_INFINITY);
|
||||||
|
|
||||||
|
_ball->addChild(ball);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto bullet = Sprite::createWithTexture(_ball->getTexture());
|
auto bullet = makeBall(400, 0, 10, PhysicsMaterial(PHYSICS_INFINITY, 0, 0));
|
||||||
bullet->setScale(0.5);
|
bullet->getPhysicsBody()->setVelocity(Point(400, 0));
|
||||||
|
|
||||||
auto body = PhysicsBody::createCircle(8, PhysicsMaterial(PHYSICS_INFINITY, 0, 0));
|
|
||||||
body->setVelocity(Point(400, 0));
|
|
||||||
bullet->setPhysicsBody(body);
|
|
||||||
|
|
||||||
bullet->setPosition(Point(-1000, VisibleRect::getVisibleRect().size.height/2));
|
bullet->setPosition(Point(-1000, VisibleRect::getVisibleRect().size.height/2));
|
||||||
|
|
||||||
|
@ -393,7 +441,7 @@ void PhysicsDemoPlink::onEnter()
|
||||||
{
|
{
|
||||||
PhysicsDemo::onEnter();
|
PhysicsDemo::onEnter();
|
||||||
|
|
||||||
auto node = Node::create();
|
auto node = DrawNode::create();
|
||||||
auto body = PhysicsBody::create();
|
auto body = PhysicsBody::create();
|
||||||
body->setDynamic(false);
|
body->setDynamic(false);
|
||||||
node->setPhysicsBody(body);
|
node->setPhysicsBody(body);
|
||||||
|
@ -405,7 +453,11 @@ void PhysicsDemoPlink::onEnter()
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 4; ++j)
|
for (int j = 0; j < 4; ++j)
|
||||||
{
|
{
|
||||||
body->addShape(PhysicsShapePolygon::create(tris, 3, PHYSICSSHAPE_MATERIAL_DEFAULT, Point(rect.origin.x + rect.size.width/9*i + (j%2)*40 - 20, rect.origin.y + j*70)));
|
Point offset(rect.origin.x + rect.size.width/9*i + (j%2)*40 - 20, rect.origin.y + j*70);
|
||||||
|
body->addShape(PhysicsShapePolygon::create(tris, 3, PHYSICSSHAPE_MATERIAL_DEFAULT, offset));
|
||||||
|
|
||||||
|
Point drawVec[] = {tris[0] + offset, tris[1] + offset, tris[2] + offset};
|
||||||
|
node->drawPolygon(drawVec, 3, STATIC_COLOR, 1, STATIC_COLOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,3 +469,208 @@ std::string PhysicsDemoPlink::title()
|
||||||
{
|
{
|
||||||
return "Plink";
|
return "Plink";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhysicsDemoRayCast::PhysicsDemoRayCast()
|
||||||
|
: _angle(0.0f)
|
||||||
|
, _node(nullptr)
|
||||||
|
, _mode(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void PhysicsDemoRayCast::onEnter()
|
||||||
|
{
|
||||||
|
PhysicsDemo::onEnter();
|
||||||
|
setTouchEnabled(true);
|
||||||
|
|
||||||
|
_scene->getPhysicsWorld()->setGravity(Point::ZERO);
|
||||||
|
|
||||||
|
auto node = DrawNode::create();
|
||||||
|
node->setPhysicsBody(PhysicsBody::createEdgeSegment(VisibleRect::leftBottom() + Point(0, 50), VisibleRect::rightBottom() + Point(0, 50)));
|
||||||
|
node->drawSegment(VisibleRect::leftBottom() + Point(0, 50), VisibleRect::rightBottom() + Point(0, 50), 1, STATIC_COLOR);
|
||||||
|
this->addChild(node);
|
||||||
|
|
||||||
|
MenuItemFont::setFontSize(18);
|
||||||
|
auto item = MenuItemFont::create("Change Mode(any)", CC_CALLBACK_1(PhysicsDemoRayCast::changeModeCallback, this));
|
||||||
|
|
||||||
|
auto menu = Menu::create(item, NULL);
|
||||||
|
this->addChild(menu);
|
||||||
|
menu->setPosition(Point(VisibleRect::left().x+100, VisibleRect::top().y-10));
|
||||||
|
|
||||||
|
scheduleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsDemoRayCast::changeModeCallback(Object* sender)
|
||||||
|
{
|
||||||
|
_mode = (_mode + 1) % 3;
|
||||||
|
|
||||||
|
switch (_mode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
((MenuItemFont*)sender)->setString("Change Mode(any)");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
((MenuItemFont*)sender)->setString("Change Mode(nearest)");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
((MenuItemFont*)sender)->setString("Change Mode(multiple)");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhysicsDemoRayCast::anyRay(PhysicsWorld& world, PhysicsShape& shape, Point point, Point normal, float fraction, void* data)
|
||||||
|
{
|
||||||
|
*((Point*)data) = point;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PhysicsDemoNearestRayCastCallback : public PhysicsRayCastCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PhysicsDemoNearestRayCastCallback();
|
||||||
|
|
||||||
|
private:
|
||||||
|
float _friction;
|
||||||
|
};
|
||||||
|
|
||||||
|
PhysicsDemoNearestRayCastCallback::PhysicsDemoNearestRayCastCallback()
|
||||||
|
: _friction(1.0f)
|
||||||
|
{
|
||||||
|
report = [this](PhysicsWorld& world, PhysicsShape& shape, Point point, Point normal, float fraction, void* data)->bool
|
||||||
|
{
|
||||||
|
if (_friction > fraction)
|
||||||
|
{
|
||||||
|
*((Point*)data) = point;
|
||||||
|
_friction = 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, PhysicsShape& shape, Point point, Point normal, float fraction, void* data)->bool
|
||||||
|
{
|
||||||
|
if (num < MAX_MULTI_RAYCAST_NUM)
|
||||||
|
{
|
||||||
|
points[num++] = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsDemoRayCast::update(float delta)
|
||||||
|
{
|
||||||
|
float L = 150.0f;
|
||||||
|
Point point1 = VisibleRect::center();
|
||||||
|
Point d(L * cosf(_angle), L * sinf(_angle));
|
||||||
|
Point point2 = point1 + d;
|
||||||
|
|
||||||
|
removeChild(_node);
|
||||||
|
_node = DrawNode::create();
|
||||||
|
switch (_mode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
PhysicsRayCastCallback callback;
|
||||||
|
Point point3 = point2;
|
||||||
|
callback.report = anyRay;
|
||||||
|
|
||||||
|
_scene->getPhysicsWorld()->rayCast(callback, point1, point2, &point3);
|
||||||
|
_node->drawSegment(point1, point3, 1, STATIC_COLOR);
|
||||||
|
|
||||||
|
if (point2 != point3)
|
||||||
|
{
|
||||||
|
_node->drawDot(point3, 2, Color4F(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
}
|
||||||
|
addChild(_node);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
PhysicsDemoNearestRayCastCallback callback;
|
||||||
|
Point point3 = point2;
|
||||||
|
|
||||||
|
_scene->getPhysicsWorld()->rayCast(callback, point1, point2, &point3);
|
||||||
|
_node->drawSegment(point1, point3, 1, STATIC_COLOR);
|
||||||
|
|
||||||
|
if (point2 != point3)
|
||||||
|
{
|
||||||
|
_node->drawDot(point3, 2, Color4F(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
}
|
||||||
|
addChild(_node);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
PhysicsDemoMultiRayCastCallback callback;
|
||||||
|
|
||||||
|
_scene->getPhysicsWorld()->rayCast(callback, point1, point2, nullptr);
|
||||||
|
|
||||||
|
_node->drawSegment(point1, point2, 1, STATIC_COLOR);
|
||||||
|
|
||||||
|
for (int i = 0; i < callback.num; ++i)
|
||||||
|
{
|
||||||
|
_node->drawDot(callback.points[i], 2, Color4F(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
addChild(_node);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_angle += 0.25f * M_PI / 180.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsDemoRayCast::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
|
||||||
|
{
|
||||||
|
//Add a new body/atlas sprite at the touched location
|
||||||
|
|
||||||
|
for( auto &touch: touches)
|
||||||
|
{
|
||||||
|
auto location = touch->getLocation();
|
||||||
|
|
||||||
|
float r = CCRANDOM_0_1();
|
||||||
|
|
||||||
|
if (r < 1.0f/3.0f)
|
||||||
|
{
|
||||||
|
addChild(makeBall(location.x, location.y, 5 + CCRANDOM_0_1()*10));
|
||||||
|
}else if(r < 2.0f/3.0f)
|
||||||
|
{
|
||||||
|
addChild(makeBox(location.x, location.y, Size(10 + CCRANDOM_0_1()*15, 10 + CCRANDOM_0_1()*15)));
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
addChild(makeTriangle(location.x, location.y, Size(10 + CCRANDOM_0_1()*20, 10 + CCRANDOM_0_1()*20)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PhysicsDemoRayCast::title()
|
||||||
|
{
|
||||||
|
return "Ray Cast";
|
||||||
|
}
|
|
@ -37,9 +37,13 @@ public:
|
||||||
void toggleDebugCallback(Object* sender);
|
void toggleDebugCallback(Object* sender);
|
||||||
|
|
||||||
void addGrossiniAtPosition(Point p, float scale = 1.0);
|
void addGrossiniAtPosition(Point p, float scale = 1.0);
|
||||||
|
Sprite* makeBall(float x, float y, float radius, PhysicsMaterial material = {1.0f, 1.0f, 1.0f});
|
||||||
|
Sprite* makeBox(float x, float y, Size size, PhysicsMaterial material = {1.0f, 1.0f, 1.0f});
|
||||||
|
Sprite* makeTriangle(float x, float y, Size size, PhysicsMaterial material = {1.0f, 1.0f, 1.0f});
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
Texture2D* _spriteTexture; // weak ref
|
Texture2D* _spriteTexture; // weak ref
|
||||||
|
SpriteBatchNode* _ball;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PhysicsDemoClickAdd : public PhysicsDemo
|
class PhysicsDemoClickAdd : public PhysicsDemo
|
||||||
|
@ -57,11 +61,6 @@ class PhysicsDemoLogoSmash : public PhysicsDemo
|
||||||
public:
|
public:
|
||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
std::string title() override;
|
std::string title() override;
|
||||||
|
|
||||||
Node* makeBall(float x, float y);
|
|
||||||
|
|
||||||
private:
|
|
||||||
SpriteBatchNode* _ball;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PhysicsDemoPyramidStack : public PhysicsDemo
|
class PhysicsDemoPyramidStack : public PhysicsDemo
|
||||||
|
@ -78,4 +77,25 @@ public:
|
||||||
std::string title() override;
|
std::string title() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PhysicsDemoRayCast : public PhysicsDemo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PhysicsDemoRayCast();
|
||||||
|
public:
|
||||||
|
void onEnter() override;
|
||||||
|
std::string title() override;
|
||||||
|
void update(float delta) override;
|
||||||
|
|
||||||
|
void onTouchesEnded(const std::vector<Touch*>& touches, Event* event) override;
|
||||||
|
|
||||||
|
void changeModeCallback(Object* sender);
|
||||||
|
|
||||||
|
static bool anyRay(PhysicsWorld& world, PhysicsShape& shape, Point point, Point normal, float fraction, void* data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float _angle;
|
||||||
|
DrawNode* _node;
|
||||||
|
int _mode;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue