2012-12-19 10 views
1

세계 좌표에서 마우스 위치를 찾으려고하지만 올바른 코드를 찾는 데 문제가 있습니다. 현재 광선을 결정할 때 이것을 사용합니다.quadtree heightmaped terrain에서 마우스 세계 좌표 (3D) 찾기

float pointX, pointY; 
D3DXMATRIX projectionMatrix, viewMatrix, inverseViewMatrix, worldMatrix, translateMatrix, inverseWorldMatrix; 
D3DXVECTOR3 direction, origin, rayOrigin, rayDirection; 
bool intersect, result; 


// Move the mouse cursor coordinates into the -1 to +1 range. 
pointX = ((2.0f * (float)mouseX)/(float)m_screenWidth) - 1.0f; 
pointY = (((2.0f * (float)mouseY)/(float)m_screenHeight) - 1.0f) * -1.0f; 

// Adjust the points using the projection matrix to account for the aspect ratio of the viewport. 
m_Direct3D->GetProjectionMatrix(projectionMatrix); 
pointX = pointX/projectionMatrix._11; 
pointY = pointY/projectionMatrix._22; 

// Get the inverse of the view matrix. 
m_Camera->GetViewMatrix(viewMatrix); 
D3DXMatrixInverse(&inverseViewMatrix, NULL, &viewMatrix); 

// Calculate the direction of the picking ray in view space. 
direction.x = (pointX * inverseViewMatrix._11) + (pointY * inverseViewMatrix._21) + inverseViewMatrix._31; 
direction.y = (pointX * inverseViewMatrix._12) + (pointY * inverseViewMatrix._22) + inverseViewMatrix._32; 
direction.z = (pointX * inverseViewMatrix._13) + (pointY * inverseViewMatrix._23) + inverseViewMatrix._33; 

// Get the origin of the picking ray which is the position of the camera. 
origin = m_Camera->GetPosition(); 

이렇게하면 ray의 원점과 방향이 나옵니다.

하지만 ...

내가 쿼드 트리로 분리하는 하이트와 사용자 정의 메시 (안 다이렉트 X의 하나)을 사용하고 난 내 논리가 맞다면, 내가 결정하는 절두체를 사용하여 시도 모른다 quadtree의 어느 노드가 보이는지, 그 노드에서만 삼각형의 교차점을 확인하는 코드는 다음과 같습니다.

참고 * m_mousepos는 벡터입니다.

bool QuadTreeClass::getTriangleRay(NodeType* node, FrustumClass* frustum, ID3D10Device* device, D3DXVECTOR3 vPickRayDir, D3DXVECTOR3 vPickRayOrig){ 


    bool result; 
    int count, i, j, indexCount; 
    unsigned int stride, offset; 
    float fBary1, fBary2; 
    float fDist; 
    D3DXVECTOR3 v0, v1, v2; 
    float p1, p2, p3; 


    // Check to see if the node can be viewed. 
    result = frustum->CheckCube(node->positionX, 0.0f, node->positionZ, (node->width/2.0f)); 

    if(!result) 
    { 
     return false; 
    } 




    // If it can be seen then check all four child nodes to see if they can also be seen. 
    count = 0; 
    for(i=0; i<4; i++) 
    { 
     if(node->nodes[i] != 0) 
     { 
      count++; 
      getTriangleRay(node->nodes[i], frustum, device, vPickRayOrig, vPickRayDir); 
     } 
    } 

    // If there were any children nodes then dont continue 

    if(count != 0) 
    { 
     return false; 
    } 

     // Now intersect each triangle in this node 

    j = 0; 

    for(i=0; i<node->triangleCount; i++){ 

     j = i * 3; 

     v0 = D3DXVECTOR3(node->vertexArray[j].x, node->vertexArray[j].y, node->vertexArray[j].z); 
     j++; 
     v1 = D3DXVECTOR3(node->vertexArray[j].x, node->vertexArray[j].y, node->vertexArray[j].z); 
     j++; 
     v2 = D3DXVECTOR3(node->vertexArray[j].x, node->vertexArray[j].y, node->vertexArray[j].z); 

     result = IntersectTriangle(vPickRayOrig, vPickRayDir, v0, v1, v2, &fDist, &fBary1, &fBary2); 

     if(result == true){ 

         // intersection = true, so get a aproximate center of the triangle on the world 

      p1 = (v0.x + v0.x + v0.x)/3; 
      p2 = (v0.y + v1.y + v2.y)/3; 
      p3 = (v0.z + v1.z + v2.z)/3; 

      m_mousepos = D3DXVECTOR3(p1, p2, p3); 

      return true; 

     } 

    } 




} 

