Cut b2body in box2d by Ray(problem) [half of problem solved]

I have full code to splite box2d you can copy it and check. I have just a little problem i think it can be sth wrong with:

“b2Vec2 arrVertices[b2_maxPolygonVertices];
std::copy(vertices.begin(), vertices.end(), arrVertices);
slicePoly.Set(arrVertices, count);”

If you guys know how to fix it or you’ve done sth similar please let me know :)))
THANKS ANYWAY :smiley:

HELLOWORLDSCENE.H

using namespace cocos2d;
class GLESDebugDraw;
struct Segment
{
b2Vec2 p1;
b2Vec2 p2;
};
class HelloWorldScene : public cocos2d::Layer ,public b2RayCastCallback{
public:
~HelloWorldScene();
HelloWorldScene();
static cocos2d::Scene* scene();
void addNewSpriteWithCoords(cocos2d::CCPoint p);
virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags) override;
bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);
void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event unused_event);
void onTouchEnded(cocos2d::Touch touch, cocos2d::Event unused_event);
virtual float32 ReportFixture(b2Fixture
fixture, const b2Vec2& point,const b2Vec2& normal, float32 fraction);
b2Vec2 findCenter(std::vector& vertices, int count);
void createSlice(std::vector& vertices, int count);
b2Vec2 toBox2dPoint(CCPoint pt);
CCPoint toCocos2dPoint(b2Vec2& pt);
private:
GLESDebugDraw m_debugDraw;
b2World
world;
b2Body
m_body;
b2Body m_groundBody;
bool m_bIsDraw;
CCPoint m_startPt;
CCPoint m_endPoint;
bool m_bIsRayCast;
Segment
laserSegment;
std::vector entryPoint;
std::vector<b2Body
> affectedByLaser;
bool m_bSliceObject;
bool m_bIsDrawEnter;
b2Vec2 enterPoint;
void update(float dt);

};

HELLOWORLDSCENE.CPP

using namespace cocos2d;

PTM_RATIO 32
enum
{
kTagTileMap = 1,
kTagSpriteManager = 1,
kTagAnimation1 = 1,
};

