9 поворотов ада

Версия Minecraft
1.11.2
1,015
9
102
Захотел сделать метод, который бы рисовал 3D линии с заданной толщиной от каких-либо координат к другим координатам. Сделал метод, который рисует полигон этой линии:
Код:
   private void drawPolygon(Tessellator tes, double length, float size, EnumFacing facing){
        VertexBuffer buf = tes.getBuffer();

        int angle = facing == EnumFacing.DOWN ? 180 : facing == EnumFacing.EAST ? 90 : facing == EnumFacing.WEST ? 270 : 0; // Угол поворота, в зависимости от того, какую сторону линии мы рисуем
        GL11.glPushMatrix();
        GL11.glTranslatef(0, -size/2, size/2);
        GL11.glRotated(angle, 1, 0, 0);
        GL11.glTranslatef(0, size/2, -size/2);

        buf.begin(GL11.GL_POLYGON, DefaultVertexFormats.POSITION);
        buf.pos(0, 0, 0).endVertex();
        buf.pos(0, 0, size).endVertex();
        buf.pos(length, 0, size).endVertex();
        buf.pos(length, 0, 0).endVertex();
        tes.draw();
        GL11.glPopMatrix();
    }

Потом написал метод, который бы рисовал полностью линию, которая идет от from к to:
Код:
   private void drawLine(Tessellator tes, Vec3d from, Vec3d to, float size){
        VertexBuffer buf = tes.getBuffer();
        double length = to.distanceTo(from);
        Vec3d vec = to.subtract(from).normalize(); // Находим единичный вектор нашей линии для её поворота

        GL11.glPushMatrix();
        GL11.glTranslated(from.xCoord, from.yCoord, from.zCoord);
        GL11.glRotated(vec.xCoord > 0 ? -Math.toDegrees(Math.asin(vec.zCoord)) : Math.toDegrees(Math.asin(vec.zCoord)-135), 0, 1, 0); // Поворачиваем линию по горизонту
        GL11.glRotated(Math.toDegrees(Math.asin(vec.yCoord)) * (vec.xCoord < 0 ? -1 : 1), vec.zCoord, 0, vec.xCoord); // Поднимаем или опускаем линию, в зависимости от Y 
        drawPolygon(tes, length, size, EnumFacing.UP);
        drawPolygon(tes, length, size, EnumFacing.EAST);
        drawPolygon(tes, length, size, EnumFacing.DOWN);
        drawPolygon(tes, length, size, EnumFacing.WEST);
        GL11.glPopMatrix();
    }

Как видно, я рисую линию только вдоль оси X, и поворачиваю её в зависимости от её угла наклона к конечной точке. По осям XZY, XY, X, Y  она рисуется нормально, но если мы будет рисовать вдоль оси YZ, то поворот по Y её не поднимет, а повернет её куда-то в сторону. Вот скрины:

Вот поворот по XYZ (Тут всё нормально):
Код:
       drawLine(tes, new Vec3d(x, y, z), new Vec3d(x+1, y+1, z+1), 0.1f);
49ff2769214b4b1a1bb2b787cd2c261c-full.png


А это поворот по YZ (Линия сдвинулась не по YZ, а по XZ):
Код:
       drawLine(tes, new Vec3d(x, y, z), new Vec3d(x, y+1, z+1), 0.1f);
c2ce0d63960e8c4e13f76abeac20a844-full.png

Когда дебажил понял, что градусы при повороте просчитываются нормально, и ость тоже. Т.е. -

Код:
        GL11.glRotated(Math.toDegrees(Math.asin(vec.yCoord)) * (vec.xCoord < 0 ? -1 : 1), vec.zCoord, 0, vec.xCoord); // При повороте по YZ тут angle будет равен 45, а ось по x = 0.7f, по z = 0

Если кто хорошо разбирается в openGL, то помогите, а то я уже второй день не понимаю, почему так происходит
 
