2013-10-02 2 views
0

방금 ​​DirectX를 배우기 시작했습니다. 현재 큐브와 큐브를 중심으로 움직일 수있는 카메라가 있습니다.카메라 LookAt 위치를 3 차원으로 계산하십시오 (DirectX)

하지만 카메라를 약간 (왼쪽/오른쪽/위/아래) 전환 할 수 있도록 기능을 만들고 싶습니다. 저는 2D로 만드는 법을 쉽게 이해합니다 : LookAt 함수에서 X와 Y를 바꿀 수 있습니다. 어떻게하면 같은 일을 3D로 할 수 있습니까? 3 차원이 있고 내 카메라는 어떤 각도를 취할 수 있습니다 ...

저는 카메라 벡터에 수직 인 평면을 찾고 2D와 같이 처리해야한다고 생각합니다. Image

아니면 더 쉽게 할 수 있습니까?

+0

카메라의 위치를 ​​변경하고 항상 큐브를 보거나 카메라의 위치를 ​​수정하고 회전 시키길 원하십니까? –

+0

내 카메라는 항상 큐브를보고 고정 된 위치로 회전시키고 싶습니다. – Mo3r

답변

0

보기 변환은 까다로운 작업입니다. 일반적으로 모델 변형이 있습니다. 이동, 회전 또는 크기 조절 (세계 변형).

그러나보기 변환은 시스템 변환입니다. 카메라를 원래 위치에서 원래 위치로 이동시키는 모델 변환이라고 상상해보십시오. 물론, 역 뷰 변환을 보는 것이 더 쉽습니다. 카메라를 그 위치에 놓는 것.

그리고 이것이 우리가 할 일입니다. 카메라를 배치하는 변환 M이 있다고 가정 해 봅시다. 해당 뷰 변환은 그 역입니다 : V = M^(-1). 카메라 객체를 회전하고 싶었다면, 당신은 단지 모델 변환에 회전 행렬을 곱 것 : M을 적용한 후 그 위치에 카메라를 회전 할

M' = R * M 

. 따라하기 뷰 변환은 여전히 ​​반대입니다. M'에 역을 적용하면

V' = (M')^(-1) 
    = (R * M)^(-1) 
    = M^(-1) * R^(-1) 

우리는 M^(-1) 이전 뷰 변환 것을 볼 산출한다. 따라서 :

V' = V * R^(-1) 

그래서 당신은, 카메라를 회전 현재 뷰 매트릭스의 오른쪽에 (부정적인 각도) 회전 행렬을 곱합니다. 게임의 시작 부분에서

  • LookAt 방법 뷰 행렬을 설정 :

    그래서 워크 플로우는 다음과 같은 것입니다.
  • 플레이어가 카메라를 회전 할 때마다 회전 행렬에 현재 뷰 행렬을 곱하십시오. 각도가 너무 크지 않은지 확인하십시오. 매 프레임마다 10 ° 씩 회전하면 60fps로 초당 600 *을 이미 갖게됩니다.
  • 카메라를 재설정 할 때마다 LookAt 방법을 다시 사용하십시오.

위아래로 돌아가려면 XMMatrixRotationX을 사용하십시오. 좌우로 돌리려면 XMMatrixRotationY을 사용하십시오. XMMatrixRotationZ은 롤이됩니다.

0

카메라 회전의 경우 D3DXMatrixLookAtLH 메서드를 사용하십시오. 당신의 질문은 눈의 원하는 "at"또는 "target"을 계산하는 방법에 관한 것입니다. 이 Vector3는 2D에서 사용 된 것과 동일한 trig 메소드를 사용하여 계산되지만 추가 치수만으로 계산됩니다. 회전을 위해 Vector3이 필요하며 각 구성 요소는 해당 축을 중심으로 회전합니다. 그런 다음 아래 방법을 사용하여 앞에서 설명한 방법으로 만든 행렬에 회전을 적용합니다.

세계 곳곳에있는 객체에서 동일한 작업을 수행하려면 회전 방향에 따라 DirectX 메서드 D3DXMatrixRotation(X,Y,Z)을 사용하십시오. 올바르게 지향 된 세계에서 왼쪽과 오른쪽은 Y 축을 중심으로 회전하고 위쪽과 아래쪽은 X 축을 중심으로 회전하며 기울임은 Z 축을 중심으로 회전합니다. 물론 이것은 행렬 회전이 아니라 쿼터니언을위한 것입니다.

  • I dentity
  • S 캐일
  • R otation
  • : 회전 (또는 조작 작업)을 수행 할 때

    동작들의 순서 (ISROT)를 기억하는 기억

  • rbit
  • T ranslation

