devkitPro / citro3d

Homebrew PICA200 GPU wrapper library for Nintendo 3DS
zlib License
244 stars 34 forks source link

Added Quat_FromMtx(). #21

Closed tommai78101 closed 8 years ago

tommai78101 commented 8 years ago

Matrix must be orthogonal or special orthogonal.

Since there's Mtx_FromQuat(), I proposed there should be a function that goes the opposite way, matrix -> quaternion.

Please check.

tommai78101 commented 8 years ago

Note: I am not able to test this code for some reasons. When building, I get "undefined references". For the time being, I request someone to help test the code for me.

fincs commented 8 years ago

Thank you for your contribution again. The function prototype should be:

C3D_FQuat Quat_FromMtx(const C3D_Mtx* m);

C3D_FQuat objects are small enough (16 bytes) to be passed and returned by value through floating point registers. However C3D_Mtx objects are too big and contain arrays (64 bytes), therefore they must be passed by reference.

You may have stray .o/.d files in the source/maths folder due to the way the test program used to work (and mtheall had a similar compilation issue). Delete them and do make clean && make install.

tommai78101 commented 8 years ago

Changed prototype. Still having issues with troubleshooting.

EDIT: I missed your quote saying to pass it by reference. Changing it.

tommai78101 commented 8 years ago

I'm just going to post the test code here:

    void mtx_quat_test()
    {
        C3D_Mtx test_matrix;
        C3D_FQuat test_quat;

        Mtx_Identity(&test_matrix);
        test_matrix.r[0].x = -1.0f;
        test_matrix.r[0].y = 3.0f;
        test_matrix.r[0].z = 0.0f;

        test_matrix.r[1].x = 9.0f;
        test_matrix.r[1].y = 1.0f;
        test_matrix.r[1].z = 14.0f;

        test_matrix.r[2].x = 0.0f;
        test_matrix.r[2].y = -6.0f;
        test_matrix.r[2].z = -1.0f;

        for (int i = 0; i < 16; i++)
        {
            std::printf("%.1f, ", test_matrix.m[(i / 4) * 4 + (3 - i % 4)]);
            if (i % 4 == 3)
                std::printf("\n");
        }
        std::printf("\n\n");

        test_quat = Quat_FromMtx(&test_matrix);

        for (int i = 0; i < 4; i++)
            std::printf("%.1f, ", test_quat.c[i]);

        while (aptMainLoop())
        {
            gspWaitForVBlank();

            hidScanInput();
            u32 down = hidKeysDown();
            if (down & (KEY_START | KEY_SELECT))
                break;
        }
    }

I used the calculator here to check:

http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/

This is just temporary, until I fix the issue I am having.

fincs commented 8 years ago

I think this looks almost ready for merging. Can you do some final testing on the output of this function to ensure it works properly?

fincs commented 8 years ago

See #26.