Эм, так и должно быть?
[font=Monaco, Consolas, Courier, monospace]GL11.glRotated([/font][font=Monaco, Consolas, Courier, monospace]Math[/font][font=Monaco, Consolas, Courier, monospace].toDegrees([/font][font=Monaco, Consolas, Courier, monospace]Math[/font][font=Monaco, Consolas, Courier, monospace].asin(vec.yCoord)) * (vec.xCoord < [/font][font=Monaco, Consolas, Courier, monospace]0[/font][font=Monaco, Consolas, Courier, monospace] ? [/font][font=Monaco, Consolas, Courier, monospace]-1[/font][font=Monaco, Consolas, Courier, monospace] : [/font][font=Monaco, Consolas, Courier, monospace]1[/font][font=Monaco, Consolas, Courier, monospace]), vec.zCoord, [/font][font=Monaco, Consolas, Courier, monospace]0[/font][font=Monaco, Consolas, Courier, monospace], vec.xCoord);[/font]

[font=Monaco, Consolas, Courier, monospace]Имеется в виду то, что у тебя вектор x и z стоят наоборот.[/font]
 
Ivasik написал(а):
Эм, так и должно быть?
[font=Monaco, Consolas, Courier, monospace]GL11.glRotated([/font][font=Monaco, Consolas, Courier, monospace]Math[/font][font=Monaco, Consolas, Courier, monospace].toDegrees([/font][font=Monaco, Consolas, Courier, monospace]Math[/font][font=Monaco, Consolas, Courier, monospace].asin(vec.yCoord)) * (vec.xCoord < [/font][font=Monaco, Consolas, Courier, monospace]0[/font][font=Monaco, Consolas, Courier, monospace] ? [/font][font=Monaco, Consolas, Courier, monospace]-1[/font][font=Monaco, Consolas, Courier, monospace] : [/font][font=Monaco, Consolas, Courier, monospace]1[/font][font=Monaco, Consolas, Courier, monospace]), vec.zCoord, [/font][font=Monaco, Consolas, Courier, monospace]0[/font][font=Monaco, Consolas, Courier, monospace], vec.xCoord);[/font]

[font=Monaco, Consolas, Courier, monospace]Имеется в виду то, что у тебя вектор x и z стоят наоборот.[/font]

Это идет поворот прямоугольника вверх/вниз. Если прямоугольник идет к положительной X, то поворачивать мы должны по другой оси и наоборот. Если он повернут по XZ, то ось поворота вверх/вниз будет идти по диагонали. Если бы векторы стояли по-другому, то мы бы всегда крутили прямоугольник вокруг своей оси, а не вверх/вниз
 
Minebot написал(а):
Ivasik написал(а):
Эм, так и должно быть?
[font=Monaco, Consolas, Courier, monospace]GL11.glRotated([/font][font=Monaco, Consolas, Courier, monospace]Math[/font][font=Monaco, Consolas, Courier, monospace].toDegrees([/font][font=Monaco, Consolas, Courier, monospace]Math[/font][font=Monaco, Consolas, Courier, monospace].asin(vec.yCoord)) * (vec.xCoord < [/font][font=Monaco, Consolas, Courier, monospace]0[/font][font=Monaco, Consolas, Courier, monospace] ? [/font][font=Monaco, Consolas, Courier, monospace]-1[/font][font=Monaco, Consolas, Courier, monospace] : [/font][font=Monaco, Consolas, Courier, monospace]1[/font][font=Monaco, Consolas, Courier, monospace]), vec.zCoord, [/font][font=Monaco, Consolas, Courier, monospace]0[/font][font=Monaco, Consolas, Courier, monospace], vec.xCoord);[/font]

[font=Monaco, Consolas, Courier, monospace]Имеется в виду то, что у тебя вектор x и z стоят наоборот.[/font]

