2012-01-03 2 views
0

Я написал код для предварительной сборки 3D, который почему-то не работает полностью правильно! (Im используя LWJGL только так вы знаете.)3D picking lwjgl

Вот как выглядит код:

if(Mouse.getEventButton() == 1) { 
    if (!Mouse.getEventButtonState()) { 
    Camera.get().generateViewMatrix(); 

    float screenSpaceX = ((Mouse.getX()/800f/2f)-1.0f)*Camera.get().getAspectRatio(); 
    float screenSpaceY = 1.0f-(2*((600-Mouse.getY())/600f)); 
    float displacementRate = (float)Math.tan(Camera.get().getFovy()/2); 

    screenSpaceX *= displacementRate; 
    screenSpaceY *= displacementRate; 

    Vector4f cameraSpaceNear = new Vector4f((float) (screenSpaceX * Camera.get().getNear()), (float) (screenSpaceY * Camera.get().getNear()), (float) (-Camera.get().getNear()), 1); 
    Vector4f cameraSpaceFar = new Vector4f((float) (screenSpaceX * Camera.get().getFar()), (float) (screenSpaceY * Camera.get().getFar()), (float) (-Camera.get().getFar()), 1); 

    Matrix4f tmpView = new Matrix4f(); 
    Camera.get().getViewMatrix().transpose(tmpView); 
    Matrix4f invertedViewMatrix = (Matrix4f)tmpView.invert(); 

    Vector4f worldSpaceNear = new Vector4f(); 
    Matrix4f.transform(invertedViewMatrix, cameraSpaceNear, worldSpaceNear); 

    Vector4f worldSpaceFar = new Vector4f(); 
    Matrix4f.transform(invertedViewMatrix, cameraSpaceFar, worldSpaceFar); 


    Vector3f rayPosition = new Vector3f(worldSpaceNear.x, worldSpaceNear.y, worldSpaceNear.z); 
    Vector3f rayDirection = new Vector3f(worldSpaceFar.x - worldSpaceNear.x, worldSpaceFar.y - worldSpaceNear.y, worldSpaceFar.z - worldSpaceNear.z); 

    rayDirection.normalise(); 

    Ray clickRay = new Ray(rayPosition, rayDirection); 

    Vector tMin = new Vector(), tMax = new Vector(), tempPoint; 
    float largestEnteringValue, smallestExitingValue, temp, closestEnteringValue = Camera.get().getFar()+0.1f; 
    Drawable closestDrawableHit = null; 
    for(Drawable d : this.worldModel.getDrawableThings()) { 
     // Calcualte AABB for each object... needs to be moved later... 
     firstVertex = true; 
     for(Surface surface : d.getSurfaces()) { 
      for(Vertex v : surface.getVertices()) { 
       worldPosition.x = (v.x+d.getPosition().x)*d.getScale().x; 
       worldPosition.y = (v.y+d.getPosition().y)*d.getScale().y; 
       worldPosition.z = (v.z+d.getPosition().z)*d.getScale().z; 
       worldPosition = worldPosition.rotate(d.getRotation()); 
       if (firstVertex) { 
        maxX = worldPosition.x; maxY = worldPosition.y; maxZ = worldPosition.z; 
        minX = worldPosition.x; minY = worldPosition.y; minZ = worldPosition.z; 
        firstVertex = false; 
       } else { 
        if (worldPosition.x > maxX) { 
         maxX = worldPosition.x; 
        } 
        if (worldPosition.x < minX) { 
         minX = worldPosition.x; 
        } 
        if (worldPosition.y > maxY) { 
         maxY = worldPosition.y; 
        } 
        if (worldPosition.y < minY) { 
         minY = worldPosition.y; 
        } 
        if (worldPosition.z > maxZ) { 
         maxZ = worldPosition.z; 
        } 
        if (worldPosition.z < minZ) { 
         minZ = worldPosition.z; 
        } 
       } 
      } 
     } 

     // ray/slabs intersection test... 


     // clickRay.getOrigin().x + clickRay.getDirection().x * f = minX 
     // clickRay.getOrigin().x - minX = -clickRay.getDirection().x * f 
     // clickRay.getOrigin().x/-clickRay.getDirection().x - minX/-clickRay.getDirection().x = f 
     // -clickRay.getOrigin().x/clickRay.getDirection().x + minX/clickRay.getDirection().x = f 


     largestEnteringValue = -clickRay.getOrigin().x/clickRay.getDirection().x + minX/clickRay.getDirection().x; 
     temp = -clickRay.getOrigin().y/clickRay.getDirection().y + minY/clickRay.getDirection().y; 
     if(largestEnteringValue < temp) { 
      largestEnteringValue = temp; 
     } 
     temp = -clickRay.getOrigin().z/clickRay.getDirection().z + minZ/clickRay.getDirection().z; 
     if(largestEnteringValue < temp) { 
      largestEnteringValue = temp; 
     } 

     smallestExitingValue = -clickRay.getOrigin().x/clickRay.getDirection().x + maxX/clickRay.getDirection().x; 
     temp = -clickRay.getOrigin().y/clickRay.getDirection().y + maxY/clickRay.getDirection().y; 
     if(smallestExitingValue > temp) { 
      smallestExitingValue = temp; 
     } 
     temp = -clickRay.getOrigin().z/clickRay.getDirection().z + maxZ/clickRay.getDirection().z; 
     if(smallestExitingValue < temp) { 
      smallestExitingValue = temp; 
     } 


      if(largestEnteringValue > smallestExitingValue) { 
       //System.out.println("Miss!"); 
      } else { 
       if (largestEnteringValue < closestEnteringValue) { 
        closestEnteringValue = largestEnteringValue; 
        closestDrawableHit = d; 
       } 
      } 

    } 
    if(closestDrawableHit != null) { 
     System.out.println("Hit at: (" + clickRay.setDistance(closestEnteringValue).x + ", " + clickRay.getCurrentPosition().y + ", " + clickRay.getCurrentPosition().z); 
     this.worldModel.removeDrawableThing(closestDrawableHit);  
    } 
    } 
} 

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

