2012-01-03 85 views
0

我已經寫了一些代碼來預製3D採摘,由於某些原因dosn't工作完全正確! (IM使用LWJGL只是讓你知道。)3D採摘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);  
    } 
    } 
} 

我只是不明白什麼是錯的,光線的拍攝,我也打的東西,被刪除但是光線的結果是非常奇怪的,它有時會消除點擊的東西,有時它消除的東西甚至不接近點擊的東西,有時甚至沒有消除任何東西。

編輯:

好了,所以我繼續尋找錯誤和調試光線(由畫SMaL公司點在那裏travles)我現在可以瑟,有一些oviously錯即時通訊發送射線出來...它的起源在世界中心附近,並且總是拍攝到相同的位置,無論我在哪裏指導我的相機...

我最初的想法是在計算我的viewMatrix時可能會出現一些錯誤(因爲無法從lwjgl中的glulookat方法獲取視圖矩陣;我必須將其構建爲自己,我猜這就是問題所在)...

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

好吧,我最終在gamedev和朋友們的幫助下解決了這個問題,這裏是鏈接到answer,我已經發布了代碼!

0

我只是不明白什麼是錯誤的,射線正在拍攝,我打的東西被刪除,但事情並沒有消失,我在屏幕上按下。

OpenGL不是一個場景圖,它是一個繪圖庫。因此,在從內部表示中刪除某些內容後,必須重新繪製場景。而你的代碼缺少一些調用觸發重繪的函數。

+0

感謝您的回覆!我很抱歉,如果我有點不清楚,但這不是我的整個程序,只是處理3D採摘(位於世界控制器)的部分。場景的渲染是在程序的單獨部分完成的(在世界視圖中)。 我可以選擇刪除對象的結果,但由於某種原因刪除了錯誤的對象。 – Wirde 2012-01-03 17:47:20