Я работал над игрой с разрушаемым окружением, и я нашел решение, в котором я проверяю возможное разрушение в моем ContactListener
объекте. Очевидно, потому что это происходит в Step()
, я откладываю обработку уничтожения до момента после шага. Я делаю это путем объединения «событий уничтожения», которые необходимо обработать в обработчике контактов, а затем сразу после Step()
вызова чего-то вроде contactListener->processDestructionEvents();
.
Способ, которым я это делаю, - это захватить встречные приборы в событии beginContact, а затем определить угол удара, а затем использовать этот угол для радиопередачи на самом приборе. Затем я собираю вершины из b2PolygonShape
прибора, а затем генерирую две новые фигуры, которые разделяются на основе точек удара и выхода луча. Исходный прибор уничтожается на теле, а затем генерируется новый прибор для первой новой формы и добавляется к исходному телу. Для второй фигуры генерируется новое тело, и эта фигура добавляется к этому новому телу.
В любом случае все работает отлично, в режиме отладки я вижу, что новые фигуры созданы и все на месте, как и должно быть. Тем не менее, я получаю действительно испорченное поведение в этой точке. Как только этот процесс завершится, ни оригинальное, ни вновь сгенерированное тело ни с чем не столкнется. Если я включу непрерывную физику, ИНОГДА динамический объект столкнется с одним из краев этих тел / приборов, но не всегда. Мне интересно, если я что-то не так делаю в своем подходе к восстановлению кузовов / приборов во время выполнения. Вот код для генерации новых объектов, любая помощь будет принята с благодарностью.
void PhysicsContactListener::processDestructionEvents() {
if(!hasDestructionEvents) {return;}
for(destructionEventsIterator = destructionEvents.begin(); destructionEventsIterator != destructionEvents.end(); ++destructionEventsIterator) {
b2Filter f1, f2;
f1.groupIndex = destructionEventsIterator->originalFixture->GetFilterData().groupIndex;
f1.categoryBits = destructionEventsIterator->originalFixture->GetFilterData().categoryBits;
f1.maskBits = destructionEventsIterator->originalFixture->GetFilterData().maskBits;
f2.groupIndex = destructionEventsIterator->originalFixture->GetFilterData().groupIndex;
f2.categoryBits = destructionEventsIterator->originalFixture->GetFilterData().categoryBits;
f2.maskBits = destructionEventsIterator->originalFixture->GetFilterData().maskBits;
b2PolygonShape newShape0 = destructionEventsIterator->newFixtures[0];
b2FixtureDef fixture0Def;
fixture0Def.shape = &newShape0;
fixture0Def.density = 1.0f;
fixture0Def.restitution = 0.2f;
b2Fixture* fixture1 = destructionEventsIterator->hostBody->CreateFixture(&fixture0Def);
fixture1->SetFilterData(f1);
//destructionEventsIterator->hostBody->SetAwake(true);
destructionEventsIterator->hostBody->ResetMassData();
//destructionEventsIterator->hostBody->SetActive(true);
destructionEventsIterator->hostBody->SetTransform(destructionEventsIterator->hostBody->GetPosition(), destructionEventsIterator->hostBody->GetAngle());
b2BodyDef bd;
bd.position = destructionEventsIterator->hostBody->GetPosition();
bd.angle = destructionEventsIterator->hostBody->GetAngle();
bd.type = destructionEventsIterator->hostBody->GetType();
b2Body* newBody = destructionEventsIterator->hostBody->GetWorld()->CreateBody(&bd);
b2PolygonShape* newShape1 = (b2PolygonShape*)(&destructionEventsIterator->newFixtures[1]);
b2Fixture* fixture2 = newBody->CreateFixture(newShape1, destructionEventsIterator->hostBodyDensity);
fixture2->SetFilterData(f2);
newBody->SetAngularVelocity(destructionEventsIterator->hostBody->GetAngularVelocity());
newBody->SetLinearVelocity(destructionEventsIterator->hostBody->GetLinearVelocity());
//newBody->SetAwake(true);
newBody->ResetMassData();
//newBody->SetActive(true);
newBody->SetTransform(destructionEventsIterator->hostBody->GetPosition(), destructionEventsIterator->hostBody->GetAngle());
destructionEventsIterator->hostBody->DestroyFixture(destructionEventsIterator->originalFixture);
}