HelloWorldScene::HelloWorldScene()
{
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
bool doSleep = true;
world = new b2World(gravity);
world->SetAllowSleeping(doSleep);
world->SetContinuousPhysics(true);

 m_debugDraw = new GLESDebugDraw( PTM_RATIO );
 world->SetDebugDraw(m_debugDraw);
 int flags = 0;
 flags += b2Draw::e_shapeBit;
 m_debugDraw->SetFlags(flags);		

auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(HelloWorldScene::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(HelloWorldScene::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(HelloWorldScene::onTouchEnded, this);
this->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

b2BodyDef groundBodyDef;
groundBodyDef.position.Set(screenSize.width/2/PTM_RATIO,
screenSize.height/2/PTM_RATIO); // bottom-left corner

m_groundBody = world->CreateBody(&groundBodyDef);

b2PolygonShape groundBox;

groundBox.SetAsBox(screenSize.width/2/PTM_RATIO, 40 / PTM_RATIO,
                   b2Vec2(0, -screenSize.height/2/PTM_RATIO), 0);

m_groundBody->CreateFixture(&groundBox, 0);
groundBox.SetAsBox(0, screenSize.height/2/PTM_RATIO, b2Vec2(-screenSize.width/2/PTM_RATIO, 0), 0);
m_groundBody->CreateFixture(&groundBox, 0);
groundBox.SetAsBox(0, screenSize.height/2/PTM_RATIO, b2Vec2(screenSize.width/2/PTM_RATIO, 0), 0);
m_groundBody->CreateFixture(&groundBox, 0);

b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(80 / PTM_RATIO, 80 / PTM_RATIO);
b2Body *body = world->CreateBody(&bodyDef);
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(50 / PTM_RATIO, 50 / PTM_RATIO);
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
body->CreateFixture(&fixtureDef);

m_bIsDraw = false;
laserSegment = NULL;

this->scheduleUpdate();
}

HelloWorldScene::~HelloWorldScene()
{
delete world;
world = NULL;

delete m_debugDraw;
m_debugDraw = NULL;
}

b2Vec2 HelloWorldScene::toBox2dPoint(cocos2d::CCPoint pt)
{
return b2Vec2(pt.x / PTM_RATIO, pt.y / PTM_RATIO);
}

CCPoint HelloWorldScene::toCocos2dPoint(b2Vec2 &pt)
{
return ccp(pt.x * PTM_RATIO, pt.y * PTM_RATIO);
}

void HelloWorldScene::draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags)
{

glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

world->DrawDebugData();
glClearColor(0.5, 0.5, 0.5, 0.5);
glColor4f(1, 0, 0, 1);
if (m_bIsDraw) {
    ccDrawLine(m_startPt, m_endPoint);
}
if (m_bIsDrawEnter) {
    b2Vec2 center = b2Vec2_zero;
    for (int i=0; i < entryPoint.size(); ++i) {
        b2Vec2 entryPt = entryPoint[i];
        center += 0.5 * entryPt;
        CCPoint pt = ccp( entryPt.x * PTM_RATIO, entryPt.y * PTM_RATIO);
       ccDrawCircle(pt, 7.0f, 0, 40, false);
   }
    if (entryPoint.size() == 2) {
        CCPoint pt = ccp( center.x * PTM_RATIO, center.y * PTM_RATIO);
       ccDrawCircle(pt, 7.0f, 0, 40, false);
    }

}
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}

float32 HelloWorldScene::ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float32 fraction)
{
b2Body *affectedBody = fixture->GetBody();

if(m_groundBody == affectedBody){
    return -1;
}
int fixtureIndex = -1;
for (int index = 0; index < affectedByLaser.size(); ++index) {
    if (affectedBody == affectedByLaser[index]) {
        fixtureIndex = index;
        break;
    }
}
 b2PolygonShape* affectedPolygon = (b2PolygonShape*)fixture->GetShape();
if (-1 == fixtureIndex) {
    affectedByLaser.push_back(affectedBody);
    entryPoint.push_back(point);
}else{
    b2Vec2 rayCenter = b2Vec2( (point.x + entryPoint[fixtureIndex].x) / 2.0f,
                              (point.y + entryPoint[fixtureIndex].y) / 2.0f);
    float rayAngle = b2Atan2(entryPoint[fixtureIndex].y - point.y, 
                             entryPoint[fixtureIndex].x - point.x);
  std::vector<b2Vec2> polyVertices;
    b2Transform xf = affectedBody->GetTransform();
  int32 vertexCount = affectedPolygon->GetChildCount();
    b2Assert(vertexCount <= b2_maxPolygonVertices);
    for (int32 i = 0; i < vertexCount; ++i)
    {
        b2Vec2 vertice = b2Mul(xf, affectedPolygon->m_vertices[i]);
        polyVertices.push_back(vertice);
    }
    std::vector<b2Vec2> newPolyVertices1;
  std::vector<b2Vec2> newPolyVertices2;
    int currentPoly = 0;
    bool cutPlaced1 = false;
    bool cutPlaced2 = false;
    for (int i=0; i<polyVertices.size(); i++) {

// b2Vec2 worldPoint = affectedBody->GetWorldPoint(polyVertices[i]);
b2Vec2 worldPoint = polyVertices[i];
float cutAngle = b2Atan2(worldPoint.y - rayCenter.y,
worldPoint.x - rayCenter.x) - rayAngle;

        if (cutAngle < M_PI * -1) {
            cutAngle += 2 * M_PI;
        }
        if (cutAngle > 0 && cutAngle <= M_PI) {
            if (currentPoly==2) {
                cutPlaced1=true;
                newPolyVertices1.push_back(point);
                newPolyVertices1.push_back(entryPoint[fixtureIndex]);
            }
            newPolyVertices1.push_back(worldPoint);
            currentPoly=1;
        } else {
            if (currentPoly==1) {
                cutPlaced2=true;
                newPolyVertices2.push_back(entryPoint[fixtureIndex]);
                newPolyVertices2.push_back(point);
            }
            newPolyVertices2.push_back(worldPoint);
            currentPoly=2;
        }
    }
    if (! cutPlaced1) {
        newPolyVertices1.push_back(point);
        newPolyVertices1.push_back(entryPoint[fixtureIndex]);
    }
    if (! cutPlaced2) {
        newPolyVertices2.push_back(entryPoint[fixtureIndex]);
        newPolyVertices2.push_back(point);
    }
    this->createSlice(newPolyVertices1,newPolyVertices1.size());
    this->createSlice(newPolyVertices2,newPolyVertices2.size());
    world->DestroyBody(affectedBody);
}
return 1;

}

