2013-07-30 1 views
2

나는 box2d를 사용하고 있고 내가 월드 타임 스텝에서 파손되고있는 것으로 나타났습니다. 이 시체를 참조하는 연락처를 가져 오는 중. Contact Listener가 충돌합니다. Box2D 본체가 시간 단계 바깥에서 파손되었을 때

은 presolve에서 수행과 접촉 리스너의 접촉 방법을 시작되는 것입니다 :

const b2Body* bodyA = contact->GetFixtureA()->GetBody(); 

const b2Body* bodyB = contact->GetFixtureB()->GetBody(); 

Object * objectA = (Object*)bodyA->GetUserData(); 
Object * objectB = (Object*)bodyB->GetUserData(); 

개체가 제거 되었기 때문에 실제로 세계 시간 단계의 외부 (넌센스에 대한 포인터 어느 objectA 또는 objectB). 잘못된 연락처가 생성되고 있거나 더 이상 존재하지 않아야하는 연락처가 여전히 나타납니다.

업데이트

나는 확인하고 올바른 몸이 파괴되고 검증 (뿐만 아니라 그들의 용기의 몸)와 접촉 리스너가 여전히 처리 접촉을 시도하는 것을 찾기 위해 세계 단계에서 코드를 변경 존재하지 않아야합니다. 나는 iOS/Xcode에있게되고 NSZombie를 활성화하고 연락처 본문 userdata가 할당 취소 된 객체 (할당 취소 된 인스턴스로 전송 된 메시지)임을 실제로 확인합니다. Box2d 소스 확인 신체가 파괴되었을 때 실제로 접촉이 끊어졌습니다. 더 많은 Box2D 코드를 거치거나 코드를 변경해야 청취자가받는 이러한 신비한 접촉을 해결할 수 있습니다.

본문에 대한 연락처 수신기에서 수신 한 연락처 (연락처 리스너에서 확인할 때)에 본문의 userdata를 null로 설정했는지 테스트 한 결과 null 사용자 데이터가 없습니다. .

+0

시체를 어떻게 파괴합니까? 코드를 보여주세요. – Pavel

+0

시체는 적절한 방법으로 파괴됩니다 (world-> DestroyBody (body);).나는 시체가 파괴된다는 것을 알고 있습니다. 문제는 오래된 접촉이 신체를 파괴 할 때 제거되지 않는 것처럼 보이므로 이러한 오래된 접촉이 접촉 청취자를 통해 나오고 문제가 발생한다는 것입니다. –

+1

world-> DestroyBody는 모든 신체 접촉을 파괴합니다. 해당 코드는 http://pastebin.com/cKJDfN6c (v2.2.1)를 참조하십시오. 내 생각에, 당신은 똑같은 것을 혼합합니다 (예를 들어, 다른 몸체를 파괴하는 것). – Pavel

답변

1

문제는 두 개의 동일한 몸체를 만들어 내게 알지 못하고 둘 다 동일한 사용자 데이터를 전달하는 것이 었습니다. 첫 번째 몸체가 해당 사용자 데이터 (및 객체 포함)와 함께 파괴되었을 때 두 번째 몸체는 여전히 접촉점을 생성하고 있었고 신체와 관련된 사용자 데이터가 해제 되었기 때문에 설명 된 문제가 발생했습니다.

크래시가 발생했을 때 디버거가 실제로 사용자 데이터가 NULL로 설정되지 않은 두 번째 본문을 표시했기 때문에 삭제 전에 본문에 대한 사용자 데이터로 NULL을 설정하면 작동하지 않는 것처럼 보였습니다. 그 코드가 컨테이너 객체 내에 상속 구조를 가지고있어서 두 개의 시체가 만들어지고 있다는 사실을 발견하기가 어려웠 기 때문에 찾기가 너무 오래 걸린 이유였습니다.

Tomasz와 Pavel의 답변으로 문제를 해결하지 못했지만이 코드는 내가 게시 한 코드만으로는 해결할 수없는 오류로 판명되었습니다. 최소한 도우려는 시도. 둘 다 고마워.

1

내가 본 것은 box2d 본문의 파괴가 그 모든 것과 관련이 없다는 것입니다. GetUserData는 몸체를 만들 때 전달한 모든 것을 반환하며 이는 가비지 일 수 있습니다. 먹는 사람이 그것을 삭제했거나 null로 전달했습니다. 당신이 시체의 생성과 파괴를위한 코드를 제공 할 수 있다면, 나는 당신에게 조금 더 말할 수있을 것입니다. 몸이 무효 될 경우

다음 프로그램은 아마도에 충돌 것 :

contact->GetFixtureA()->GetBody(); 

또는 bodyB 부분.

+0

맞아요, 시체가 만들어 졌을 때 저는 시체가 들어있는 Object로 UserData를 설정했습니다. 나는. Object 클래스는 b2Body * body의 멤버를 포함합니다. 그래서 시체가이 Object에 할당 되었기 때문에 위의 코드는 GetUserData()가 Object 객체를 반환 할 것으로 기대합니다 (끔찍한 이름 짓기에 대해 유감스럽게 생각합니다). 그 객체는 실제로 파괴되도록 설정되어있었습니다. 실제로 객체의 소멸자는 DestroyBody (body)가 완료된 것입니다. 내 문제는 신체와 사용자 데이터가 단계 밖에서 삭제 되었기 때문에이 연락처가 더 이상 존재하지 않을 것이라는 점입니다. –

+0

그것은 미묘한 질문 일지 모르지만 디버그 모드에서 실행 중이며 box2d 월드 단계 외부에서 world-> DestroyBody (body)를 호출하고 있습니까? 디버그 모드에서 접촉 리스너 내에서 world-> DestroyBody (body)를 호출하려는 경우 box2d 객체를 파괴하는 것이 월드 단계에서 허용되지 않으므로 프로그램이 어설 션해야합니다. 릴리스 모드에서 월드 스텝 안에있는 동안 몸을 파괴하려고 시도하면 몸체가 전혀 제거되지 않습니다. 그래서 이것은 box2d 본문을 감싸는 대상이 파괴되고 본문과 청취자가 여전히 세계에 있음을 의미합니다. – LemonMooseTom

+0

디버그 모드에서 실행하고 있지는 않지만 world-> DestroyBody (body)가 월드 스텝 외부에서 수행됩니다. 월드 스텝 콜과 ClearForces 콜 바로 직후에 수행됩니다. 내가이 시체를 내 이해에서 파기하면 그 시체에 대한 모든 접촉이 삭제 될 것입니다. 이것이 잘못된 가정 일 수 있습니까? –

관련 문제