Проблема Матричного преобразования - Вращение оси Z Скашивается

Для простой 2-й игры, которую я делаю, я пытаюсь повернуть спрайты вокруг оси z с помощью матриц. Я ясно делаю что-то не так как тогда, когда я пытаюсь повернуть свой спрайт, похоже, что это поворачивается вокруг экранного источника (нижняя часть, покинутая) а не источника спрайта. Я смущен, как моя четверка уже в источнике, таким образом, я не думал, что должен перевести->, поворачивают и переводят назад. Вот фрагмент кода и маленькое видео или ошибочное преобразование

void MatrixMultiply(
MATRIX      &mOut,
const MATRIX    &mA,
const MATRIX    &mB);
/*!***************************************************************************
@Function           TransTransformArray
@Output         pTransformedVertex  Destination for transformed vectors
@Input              pV                  Input vector    array
@Input              nNumberOfVertices   Number of vectors to transform
@Input              pMatrix             Matrix to transform the vectors of input vector (e.g. use 1 for position, 0 for normal)
@Description        Transform all vertices in pVertex by pMatrix and store them in
                pTransformedVertex
                - pTransformedVertex is the pointer that will receive transformed vertices.
                - pVertex is the pointer to untransformed object vertices.
                - nNumberOfVertices is the number of vertices of the object.
                - pMatrix is the matrix used to transform the object.
*****************************************************************************/
void TransTransformArray(
VECTOR3     * const pTransformedVertex,
const VECTOR3   * const pV,
const int     nNumberOfVertices,
const MATRIX    * const pMatrix);


RenderQuad CreateRenderQuad(
    const Texture2D & texture,
    float x,
    float y,
    float scaleX, 
    float scaleY,
    float rotateRadians,
    int   zIndex,
    const Color & color,
    const Quad2 & textureCoord,
    const char * name
) {
    MATRIX mT;
    MATRIX mS;
    MATRIX concat;  
    MATRIX mR;

    MatrixTranslation(mT, x, y, 0.0f);
    MatrixRotationZ(mR, rotateRadians);
    MatrixScaling(mS, scaleX, scaleY, 1.0f);

    VECTOR3 quad[] = {
        {-0.5f, 0.5f, 0.f}, //tl
        {0.5f, 0.5f, 0.f}, //tr
        {-0.5, -0.5f, 0.0f}, //bl
        {0.5f, -0.5f, 0.0f}, //br
    };

    MatrixMultiply(concat, mR, mT);
    MatrixMultiply(concat, concat, mS);
    // apply to all the points in the quad
    TransTransformArray(quad, quad, 4, &concat);

== Обновление:

вот код структур и рендеринга:

Я использую матричный класс из oolongengine code.google.com/p/oolongengine/source/browse/trunk/Oolong%20Engine2/Math/Matrix.cpp

Я преобразовываю все четверки, затем позже представляют их использующий OpenGL. Здесь мои структуры данных и представляют код:

typedef struct _RenderData {
    VECTOR3        vertex;
    RenderColor3D      color;
    RenderTextureCoord textureCoord;
    float              zIndex;
    GLuint             textureId;
} RenderData;

typedef struct _RenderQuad {
    //! top left
    RenderData  tl;
    //! top right
    RenderData  tr;
    //! bottom left
    RenderData  bl;        
    //! bottom right
    RenderData  br;

    float zIndex;

    Texture2D * texture; // render quad draws a source rect from here

    ESpriteBlendMode blendMode;

} RenderQuad ;

/// Draw
class QuadBatch {
   GLushort *              m_indices;
   const Texture2D *       m_texture;
   GLuint                   m_vbos[2];
   RenderData *            m_vertices; 
};

QuadBatch::Draw () {
    int offset = (int)&m_vertices[startIndex];

            // vertex
            int diff = offsetof( RenderData, vertex);
            glVertexPointer(3, GL_FLOAT, kRenderDataSize, (void*) (offset + diff) );

            // color
            diff = offsetof( RenderData, color);
            glColorPointer(4, GL_FLOAT, kRenderDataSize, (void*)(offset + diff));

            // tex coords
            diff = offsetof( RenderData, textureCoord);
            glTexCoordPointer(2, GL_FLOAT, kRenderDataSize, (void*)(offset + diff));

            // each quad has 6 indices

            glDrawElements(GL_TRIANGLES, vertexCount * elementMultiplier, GL_UNSIGNED_SHORT, m_indices);

1
задан Binary Bob 10 July 2010 в 05:51
поделиться

1 ответ

"Вращение", по определению, происходит вокруг начала координат (0,0,0). Если вам нужна другая ось вращения, необходимо применить компонент Translation. Допустим, вы хотите применить вращение R вокруг оси a. Преобразование, которое нужно применить к произвольному вектору x, выглядит так:

x --> a + R(x - a) = Rx + (a - Ra)

(Это может занять некоторое время). Итак, после применения вращения - которое, как вы заметили, вращается вокруг начала координат - вы должны добавить постоянный вектор (a - Ra).

[Edit:] Этот ответ не зависит от языка и платформы - математика одинакова, где бы вы ни искали. Конкретные библиотеки содержат различные структуры и API для применения преобразований. Например, DirectX и OpenGL поддерживают матричные преобразования 4x4, чтобы объединить повороты и переводы в одно матричное умножение (с помощью аппарата, называемого однородными координатами).

2
ответ дан 2 September 2019 в 23:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: