1 인칭 카메라는 어떻게 구현해야합니까?


12

저는 초보자 프로그래머이며 일인칭 카메라를 통해 방을 돌아 다닐 수있는 프로젝트를 만들고 있습니다. 지금까지 건물이 그려져 있지만 지금 막 붙어서 일인칭 카메라로 어떻게 걸을 수 있는지 모릅니다.

누구든지 내가 사용할 수있는 카메라 클래스 또는 유용한 코드를 가리킬 수 있습니까?


답변:


7

다음은 카메라 회전에 대한 팁입니다 (mouselook). 카메라 클래스를 처음부터 처음부터 구현 한 후, 좋은 회전 동작을 위해 몇 가지 추가 조정을 수행해야한다는 것을 알았습니다.

  1. 각 프레임에서 마우스 좌표를 화면 중앙으로 재설정하여 마우스가 화면 경계에 걸리지 않도록합니다.

  2. 카메라의 "위"벡터를 유지하고 (롤 금지) "옆으로"벡터를 다시 계산하십시오.

  3. 세로 + y 축을지나 위로 또는 -y 축을 넘어서 위로 볼 수 없음

  4. 올바른 회전 순서를 가져옵니다 (먼저 위 / 아래로 이동 한 다음 왼쪽 / 오른쪽)

  5. 각 프레임의 "위", "목표"및 "옆으로"벡터를 다시 정규화

이 코드 중 일부를 유리하게 사용할 수 있기를 바랍니다.

    const int mouseDeltaX = mouseAxisX * (input.GetMouseX() - int(app.GetWidth()/2));
    const int mouseDeltaY = -mouseAxisY * (input.GetMouseY() - int(app.GetHeight()/2));  // mouse y-offsets are upside-down!

    // HACK:  reset the cursor pos.:
    app.SetCursorPosition(app.GetWidth()/2, app.GetHeight()/2);

    float lookRightRads = mouseDeltaX * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;
    float lookUpRads    = mouseDeltaY * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;

    // Limit the aim vector in such a way that the 'up' vector never drops below the horizon:
    static const float zenithMinDeclination = DEG_TO_RAD * MIN_UPWARDS_TILT_DEG;
    static const float zenithMaxDeclination = DEG_TO_RAD * (180.0f - MIN_UPWARDS_TILT_DEG);

    const float currentDeclination = std::acosf(camera.aim_.y_);  ///< declination from vertical y-axis
    const float requestedDeclination = currentDeclination - lookUpRads;

    // Clamp the up/down rotation to at most the min/max zenith:
    if(requestedDeclination < zenithMinDeclination)
        lookUpRads = currentDeclination - zenithMinDeclination;
    else if(requestedDeclination > zenithMaxDeclination)
        lookUpRads = currentDeclination - zenithMaxDeclination;

    // Rotate both the "aim" vector and the "up" vector ccw by 
    // lookUpRads radians within their common plane -- which should 
    // also contain the y-axis:  (i.e. no diagonal tilt allowed!)
    camera.aim_.rotateAboutAxis(camera.right_, lookUpRads);
    camera.up_.rotateAboutAxis(camera.right_, lookUpRads);
    ASSERT_ORTHONORMAL(camera.aim_, camera.up_, camera.right_);

    // Rotate both the "aim" and the "up" vector ccw about the vertical y-axis:
    // (again, this keeps the y-axis in their common plane, and disallows diagonal tilt)
    camera.aim_.rotateAboutAxis(Y_AXIS, -lookRightRads);
    camera.up_.rotateAboutAxis(Y_AXIS, -lookRightRads);
    camera.updateRightAxis();

참고 :

mouseAxisX 및 mouseAxisY는 x 또는 y 축 마우스 모양을 반전 시킬지 여부에 따라 +/- 1로 정의됩니다. 일반적으로 게임은 적어도 세로 축에이 옵션을 제공합니다.

MIN_UPWARDS_TILT_DEG는 1.0 도로 정의됩니다 (따라서 뷰어는 -89도에서 +89도까지 상향으로 볼 수 있습니다. 이는 180도 수직 범위와 매우 유사하게 보입니다. .

camera.aim_, camera.right_ 및 camera.up_은 물론 3D 벡터이며, wikipedia와 여러 온라인 소스에서 함께 할 수있는 rotateAboutAxis () 메소드입니다. Y_AXIS는 고정 상수 (0,1,0) 벡터입니다.

ASSERT_ORTHONORMAL ()은 디버그 모드 전용 상태 검사이며 최적화 / 릴리스 모드에서 컴파일되지 않습니다.

C 스타일 코드에 대한 사전 사과 ... 다음으로 다시 Mediocritus라는 사람의 조언을 받고 있습니다! ; ^)


무슨 소리 야? C 스타일 코드는 해커 정신의 초석입니다! 8-)
blissfreak 4

5

이에 대한 몇 가지 방법이 있습니다 ( 예 : 여기 , 여기여기 에있는 자습서를 참조 하여 인터넷을 통해 인터넷을 통해 더 많이 사용 가능). 온라인에서 찾을 수있는 리소스에 사용 된 기술은 약간 다를 수 있지만 (D3D, XNA, OpenGL 등), 기본 원칙은 동일합니다.

  • 카메라 객체는 위치와 방향 및 선택적으로 방향과 함께 카메라 좌표계의 직교 기반을 형성하는 다른 벡터 쌍을 유지합니다.
  • 카메라의 공용 API는 기본 벡터 주위로 카메라를 요잉, 피칭 및 선택적으로 롤링하는 방법을 노출합니다. 카메라 방향을 조정하면 이후 사용을 위해 기본 벡터가 업데이트됩니다.

벡터를 직접 저장하거나 필요할 때마다 기본 뷰 매트릭스를 다시 계산하도록 선택할 수 있습니다. 이 기술에는 많은 유연성이 있으므로 일반적인 단계를 넘어서 도움이 필요한 경우보다 구체적인 쿼리로 새 질문을 게시 할 수 있습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.