2017-08-04 1 views
1

タンゴを使用して3Dオブジェクトをスキャンしています。今度は画面上の4点をタッチして矩形を作成し、この矩形の外にあるすべての点群を削除します。タンゴの電話で触ってリタングルを作成してポイントクラウドをフィルタリングする方法

しかし、私はTango SDKで提供されている「ポイントツーポイント」の例をチェックしましたが、ポイントクラウドと画面上のタッチ位置の関係はわかりません。

public void OnTangoPointCloudAvailable(TangoPointCloudData pointCloud) 
{ 
    m_mostRecentPointCloud = pointCloud; 

    // Calculate the time since the last successful depth data 
    // collection. 
    if (m_depthTimestamp != 0.0) 
    { 
     m_depthDeltaTime = (float)((pointCloud.m_timestamp - m_depthTimestamp) * 1000.0); 
    } 

    // Fill in the data to draw the point cloud. 
    m_pointsCount = pointCloud.m_numPoints; 
    if (m_pointsCount > 0) 
    { 
     _SetUpCameraData(); 

     DMatrix4x4 globalTLocal; 
     bool globalTLocalSuccess = m_tangoApplication.GetGlobalTLocal(out globalTLocal); 
     if (!globalTLocalSuccess) 
     { 
      return; 
     } 

     DMatrix4x4 unityWorldTGlobal = DMatrix4x4.FromMatrix4x4(TangoSupport.UNITY_WORLD_T_START_SERVICE) * globalTLocal.Inverse; 

     TangoPoseData poseData; 

     // Query pose to transform point cloud to world coordinates, here we are using the timestamp that we get from depth. 
     bool poseSuccess = _GetDevicePose(pointCloud.m_timestamp, out poseData); 
     if (!poseSuccess) 
     { 
      return; 
     } 

     DMatrix4x4 unityWorldTDevice = unityWorldTGlobal * DMatrix4x4.TR(poseData.translation, poseData.orientation); 

     // The transformation matrix that represents the point cloud's pose. 
     // Explanation: 
     // The point cloud, which is in Depth camera's frame, is put in Unity world's 
     // coordinate system(wrt Unity world). 
     // Then we are extracting the position and rotation from uwTuc matrix and applying it to 
     // the point cloud's transform. 
     DMatrix4x4 unityWorldTDepthCamera = unityWorldTDevice * m_deviceTDepthCamera; 
     transform.position = Vector3.zero; 
     transform.rotation = Quaternion.identity; 

     // Add offset to the point cloud depending on the offset from TangoDeltaPoseController. 
     if (m_tangoDeltaPoseController != null) 
     { 
      m_mostRecentUnityWorldTDepthCamera = m_tangoDeltaPoseController.UnityWorldOffset * unityWorldTDepthCamera.ToMatrix4x4(); 
     } 
     else 
     { 
      m_mostRecentUnityWorldTDepthCamera = unityWorldTDepthCamera.ToMatrix4x4(); 
     } 

     // Converting points array to world space. 
     m_overallZ = 0; 
     for (int i = 0; i < m_pointsCount; ++i) 
     { 
      Vector3 point = pointCloud[i]; 
      m_points[i] = m_mostRecentUnityWorldTDepthCamera.MultiplyPoint3x4(point); 
      m_overallZ += point.z; 
     } 

     m_overallZ = m_overallZ/m_pointsCount; 
     m_depthTimestamp = pointCloud.m_timestamp; //m_timestamp is the time of capture of point cloud 

     // For debugging 
     if (m_updatePointsMesh) 
     { 
      // Need to update indices too! 
      int[] indices = new int[m_pointsCount]; 
      for (int i = 0; i < m_pointsCount; ++i) 
      { 
       indices[i] = i; 
      } 

      m_mesh.Clear(); 
      m_mesh.vertices = m_points; 
      m_mesh.SetIndices(indices, MeshTopology.Points, 0); 
     } 

     // The color should be pose relative; we need to store enough info to go back to pose values. 
     m_renderer.material.SetMatrix("depthCameraTUnityWorld", m_mostRecentUnityWorldTDepthCamera.inverse); 

     // Try to find the floor using this set of depth points if requested. 
     if (m_findFloorWithDepth) 
     { 
      _FindFloorWithDepth(); 
     } 
    } 
    else 
    { 
     m_overallZ = 0; 
    } 

私はCamera.main.ScreenToWorldPointを(使用してワールド空間に画面空間からのタッチ位置を変換しようとしている次のように「TangoPointCloud.cs」ファイルでは、点群はワールド空間に変換されます)。私はまた、世界の空間からスクリーン空間にすべての点群を変換しようとしました。表示された点群とタッチ位置は画面上で同じですが、変換された値は完全に異なります。

誰でもこの問題を認識していますか?私を助けてください。ありがとうございました。

答えて

0

TangoPointCloud.csには、m_pointsにUnityワールドスペースの最新のポイントクラウドが設定されています。したがって、ポイントが画面の特定の部分に含まれるかどうかを判断する最も簡単な方法は、UnityのCamera.WorldToViewportPointメソッドを使用してm_pointsのエントリをビューポートスペースに変換することです(つまり、(0,0)は左下、(1,1)はトップです)右)、指定されたビューポイントがターゲット領域内にあるかどうかを確認します。

例として、使用する前に_WaitForDepthに簡単なチェックを追加することで、画面の中央矩形の外側(幅の半分、高さの半分)にあるすべての点を無視することができます次の選択のポイント:PointToPointGUIController._WaitForDepthから

if (pointIndex > -1) 
{ 
    Vector3 screenPoint = cam.WorldToViewportPoint(
     m_pointCloud.m_points[pointIndex]); 
    if (screenPoint.x > 0.25f && screenPoint.x < 0.75f && 
     screenPoint.y > 0.25f && screenPoint.y < 0.75f) { 
     // Index is valid 
     m_startPoint = m_endPoint; 
     m_endPoint = m_pointCloud.m_points[pointIndex]; 

     m_distance = Vector3.Distance(m_startPoint, m_endPoint); 
    } 
} 

最後に、スペースをビューポート(すなわちピクセル)画面スペースにあるTouch.positionから変換するには、あなたがCamera.ScreenToViewportPointを使用することができ、その後、あなたはこれらを直接比較することができます広告のビューポート座標でepth point。

+0

ありがとうございます。私はチェックし、その結果をあなたに知らせます。 – minpu

関連する問題