bool QuadTreeClass::IntersectTriangle(const D3DXVECTOR3& orig, const D3DXVECTOR3& dir,D3DXVECTOR3& v0, D3DXVECTOR3& v1, D3DXVECTOR3& v2, FLOAT* t, FLOAT* u, FLOAT* v){ 
    // Find vectors for two edges sharing vert0 
    D3DXVECTOR3 edge1 = v1 - v0; 
    D3DXVECTOR3 edge2 = v2 - v0; 

    // Begin calculating determinant - also used to calculate U parameter 
    D3DXVECTOR3 pvec; 
    D3DXVec3Cross(&pvec, &dir, &edge2); 

    // If determinant is near zero, ray lies in plane of triangle 
    FLOAT det = D3DXVec3Dot(&edge1, &pvec); 

    D3DXVECTOR3 tvec; 
    if(det > 0) 
    { 
     tvec = orig - v0; 
    } 
    else 
    { 
     tvec = v0 - orig; 
     det = -det; 
    } 

    if(det < 0.0001f) 
     return FALSE; 

    // Calculate U parameter and test bounds 
    *u = D3DXVec3Dot(&tvec, &pvec); 
    if(*u < 0.0f || *u > det) 
     return FALSE; 

    // Prepare to test V parameter 
    D3DXVECTOR3 qvec; 
    D3DXVec3Cross(&qvec, &tvec, &edge1); 

    // Calculate V parameter and test bounds 
    *v = D3DXVec3Dot(&dir, &qvec); 
    if(*v < 0.0f || *u + *v > det) 
     return FALSE; 

    // Calculate t, scale parameters, ray intersects triangle 
    *t = D3DXVec3Dot(&edge2, &qvec); 
    FLOAT fInvDet = 1.0f/det; 
    *t *= fInvDet; 
    *u *= fInvDet; 
    *v *= fInvDet; 


    return TRUE; 
} 

이 코드가 맞습니까? 그것이 내 문제라면 quadtree와 관련이 있어야합니다.

감사합니다.

+0

마우스 위치 란 무엇입니까? AFAIK, 마우스 위치는 화면의 2D 지점입니다. – zdd

+0

내 마우스의 3D 좌표 (내 지형과 교차) – user1900984

+0

그건 마우스 위치가 아니고, 광선을 쏘는 선과 메쉬의 교차점입니다. 분명히하기 위해 질문을 편집해야한다고 생각합니다. – zdd

답변

2

교차로를 찾기 위해 모든 보이는 삼각형을 반복하면 매우 비쌉니다. 하이트 맵이 더 세밀 해지면 추가 비용이 발생합니다. I 원점에서 시작 clickray의 높이에 대한 단계별 검색을 수행

: 내 높이 맵에 대한

나는 다른 접근 방식을 사용합니다. 모든 단계에서 현재 위치가 광선을 따라 이동하고 하이트 맵의 높이에 대해 테스트됩니다 (따라서 높이 함수가 필요함). 현재 위치가 하이트 맵 아래에 있으면, 더 복잡한 위치를 찾기 위해 마지막 인터벌이 추가 반복에 의해 다시 검색됩니다. 이것은 heightmap에서 stepsize와 관련하여 하이트 맵의 빈도가 너무 높지 않으면 작동합니다 (그렇지 않으면 피크를 뛰어 넘을 수 있음).

+0

감사합니다, 나는 그것을했고 그것은 잘 작동했습니다! – user1900984