b2Vec2 HelloWorldScene::findCenter(std::vector& vertices, int count)
{
b2Vec2 c;
float area = 0.0f;
float p1x = 0.0f;
float p1y = 0.0f;
float inv3 = 1.0f / 3.0f;
for (int i=0; i < count; ++i) {
b2Vec2 p2 = vertices[i];
b2Vec2 p3 = (i + 1) < count ? vertices[i+1] : vertices[0];
float e1x = p2.x - p1x;
float e1y = p2.y - p1y;
float e2x = p3.x - p1x;
float e2y = p3.y - p1y;
float d = (e1x * e2y - e1y * e2x);
float triangleArea = 0.5f * d;
area += triangleArea;
c.x += triangleArea * inv3 * (p1x + p2.x + p3.x);
c.y += triangleArea * inv3 * (p1y + p2.y + p3.y);
}
c.x *= 1.0 / area;
c.y *= 1.0 / area;
return c;
}

void HelloWorldScene::createSlice(std::vector &vertices, int count)
{
b2Vec2 centre = this->findCenter(vertices, vertices.size());
// if ( centre.x < -50 || centre.x > 50 || centre.y > 50 || centre.y < -50 || centre.y != centre.y
// || count > b2_maxPolygonVertices) {
// return;
// }

for (int i=0; i< count; ++i) {
    vertices[i] -= centre;
}
b2BodyDef sliceBody;
sliceBody.position.Set(centre.x, centre.y);
sliceBody.type = b2_dynamicBody;
b2PolygonShape slicePoly;
b2Vec2 arrVertices[b2_maxPolygonVertices];
std::copy(vertices.begin(), vertices.end(), arrVertices);
slicePoly.Set(arrVertices, count);
b2FixtureDef sliceFixture;
sliceFixture.shape = &slicePoly;
sliceFixture.density = 1;
b2Body *pSliceBody = world->CreateBody(&sliceBody);
pSliceBody->CreateFixture(&sliceFixture);
for (int i=0; i < count; ++i) {
    vertices[i] += centre;
}

}

void HelloWorldScene::update(float dt)
{

int velocityIterations = 8;
int positionIterations = 1;

world->Step(dt, velocityIterations, positionIterations);
if (m_bIsRayCast && NULL != laserSegment && (laserSegment->p2 - laserSegment->p1).LengthSquared() > 0) {

    entryPoint.clear();
    affectedByLaser.clear();
    world->RayCast(this, laserSegment->p1,laserSegment->p2);
    world->RayCast(this, laserSegment->p2,laserSegment->p1);
    delete laserSegment;
    laserSegment = NULL;  
}  	

for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
}
}
}

bool HelloWorldScene::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event){
m_bSliceObject = false;

laserSegment = new Segment;
m_bIsRayCast = false;
m_bIsDraw = false;
m_bIsDrawEnter = false;
m_startPt = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());
m_endPoint = m_startPt;
laserSegment->p1 = b2Vec2(m_startPt.x / PTM_RATIO,m_startPt.y / PTM_RATIO);

return true;
}

void HelloWorldScene::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event){
m_endPoint = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());
m_bIsDraw = true;
}

void HelloWorldScene::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event)
{
CCPoint location = touch->getLocationInView();
location = CCDirector::sharedDirector()->convertToGL(location);
m_endPoint = location;

    laserSegment->p2 = b2Vec2(m_endPoint.x / PTM_RATIO, m_endPoint.y / PTM_RATIO);
    m_bIsDraw = false;
    m_bIsRayCast = true;

}

Scene* HelloWorldScene::scene()
{
CCScene scene = CCScene::create();
CCLayer
layer = new HelloWorldScene();
scene->addChild(layer);
layer->release();

return scene;

}