Ошибка обнаружения столкновения Box2D

Недавно я начал использовать Box2D версии 2.1 в сочетании с Allegro5. В настоящее время я построил тест с землей и 4 ящиками. 3 коробки сложены друг на друга, а другая разбивается, заставляя их переворачиваться. Во время этой демонстрации я заметил два глюка.

Во-первых, создание блока в Box2D "SetAsBox(ширина, высота)" дает только половину размера обычного блока, нарисованного на экране с помощью аллегро. Пример: в Box2D я создаю коробку размером (15, 15). Когда я приступаю к рисованию фигуры с помощью аллегро, я должен сделать смещение -15 по оси y и увеличить фигуру в два раза.

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

Вот код для создания моих коробок:

cBox2D::cBox2D( int width, int height ) {

  // Note: In Box2D, 30 pixels = 1 meter
  velocityIterations  = 10;
  positionIterations  = 10;
  worldGravity  = 9.81f;
  timeStep    = ( 1.0f / 60.0f );
  isBodySleep   = false;

  gravity.Set( 0.0f, worldGravity );
  world = new b2World( gravity, isBodySleep );

  groundBodyDef.position.Set( 0.0f, height ); // ground location
  groundBody = world->CreateBody( &groundBodyDef );

  groundBox.SetAsBox( width, 0.0f ); // Ground size
  groundBody->CreateFixture( &groundBox, 0.0f );

 }

 cBox2D::~cBox2D( void ) {}

 void cBox2D::makeSquare( int width, int height, int locX, int locY, float xVelocity, float yVelocity, float angle, float angleVelocity ) {

  sSquare square;

  square.bodyDef.type = b2_dynamicBody;
  square.bodyDef.position.Set( locX, locY ); // Box location
  square.bodyDef.angle = angle; // Box angle
  square.bodyDef.angularVelocity = angleVelocity;
  square.bodyDef.linearVelocity.Set( xVelocity, yVelocity ); // Box Velocity
  square.body = world->CreateBody( &square.bodyDef );

  square.dynamicBox.SetAsBox( width, height ); // Box size
  square.fixtureDef.shape = &square.dynamicBox;
  square.fixtureDef.density = 1.0f;
  square.fixtureDef.friction = 0.3f;
  square.fixtureDef.restitution = 0.0f; // Bouncyness
  square.body->CreateFixture( &square.fixtureDef );

  squareVec.push_back( square );

 }

 int cBox2D::getVecSize( void ) {
  return squareVec.size();
 }

 b2Body* cBox2D::getSquareAt( int loc ) {
  return squareVec.at( loc ).body;
 }

 void cBox2D::update( void ) {

  world->Step(timeStep, velocityIterations, positionIterations);
  world->ClearForces();

 }

Редактировать: Спасибо, Крис Берт-Браун, за то, что объяснил мне первую проблему, что касается второй проблемы, это была хорошая идея, но она не решила ее. Я пробовал оба метода округления, которые вы мне показали.

Изменить: я думаю, что нашел ответ на свой второй вопрос. Оказывается, у Allegro другая система координат, чем у OpenGL. В результате вместо -gravity мне пришлось использовать +gravity, из-за чего Box2D стал нестабильным и вел себя странно.

Редактировать: Плохо, я думал, что это проблема, но оказалось, что это ничего не изменило.


person Johnathan    schedule 25.01.2011    source источник


Ответы (1)


На самом деле это SetAsBox(halfwidth, halfheight). Я знаю, это звучит странно, но загляните внутрь SetAsBox. Передача параметров 15 и 15 даст коробку с углами (-15,-15) и (15,15), т.е. коробку размером 30x30.

Я думаю, что это задумано как оптимизация, но это довольно глупо.

Я не знаю, в чем причина вашей другой проблемы, но когда вы рисуете коробки с помощью Allegro, попробуйте посмотреть, исправлено ли это, когда вы round координаты. (Если это не сработает, попробуйте ceil.)

person Chris Burt-Brown    schedule 25.01.2011