2011-05-13 53 views
10

我正在開發一個使用OpenGL渲染圖像的應用程序。檢測OpenGL對象的觸摸?

現在我只想確定我已經鑽過的opengl球體對象的觸摸事件。

這裏我在屏幕上繪製4個對象。現在我該怎麼知道哪個對象已經被觸摸了

。我已經使用onTouchEvent()方法。但它只給出了y座標,但我的座標是

對象是用3D繪製的。

請幫忙,因爲我是OpenGL的新手。

最好的問候, 〜阿努普 enter image description here

+0

球意味着你有三個圈? – 2011-05-23 07:23:43

+0

你能PLZ添加你的3D圖像...? – 2011-05-23 07:31:02

+0

@CapDroid,我添加了圖像,並且想要識別圖像中顯示的這些紅色斑點的觸摸。 – 2011-05-24 08:05:42

回答

3

在我的項目,我選擇的解決方案是:

  1. Unproject你的2D屏幕座標虛擬3D線通過場景去。
  2. 檢測該線條和場景對象的可能交點。

這是相當複雜的事情。

+0

可否請您提供任何代碼,以更好的方式描述這一點。 – 2011-05-13 10:41:07

+0

我不知道我的代碼是否適用於您的任務,因爲它的C#和特定的OpenGL包裝。獲得線條的方法是兩次取消投影屏幕座標:兩個不同的虛擬屏幕深度的近距離和遠距離未投影。 GLUT提供了一個基本的非項目功能,可以作爲一個模型。 – 2011-05-13 10:45:02

+0

我還有其他方法可以做到這一點。請幫幫我。 – 2011-05-13 10:46:50

9

t Google IO有一個關於如何將OpenGL用於Android上的Google Body的會話。選擇身體部位是通過將每個身體部分用純色渲染到隱藏的緩衝區中,然後根據觸摸x,y上的顏色來找到相應的對象。出於性能考慮,這種方式只能渲染觸摸點周圍的20x20像素的小剪輯區域。

+0

嘿,感謝哥們,請你給我提供任何鏈接或任何這樣的例子。幫我。 – 2011-05-16 06:06:58

+0

當然,http://www.youtube.com/watch?v = YLVbLVtjDDw @ 33.00 – 2011-05-16 21:36:01

+0

嘿,感謝夥計.. – 2011-05-17 04:55:43

2

我已經在Direct3D而不是OpenGL ES的只有做到了這一點,但這些步驟如下:

  1. 找到你的模型視圖和投影矩陣。看來OpenGL ES已經刪除了檢索由gluProject()等設置的矩陣的能力。但是您可以使用android.opengl.Matrix成員函數來創建這些矩陣,然後使用glLoadMatrix()進行設置。

  2. 撥打gluUnproject()兩次,一次用winZ = 0,然後用winZ = 1。傳遞你之前計算的矩陣。

  3. 這將從每個呼叫輸出一個3d位置。這對位置在OpenGL「世界空間」中定義了一條光線。

  4. 按順序在每個球體上執行ray - sphere intersection test。 (最靠近攝像頭,否則你可能會選擇一個隱藏在另一個之後的球體)。如果你檢測到一個十字路口,你已經觸及球體。

7

兩種方法(1.隱藏顏色緩衝區和2.相交測試)都有其優點。 1.隱藏顏色緩衝區:像素讀出是一個非常緩慢的操作。 當然是一個簡單的射線球面相交測試的矯枉過正。

  1. Ray-sphere intersection test:這並不難。 這是Ogre3d中一個實現的簡化版本。

    std::pair<bool, m_real> Ray::intersects(const Sphere& sphere) const 
    { 
    const Ray& ray=*this; 
    const vector3& raydir = ray.direction(); 
    // Adjust ray origin relative to sphere center 
    const vector3& rayorig = ray.origin() - sphere.center; 
    m_real radius = sphere.radius; 
    
    // Mmm, quadratics 
    // Build coeffs which can be used with std quadratic solver 
    // ie t = (-b +/- sqrt(b*b + 4ac))/2a 
    m_real a = raydir%raydir; 
    m_real b = 2 * rayorig%raydir; 
    m_real c = rayorig%rayorig - radius*radius; 
    
    // Calc determinant 
    m_real d = (b*b) - (4 * a * c); 
    if (d < 0) 
    { 
        // No intersection 
        return std::pair<bool, m_real>(false, 0); 
    } 
    else 
    { 
        // BTW, if d=0 there is one intersection, if d > 0 there are 2 
        // But we only want the closest one, so that's ok, just use the 
        // '-' version of the solver 
        m_real t = (-b - sqrt(d))/(2 * a); 
        if (t < 0) 
        t = (-b + sqrt(d))/(2 * a); 
        return std::pair<bool, m_real>(true, t); 
    } 
    

    }

也許,對應於光標位置的射線也需要進行計算。再次您可以參考Ogre3d的源代碼:搜索getCameraToViewportRay。基本上,您需要視圖和投影矩陣從2D位置計算光線(3D位置和3D方向)。

+0

就像是一種即興的射線碰撞方法,您必須使用相機信息創建射線,您也可以將您的起點設置爲相機的當前位置並使用觸摸x計算方向,y – Ali1S232 2011-05-21 21:09:36

2

爲尋摸點內圓或不..

public boolean checkInsideCircle(float x,float y, float centerX,float centerY, float Radius) 
    { 
     if(((x - centerX)*(x - centerX))+((y - centerY)*(y - centerY)) < (Radius*Radius)) 
      return true; 
     else 
      return false; 
    } 

其中

1) centerX,centerY are center point of circle. 
2) Radius is radius of circle. 
3) x,y point of touch.. 
+0

嘿,感謝您的回覆,但它不是簡單的圓圈,而是球體。 – 2011-05-24 09:08:01