Edit:

Хорошо, так я продолжил поиски ошибок и отладки луча (по живописи Смаль точки, где она travles) теперь я могу се, что есть что-то oviously неправильно с лучом, что им отправка out ... он имеет свое происхождение вблизи мирового центра и всегда выстреливает в одно и то же положение независимо от того, где я направляю свою камеру ...

Мои первоначальные жесткости - это может быть некоторая ошибка в том, как я вычислил свой viewMatrix (так как невозможно получить viewmatrix от метода glulookat в lwjgl, я должен создать его сам, и я думаю, что там проблема)

Edit2:

Это, как я вычислить его в данный момент:

private double[][] viewMatrixDouble = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,1}}; 

public Vector getCameraDirectionVector() { 
    Vector actualEye = this.getActualEyePosition(); 
    return new Vector(lookAt.x-actualEye.x, lookAt.y-actualEye.y, lookAt.z-actualEye.z); 
} 

public Vector getActualEyePosition() { 
    return eye.rotate(this.getRotation()); 
} 

public void generateViewMatrix() { 

    Vector cameraDirectionVector = getCameraDirectionVector().normalize(); 
    Vector side = Vector.cross(cameraDirectionVector, this.upVector).normalize(); 
    Vector up = Vector.cross(side, cameraDirectionVector); 

    viewMatrixDouble[0][0] = side.x;     viewMatrixDouble[0][1] = up.x;     viewMatrixDouble[0][2] = -cameraDirectionVector.x;     
    viewMatrixDouble[1][0] = side.y;     viewMatrixDouble[1][1] = up.y;     viewMatrixDouble[1][2] = -cameraDirectionVector.y;     
    viewMatrixDouble[2][0] = side.z;     viewMatrixDouble[2][1] = up.z;     viewMatrixDouble[2][2] = -cameraDirectionVector.z;     


    /* 
    Vector actualEyePosition = this.getActualEyePosition(); 
    Vector zaxis = new Vector(this.lookAt.x - actualEyePosition.x, this.lookAt.y - actualEyePosition.y, this.lookAt.z - actualEyePosition.z).normalize(); 
    Vector xaxis = Vector.cross(upVector, zaxis).normalize(); 
    Vector yaxis = Vector.cross(zaxis, xaxis); 
    viewMatrixDouble[0][0] = xaxis.x;     viewMatrixDouble[0][1] = yaxis.x;     viewMatrixDouble[0][2] = zaxis.x;     
    viewMatrixDouble[1][0] = xaxis.y;     viewMatrixDouble[1][1] = yaxis.y;     viewMatrixDouble[1][2] = zaxis.y;     
    viewMatrixDouble[2][0] = xaxis.z;     viewMatrixDouble[2][1] = yaxis.z;     viewMatrixDouble[2][2] = zaxis.z;     
    viewMatrixDouble[3][0] = -Vector.dot(xaxis, actualEyePosition); viewMatrixDouble[3][1] =-Vector.dot(yaxis, actualEyePosition); viewMatrixDouble[3][2] = -Vector.dot(zaxis, actualEyePosition); 
    */ 
    viewMatrix = new Matrix4f(); 
    viewMatrix.load(getViewMatrixAsFloatBuffer()); 
} 

Было бы Верри greatfull если кто-нибудь может проверить, если это неправильно или правильно, и если это не так; предоставить мне с правильным способом сделать это ... Я прочитал много потоков и документаций об этом, но я не могу шов, чтобы wrapp моей головы вокруг него ...

ответ

0

Хорошо, поэтому я окончательно решил его с помощью парней в гамедеве и другом, вот ссылка на answer, где я опубликовал код!

0

Я просто не понимаю, что не так, луч стреляет, и я ударяю вещи, которые удаляются, но вещи не исчезают, когда я нажимаю на экран.

OpenGL не является графиком сцены, это библиотека для рисования. Поэтому после удаления чего-либо из вашего внутреннего представления вы должны перерисовать сцену. И ваш код пропускает некоторый вызов функции, которая вызывает перерисовку.

+0

Спасибо за ваш ответ! Мне жаль, если я был немного неясен, но это не моя вся программа, а только часть, которая обрабатывает 3D-подборку (которая находится в мировом контроллере). Оформление сцены выполняется в отдельной части программы (в мировоззрении). Я могу удалить результат удаленных объектов, но по какой-то причине удалив неправильные объекты. – Wirde

 Смежные вопросы

  • Нет связанных вопросов^_^