RayCasting в Box2D? - PullRequest
       4

RayCasting в Box2D?

0 голосов
/ 03 января 2012

Я создаю проект, в котором у меня есть случайные Box2d тела . Теперь я рисую линию на основе TouchesMoved пользователем в методе DRAW. мне нужно использовать метод RayCasting Box2d для проверки пересечения между этой линией и телами Box2D.

Я использую следующий код для этого в моем методе Draw

for(int i = 0; i < [pointTouches count]; i+=2)
{
    CGPoint startPoint = CGPointFromString([pointTouches objectAtIndex:i]);

    CGPoint endPoint = CGPointFromString([pointTouches objectAtIndex:i+1]);

    ccDrawLine(startPoint, endPoint);

    b2Vec2 start=[self toMeters:startPoint];

    b2Vec2 end=[self toMeters:endPoint];

    [self checkIntersectionbtw:start:end];
}

-(void)checkIntersectionbtw:(b2Vec2)point1:(b2Vec2)point2
{
    RaysCastCallback callback;

world->RayCast(&callback, point1,point2);

if (callback.m_fixture)
{
    NSLog(@"intersected");
    checkPoint = true;
}
}

-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{ 

    UITouch *myTouch = [touches anyObject];

    CGPoint currentTouchArea = [myTouch locationInView:[myTouch view]];
    CGPoint lastTouchArea = [myTouch previousLocationInView:[myTouch view]];

    currentTouchArea = [[CCDirector sharedDirector] convertToGL:currentTouchArea];
    lastTouchArea = [[CCDirector sharedDirector] convertToGL:lastTouchArea];

    [pointTouches addObject:NSStringFromCGPoint(currentTouchArea)];
    [pointTouches addObject:NSStringFromCGPoint(lastTouchArea)];


}

но обратный вызов сообщает пересечение только тогда, когда нарисованная линия полностью проходит тела. когда пользователь начинает с какой-либо внешней точки и покидает точку внутри тела box2d, обратный вызов не сообщает, что линия пересеклась. Что я, возможно, делаю не так?

Ответы [ 2 ]

0 голосов
/ 04 января 2012

Радиопередачи Box2D игнорируют любые «задние» ребра, на которые они попадают, поэтому, если луч начинается внутри прибора, этот прибор будет игнорироваться. Самое простое, что нужно сделать - это направить один и тот же луч в обоих направлениях.

0 голосов
/ 03 января 2012

Вы рисуете линию или кривую?Для линии я предполагаю, что вы используете только первую и последнюю обнаруженные точки.Для кривой вы используете все обнаруженные точки для формирования кривой, которую вы рисуете.

Если вы рисуете кривую, то подумайте, что я понимаю проблему.Вы рассчитываете линию пересечения, используя последовательные точки, обнаруженные сенсорной системой.Эти последовательные точки расположены очень близко друг к другу, что приводит к очень маленькому отливу лучей, и может случиться так, что вы можете навести линию с начальной и конечной точками внутри шаров, что может вызвать отрицательное столкновение.

Если цель состоит в том, чтобы определить, касаетесь ли вы шаров, я предлагаю использовать датчик, сохраняемый под касанием, а затем проверить столкновение с этим кодом в своем методе обновления:

for (b2ContactEdge* ce = sensorbody->GetContactList(); ce; ce = ce->next)
{   
    b2Contact* c = ce->contact;

    if(c->IsTouching())
    {
         const b2Body* bodyA = c->GetFixtureA()->GetBody();
         const b2Body* bodyB = c->GetFixtureB()->GetBody();

         const b2Body* ballBody = (bodyA == sensorbody)?bodyB:bodyA;

         ...


    }
}

Если вы действительноЕсли вы хотите использовать raycast, я предлагаю сохранить несколько последовательных точек и сделать из них вектор, чтобы избежать небольшого приведения лучей.

edit: Извините, пример, который я написал, написан на C ++, но вы должнысмог найти эквивалент для Objective-C.

...