Создайте и используйте Rotation 3D Matrix - PullRequest
0 голосов
/ 11 февраля 2020

Привет

Раньше я спрашивал с поворотом сетки в Lua, но сделать то же самое в 3D оказалось непросто. ПРИМЕЧАНИЕ В данный момент я не концентрируюсь на эффективности, я просто хочу, чтобы она работала как положено.

Util.java

public static float[][] generate3DMatrix(final float d, final char axis)
{
    final double r = d * Math.PI/180;
    final float c = (float) Math.cos(r), s = (float) Math.sin(r);
    switch (axis) {
        case 'x':
            return new float[][] {
                    {1, 0, 0 },
                    {0, c, -s},
                    {0, s, c }
            };
        case 'z':
            return new float[][] {
                    {c, -s, 0},
                    {s, c,  0},
                    {0, 0,  1}
            };
        default: // 'y'
            return new float[][] {
                    {c,  0, s},
                    {0,  1, 0},
                    {-s, 0, c}
            };
    }
}

Идея заключалась в том, чтобы (в мой класс Util) имеет функцию, которая сначала генерирует матрицу вращения из угла и оси. Прежде чем он сгенерирует, он преобразует его в радианные углы.

После этого у меня есть функция вращения, у которой в качестве аргумента используется матрица:

public static float[] rotate3D(float x, float y, float z, float[][] matrix)
{
    return new float[] {matrix[0][0]*x+matrix[0][1]*y+matrix[0][2]*z,matrix[1][0]*x+matrix[1][1]*y+matrix[1][2]*z,matrix[2][0]*x+matrix[2][1]*y+matrix[2][2]*z};
}

Максимальный размер кубоида - 16x16x16. Я использую это для создания шести «расширений» глубины для центрального кубоида, центральный кубоид и одна из сторон уже определены и должны сгенерировать остальные пять сторон из первого удлиненного кубоида. Сначала я храню две точки в k1 и k2, создавая матрицу 90 ° и применяя преобразование к координатам и создавая кубоидные объекты. Для двух последних сторон (вверх и вниз) я делаю исключение и сначала генерирую матрицу 90 ° на оси X, а затем 270 ° и преобразую значения точек из поля аргументов.

BlockCableCase.java

...
private static final byte[] SIDE = {0,2,2,2,14,14}, SIDE_MOD = {0,0,2,2,16,16};
public static final VoxelShape[] CONNECTION_SIDES = getSides(SIDE[0],SIDE[1],SIDE[2],SIDE[3],SIDE[4],SIDE[5]);
...
private static VoxelShape[] getSides(short x1, short y1, short z1, short x2, short y2, short z2)
{
    VoxelShape[] t = new VoxelShape[6];
    t[0] = Block.makeCuboidShape(x1,y1,z1,x2,y2,z2);
    short[] k1 = {(short)(x1+8),(short)(y1+8),(short)(z1+8)};
    short[] k2 = {(short)(x2+8),(short)(y2+8),(short)(z2+8)};
    float[][] mY90 = Util.generate3DMatrix(90,'y');
    for (short i=1;i<6;i++) {
        if (i < 3) {
            k1 = Util.rotateY(k1[0], k1[1], k1[2], mY90);
            k2 = Util.rotateY(k2[0], k2[1], k2[2], mY90);
        } else {
            k1 = Util.rotate3D((short)(x1+8), (short)(y1+8), (short)(z1+8), Util.generate3DMatrix(90, 'x'));
            k2 = Util.rotate3D((short)(x2+8), (short)(y2+8), (short)(z2+8), Util.generate3DMatrix(270, 'x'));
        }
        t[i] = Block.makeCuboidShape(k1[0]-8,k1[1]-8,k1[2]-8,k2[0]-8,k2[1]-8,k2[2]-8);
    }
    return t;
}
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...