//не стоит каждый раз создавать новый буфер, это чревато проблемами с производительностью
private static IntBuffer viewportBuf = BufferUtils.createIntBuffer(16);
private static FloatBuffer projectionBuf = BufferUtils.createFloatBuffer(16);
private static FloatBuffer modelviewBuf = BufferUtils.createFloatBuffer(16);
/**
* Метод использует текущие матрицу проекции и modelview матрицу, так что вызывать
* его во время отрисовки ГУИ - не дело. Вызывай в RenderWorldLastEvent, например
*/
public MovingObjectPosition calcBlockMouseOver(World world){
GL11.glGetInteger(GL11.GL_VIEWPORT, viewportBuf);
GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projectionBuf);
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelviewBuf);
float vx = Mouse.getX();
// я не очень помню, где находится 0 по оси Y: сверху или снизу.
// если сверху, то vy = mc.displayHeight - Mouse.getY().
float vy = Mouse.getY();
// этот буфер не нативный, так что всё ОК
FloatBuffer resultBuf = FloatBuffer.allocate(3);
// В той статье предполагается ставить z на -1,
// но я не уверен, что оно будет правильно работать.
// Всё-таки миниальная глубина - это 0, а не -1. Решай сам, кому верить
Project.gluUnProject(vx, vy, -1, modelviewBuf, projectionBuf, viewportBuf, resultBuf);
Vec3 p1 = Vec3.createVectorHelper(resultBuf.get(0), resultBuf.get(1), resultBuf.get(2));
Project.gluUnProject(vx, vy, 1, modelviewBuf, projectionBuf, viewportBuf, resultBuf);
Vec3 p2 = Vec3.createVectorHelper(resultBuf.get(0), resultBuf.get(1), resultBuf.get(2));
//И всё бы ничего, но p1 и p2 центрированы то ли к камере, то ли к голове персонажа.
//Склоняюсь ко второму варианту. Поправим это.
p1 = p1.addVector(RenderManager.renderPosX, RenderManager.renderPosY, RenderManager.renderPosZ);
p2 = p2.addVector(RenderManager.renderPosX, RenderManager.renderPosY, RenderManager.renderPosZ);
return world.clip(p1, p2);
}