2017-11-11 7 views
3

마우스 움직임으로 카메라보기를 변경하고 카메라가 원점을 중심으로 arcball 방식으로 이동하지 않고 장면 아래로 이동하려고합니다. 그래서 종류의 돔 - 같은보기.Arcball 카메라 확대/축소

다음은 눈 좌표를 가져 와서 반 arcball보기를 만드는 데 만족스럽게 작동합니다. 장면 아래에서 볼 수 없도록 조건을 하드 코드했습니다. 이 조건의 결과로 장면 아래로가는 대신 카메라가 중앙으로 확대됩니다. 나는 카메라가이 '줌'을하는 것을 방해하는 방법에 대해 내 마음을 감쌀 수 없다. 돔 뷰의 가장 낮은 부분에 도달하면 왼쪽이나 오른쪽으로 만 이동할 수 있습니다. 거리는 일정합니다. 어떤 지침?

void onMotion(int x, int y) { 
    camX = distance * -sinf(x*(M_PI/180)) * cosf((y)*(M_PI/180)); 
    camY = distance * -sinf((y)*(M_PI/180)); 
    camZ = -distance * cosf((x)*(M_PI/180)) * cosf((y)*(M_PI/180)); 
    if (camY < 4) 
     camY = 4; 
    glutPostRedisplay(); 
} 
+0

거리가 전혀 변하지 않습니까? 아니면 그렇지 않다면 시야가 변하는 것입니까? 또한 확대/축소 효과가 발생할 수 있습니다. – user1118321

+0

@ user1118321, 거리는 고정되어 있지 않습니다. FOV가 바뀌고 있는지 어떻게 확인할 수 있습니까? – rafvasq

+1

시야는 투영 행렬에 의해 제어됩니다. 변경되는 경우 잠재적으로 확대/축소 효과가 생성됩니다. – user1118321

답변

2

이것은 거리가 확정되지 않는다는 사실에 기인한다고 생각합니다. camY < 4. 카메라가 구형의 남극에 가까이있을 때를 생각해보십시오. y 좌표는 4로 설정되지만 x와 z는 여전히 축 근처에 있습니다.

변수를 설정하는 대신 새 y 좌표로 모든 값을 다시 계산해야합니다. camY을 4로 설정 한 다음 camXcamZ을 다시 새 방향으로 적절한 거리로 밀면됩니다. 이 같은 것 :

if (camY < 4) 
{ 
    camY = 4; 
    // Normalize the new vector 
    mag = sqrt(camX * camX + camY * camY + camZ * camZ); 
    camX /= mag; 
    camY /= mag; 
    camZ /= mag; 

    // Now push it out to distance 
    camX *= distance; 
    camY *= distance; 
    camZ *= distance; 
} 
2
당신은 결과 좌표 만 입력 각도를 제한 할 필요가 없습니다

:

double yAngle = y * M_PI/180; 
double yThreshold = std::asin(-4.0/distance); 
if(yAngle > yThreshold) 
    yAngle = yThreshold; 

을 그리고 대신 yAngle를 사용 : 다음을 수행 시작 부분에,

4 <= distance * -sin(y) 
-4/distance >= sin(y) 
//Assuming y is always between -PI/2 and PI/2 
arc sin(-4/distance) >= y 

따라서 y입니다.

Btw, 마우스 좌표에서 각도로의 매핑이 약간 이상하게 보입니다. 위 공식의 가정이 성립하는지 확신 할 수 없습니다. 따라서 코드를 수정해야 할 수도 있습니다. 더 나은 방법은 각도 계산 방법을 적용하는 것입니다. 아마도 창 크기를 고려해야합니다.