Пиксельная проблема обнаружения столкновений с OpenGLES 2.0 под Android - PullRequest
12 голосов
/ 02 сентября 2011


Это мой первый пост, поэтому прошу прощения за любые ошибки.
Я разрабатываю простую игру с использованием OpenGL ES 2.0 и Android 2.3. Моя игровая среда, над которой я сейчас работаю, основана на двухмерных спрайтах, которые существуют в трехмерном мире. Конечно, сущности моего мира обладают такой информацией, как положение в воображаемом мире, значение вращения в форме матрицы float [], дескриптор текстуры OpenGL, а также дескриптор растрового изображения Android (я не уверен, что последнее необходимо, поскольку я делаю растеризация с использованием машины OpenGl, но пока она только там, для моего удобства). Это кратко фон, теперь к проблемному вопросу.
В настоящее время я застрял с обнаружением столкновений на основе пикселей, поскольку я не уверен, какой объект (здесь текстура OGL или растровое изображение Android) мне нужно сэмплировать. Я имею в виду, что я уже пытался попробовать растровое изображение Android, но у меня оно полностью не сработало - много сбоев во время выполнения по отношению к чтению за пределами растрового изображения. Конечно, чтобы иметь возможность считывать пиксели из растрового изображения, я использовал метод Bitmap.create , чтобы получить правильно повернутый спрайт. Вот фрагмент кода:

android.graphics.Matrix m = new android.graphics.Matrix();
if(o1.angle != 0.0f) {          
    m.setRotate(o1.angle);
    b1 = Bitmap.createBitmap(b1, 0, 0, b1.getWidth(), b1.getHeight(), m, false);
}

Другая проблема, которая может добавить к проблеме или даже стать основной проблемой, состоит в том, что мой прямоугольник пересечения (прямоугольник, указывающий двухмерное пространство, взаимное для обоих объектов) состоит из частей двух ограничивающих прямоугольников, которые были вычислены с использование OpenGL матриц Matrix.multiplyMV функциональность (код ниже). Может быть, эти два метода вычисления матриц Android и OpenGL не равны?

Matrix.rotateM(mtxRotate, 0, -angle, 0, 0, 1);

// original bitmap size, equal to sprite size in it's model space,
// as well as in world's space
float[] rect = new float[] {
    origRect.left, origRect.top, 0.0f, 1.0f, 
    origRect.right, origRect.top, 0.0f, 1.0f,
    origRect.left, origRect.bottom, 0.0f, 1.0f,
    origRect.right, origRect.bottom, 0.0f, 1.0f 
};

android.opengl.Matrix.multiplyMV(rect, 0, mtxRotate, 0, rect, 0);
android.opengl.Matrix.multiplyMV(rect, 4, mtxRotate, 0, rect, 4);
android.opengl.Matrix.multiplyMV(rect, 8, mtxRotate, 0, rect, 8);
android.opengl.Matrix.multiplyMV(rect, 12, mtxRotate, 0, rect, 12);

// computation of object's bounding box (it is necessary as object has been
// rotated second ago and now it's bounding rectangle doesn't match it's host
float left = rect[0];
float top = rect[1];
float right = rect[0];
float bottom = rect[1];
for(int i = 4; i < 16; i += 4) {
    left = Math.min(left, rect[i]);
    top = Math.max(top, rect[i+1]);
    right = Math.max(right, rect[i]);
    bottom = Math.min(bottom, rect[i+1]);
};

1 Ответ

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

Cheers,

первое замечание, что в вашем коде есть ошибка.Вы не можете использовать Matrix.multiplyMV () с одинаковым вектором источника и назначения (функция будет правильно рассчитывать координату x, которую она будет перезаписывать в исходном векторе. Однако для вычисления y, z и w требуется исходный xкоординаты - которые в свою очередь ошибочны).Также обратите внимание, что вам будет проще использовать ограничивающие сферы для первого шага обнаружения коллизии, поскольку они не требуют такого сложного кода для выполнения преобразования матрицы.

Затем, обнаружение коллизии.Вы не должны читать ни растровые изображения, ни текстуры.Что вы должны сделать, это построить силуэт для вашего объекта (это довольно просто, силуэт это просто список позиций).После этого вам нужно построить выпуклые объекты, которые заполняют (не выпуклый) силуэт.Это может быть достигнуто, например,алгоритм отсечения ушей.Возможно, он не самый быстрый, но его очень легко реализовать, и он будет выполнен только один раз.Получив выпуклые объекты, вы можете преобразовать их координаты, используя матрицу, и обнаружить столкновения с вашим миром (есть много хороших статей о пересечениях луч-треугольник, которые вы можете использовать), и вы получите такую ​​же точность, как если бы вы использовали пиксель.обнаружение столкновений на основе.

Надеюсь, это поможет ...

...