당신이 보이는 펑키 물건 일이 필요 끝나지 않는이 방법. 또한 D3DXMatrixYawPitchRoll 방법을 고려하십시오.

0

먼저 should read this question입니다.

기본적으로 행렬은 x, y, z 벡터와 시스템 위치 (상위 시스템의 좌표 내)가 포함 된 좌표계입니다. 따라서 "LookAt"루틴을 사용하지 않고 행렬을 떼어 내고 벡터를 수정하고 행렬을 다시 작성할 수 있습니다. 중요한 점은, 카메라 매트릭스 (뷰 변환)는이 시점에서 카메라 대신 오브젝트가 배치 된 경우 오브젝트 매트릭스 (월드 변환)의 반대입니다. 그러나 카메라 행렬은 특별한 속성을 가지고 있기 때문에 (축은 직각이며 길이가 단위가 없습니다), 단순히 행렬을 조 변경하고 행렬의 "위치"부분을 다시 계산할 수 있습니다.

이 오래된 함수는 벡터 세트에서 카메라 매트릭스 ("뷰"변환 또는 D3DTS_VIEW)를 빌드합니다. x 포인트가 오른쪽이고 y 포인트가 위로, z 포인트가 앞으로, pos이 카메라 위치입니다.벡터로

typedef D3DXVECTOR3 Vector3; 
typedef D3DXMATRIX Matrix; 

void vecToCameraMat(Matrix& m, const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& pos){ 
    m._11 = x.x; 
    m._12 = y.x; 
    m._13 = z.x; 
    m._14 = 0; 

    m._21 = x.y; 
    m._22 = y.y; 
    m._23 = z.y; 
    m._24 = 0; 

    m._31 = x.z; 
    m._32 = y.z; 
    m._33 = z.z; 
    m._34 = 0; 

    m._41 = - (pos.x*x.x + pos.y*x.y + pos.z*x.z);//(pos.x*x.x + pos.y*y.x + pos.z*z.x); 
    m._42 = - (pos.x*y.x + pos.y*y.y + pos.z*y.z); 
    m._43 = - (pos.x*z.x + pos.y*z.y + pos.z*z.z); 
    m._44 = 1; 
} 

해체 카메라 매트릭스 :

void cameraMatToVec(Vector3& x, Vector3& y, Vector3& z, Vector3& pos, const Matrix& m){ 
    x.x = m._11; 
    y.x = m._12; 
    z.x = m._13; 

    x.y = m._21; 
    y.y = m._22; 
    z.y = m._23; 

    x.z = m._31; 
    y.z = m._32; 
    z.z = m._33; 

    pos.x = -(m._41*x.x + m._42*y.x + m._43*z.x); 
    pos.y = -(m._41*x.y + m._42*y.y + m._43*z.y); 
    pos.z = -(m._41*x.z + m._42*y.z + m._43*z.z); 
} 

그리고이 OBJECT 매트릭스를 구성한다 (즉 "세계"변환 또는 D3DTS_WORLD) 벡터들의 유사한 세트를 사용. 벡터의 집합으로

void vecToMat(Matrix& m, const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& pos){ 
    m._11 = x.x; 
    m._12 = x.y; 
    m._13 = x.z; 
    m._14 = 0; 

    m._21 = y.x; 
    m._22 = y.y; 
    m._23 = y.z; 
    m._24 = 0; 

    m._31 = z.x; 
    m._32 = z.y; 
    m._33 = z.z; 
    m._34 = 0; 

    m._41 = pos.x; 
    m._42 = pos.y; 
    m._43 = pos.z; 
    m._44 = 1; 
} 

해체 "개체"매트릭스 : 카메라

void matToVec(Vector3& x, Vector3& y, Vector3& z, Vector3& vpos, const Matrix& m){ 
    x.x = m._11; 
    x.y = m._12; 
    x.z = m._13; 

    y.x = m._21; 
    y.y = m._22; 
    y.z = m._23; 

    z.x = m._31; 
    z.y = m._32; 
    z.z = m._33; 

    vpos.x = m._41; 
    vpos.y = m._42; 
    vpos.z = m._43; 
} 

, x, yz1.0의 길이를 가져야하고, 서로 직교한다.

이러한 루틴은 DirectX에만 해당되며 (보기) 행렬이 왼손잡이라고 가정합니다.

카메라를 "오른쪽"으로 이동하려면 매트릭스를 구성 요소로 나누고 "x"를 "pos"에 추가하고 다시 구성해야합니다. "보기"를 사용하기를 원한다면 "보기 위치"와 "위치보기"에 모두 "x"를 추가해야합니다.

관련 문제