Это идет поворот прямоугольника вверх/вниз. Если прямоугольник идет к положительной X, то поворачивать мы должны по другой оси и наоборот. Если он повернут по XZ, то ось поворота вверх/вниз будет идти по диагонали. Если бы векторы стояли по-другому, то мы бы всегда крутили прямоугольник вокруг своей оси, а не вверх/вниз
А ок, кстати, не ты ли создавал тему с color picker или же проще с вот этим?:
XnGncPUTQlu7MSf1IHBp1g.png

Тип как рендерить и все дела...
 
Зашел в свой код молнии, который писал года два назад, там, поворот делается так:
GL11.glRotatef(vector.getYaw(), 0, 1, 0);
GL11.glRotatef(vector.getPitch(), 0, 0, 1);

Дупля не приложу что происходит, но оно работает.


Дословный код:
Код:
for (Segment seg : bolt.chain.segments)
 {
 GL11.glRotatef(seg.getYaw(), 0, 1, 0);
 GL11.glRotatef(seg.getPitch(), 0, 0, 1);
 RenderHelper.renderColorBox(innerWidth, innerWidth, seg.getLength()+0.02, -1315861, innerAlpha);
 RenderHelper.renderColorBox(outerWidth, outerWidth, seg.getLength()+0.05, -16724757, outerAlpha);
 GL11.glTranslated(seg.getLength(), 0, 0);
 GL11.glRotatef(-seg.getPitch(), 0, 0, 1);
 GL11.glRotatef(-seg.getYaw(), 0, 1, 0);
 }


Minebot написал(а):
svk2140 написал(а):
Вращать же надо по перпендикулярному вектору, не?

Да, так и делается, по-моему)

[font=Monaco, Consolas, Courier, monospace]vec.zCoord, [/font][font=Monaco, Consolas, Courier, monospace]0[/font][font=Monaco, Consolas, Courier, monospace], vec.xCoord[/font]
Разве?
 
CoomingSoon написал(а):
Это угол поворота вокруг оси. Вектор же формы (x.y.z). Тогда забей его (roll, yaw, pitch) в градусах/радианах

Я это понимаю. Просто я не могу найти в каком классе есть pitch и yaw. У обычного вектора такого нет
 
Minebot написал(а):
CoomingSoon написал(а):
Это угол поворота вокруг оси. Вектор же формы (x.y.z). Тогда забей его (roll, yaw, pitch) в градусах/радианах

Я это понимаю. Просто я не могу найти в каком классе есть pitch и yaw. У обычного вектора такого нет
Я сам стырил писал:
Код:
pitch = (float)(Math.atan2(end.yCoord - start.yCoord, lengthXZ) / Math.PI * 180);
 yaw = (float)(-Math.atan2(end.zCoord - start.zCoord, end.xCoord - start.xCoord) / Math.PI * 180);
 
svk2140 написал(а):
Minebot написал(а):
CoomingSoon написал(а):
Это угол поворота вокруг оси. Вектор же формы (x.y.z). Тогда забей его (roll, yaw, pitch) в градусах/радианах

Я это понимаю. Просто я не могу найти в каком классе есть pitch и yaw. У обычного вектора такого нет
Я сам стырил писал:
Код:
pitch = (float)(Math.atan2(end.yCoord - start.yCoord, lengthXZ) / Math.PI * 180);
 yaw = (float)(-Math.atan2(end.zCoord - start.zCoord, end.xCoord - start.xCoord) / Math.PI * 180);

Лол, я пытался сделать тоже самое, но работало только на положительном X, а на отрицательном поворот инвертировался
Код:
        GL11.glRotated(Math.toDegrees(Math.atan2(delta.yCoord, length2)), 0, 0 , 1);
        GL11.glRotated(-Math.toDegrees(Math.atan2(delta.zCoord, delta.xCoord)), 0, 1, 0);


Я поменял местами те строки, которые я скинул и стало норм. Тут или я идиот, или openGL просчитывает повороты с конца...


Что бы тему новую не создавать, спрошу. Из-за чего может быть разтроение того, что рисуешь при движении? Скрин не могу дать, ибо это происходит в разные кадры
 
Назад
Сверху