이 코드는 모든 다시 그리기 전에 호출됩니다. 어떻게 회전/변환 (timer 또는 mouseDown)하는지 모르겠지만, 아래에 설명 된 메서드는 부드럽게 수행되고 사용자에게 자연스럽게 나타날 수 있습니다.
가까운 물체로 물체를 잘리는 경우 니어 컷오프 평면을 카메라쪽으로 뒤로 이동하십시오 (이 코드에서는 VIEWPLANEOFFSET을 증가 시키십시오). 카메라가 너무 가까워 가까이있는 비행기를 뒤로 멀리 움직일 수 없으면 카메라를 뒤로 움직여야 할 수도 있습니다.
개체를 왼쪽, 오른쪽, 위쪽 또는 아래쪽 자르기 기준면으로 잘리는 경우 카메라 조리개를 조정하십시오.
자세한 내용은 아래에서 설명합니다.
// ******************************* Distance of The Camera from the Origin
cameraRadius = sqrtf((camera.viewPos.x * camera.viewPos.x) + (camera.viewPos.y * camera.viewPos.y) + (camera.viewPos.z * camera.viewPos.z));
GLfloat phi = atanf(camera.viewPos.x/cameraRadius);
GLfloat theta = atanf(camera.viewPos.y/cameraRadius);
camera.viewUp.x = cosf(theta) * sinf(phi);
camera.viewUp.y = cosf(theta);
camera.viewUp.z = sinf(theta) * sinf(phi);
우리는 카메라 (눈) 위치 및보기 방향 만 정의하는보기 매트릭스를 볼 수 있습니다. 아직 클리핑이 없습니다. 그러나 카메라 위치는 객체에 너무 가까워지면 니어 컷오프 평면을 설정하는 방법이 제한 될 것입니다. 나는 카메라를 공정하게 되돌려 놓지 않을 이유가 없다고 생각한다.
// ********************************************** Make the View Matrix
viewMatrix = GLKMatrix4MakeLookAt(camera.viewPos.x, camera.viewPos.y, camera.viewPos.z, camera.viewPos.x + camera.viewDir.x, camera.viewPos.y + camera.viewDir.y, camera.viewPos.z + camera.viewDir.z, camera.viewUp.x, camera.viewUp.y, camera.viewUp.z);
투영 매트릭스는 클리핑 절두체가 정의 된 곳입니다. 다시 말하지만, 카메라가 너무 가깝다면 원점으로부터의 카메라 거리보다 크면 오브젝트를 클리핑하지 않도록 니어 컷오프 평면을 설정할 수 없습니다. 카메라를 상당히 멀리 되돌려 놓지 않을 이유가 전혀 없지만 근거리/원거리 클리핑면을 원하는 것보다 더 멀리 떨어 뜨리지 않는 이유가 있습니다 (깊이 선별의 정확성).
이 코드에서는 카메라 조리개를 직접 사용하지만 glFrustum과 같은 것을 사용하여 프로젝션 매트릭스를 만드는 경우 카메라 조리개에서 왼쪽 및 오른쪽 자르기 평면을 계산하는 것이 좋습니다. 이렇게하면 사용자가 좋아하는대로 확대하거나 축소 할 수 있도록 카메라 조리개를 변경하여 줌 효과를 만들 수 있습니다 (mouseDown 메서드에서). 조리개를 늘리면 효과적으로 축소됩니다. 감소 조리개 효율적으로 확대
// ********************************************** Make Projection Matrix
GLfloat aspectRatio;
GLfloat cameraNear, cameraFar;
// The Camera Near and Far Cutoff Planes
cameraNear = cameraRadius - VIEWPLANEOFFSET;
if (cameraNear < 0.00001)
cameraNear = 0.00001;
cameraFar = cameraRadius + VIEWPLANEOFFSET;
if (cameraFar < 1.0)
cameraFar = 1.0;
// Get The Current Frame
NSRect viewRect = [self frame];
camera.viewWidth = viewRect.size.width;
camera.viewHeight = viewRect.size.height;
// Calculate the Ratio of The View Width/View Height
aspectRatio = viewRect.size.width/viewRect.size.height;
float fieldOfView = GLKMathDegreesToRadians(camera.aperture);
projectionMatrix = GLKMatrix4MakePerspective(fieldOfView, aspectRatio, cameraNear, cameraFar);
편집 :. 여기
카메라의 조리개에서 왼쪽 및 오른쪽 클리핑 비행기를 계산하는 방법을 설명하는 코드이다 : 나는 것을
GLfloat ratio, apertureHalfAngle, width;
GLfloat cameraLeft, cameraRight, cameraTop, cameraBottom, cameraNear, cameraFar;
GLfloat shapeSize = 3.0;
GLfloat cameraRadius;
// Distance of The Camera from the Origin
cameraRadius = sqrtf((camera.viewPos.x * camera.viewPos.x) + (camera.viewPos.y * camera.viewPos.y) + (camera.viewPos.z * camera.viewPos.z));
// The Camera Near and Far Cutoff Planes
cameraNear = cameraRadius - (shapeSize * 0.5);
if (cameraNear < 0.00001)
cameraNear = 0.00001;
cameraFar = cameraRadius + (shapeSize * 0.5);
if (cameraFar < 1.0)
cameraFar = 1.0;
// Calculte the camera Aperture Half Angle (radians) from the Camera Aperture (degrees)
apertureHalfAngle = (camera.aperture/2) * PI/180.0; // half aperture degrees to radians
// Calculate the Width from 0 of the Left and Right Camera Cutoffs
// We Use Camera Radius Rather Than Camera Near For Our Own Reasons
width = cameraRadius * tanf(apertureHalfAngle);
NSRect viewRect = [self bounds];
camera.viewWidth = viewRect.size.width;
camera.viewHeight = viewRect.size.height;
// Calculate the Ratio of The View Width/View Height
ratio = camera.viewWidth/camera.viewHeight;
// Calculate the Camera Left, Right, Top and Bottom
if (ratio >= 1.0)
{
cameraLeft = -ratio * width;
cameraRight = ratio * width;
cameraTop = width;
cameraBottom = -width;
} else {
cameraLeft = -width;
cameraRight = width;
cameraTop = width/ratio;
cameraBottom = -width/ratio;
}
질문이 이해가 가지 않습니다. 어떤 물건을 그려서는 안되는지를 결정하기 위해 어떤 종류의자가 제작 절두체 컬링 (self-made frustum culling)을 사용합니까? 그렇다면, 왜 회전/번역을하지 않은 이유는 무엇입니까? – HolyBlackCat
투영 행렬을 만드는 방법에 대한 코드를 게시해야합니다. 치수의 가능성을 이해한다면 가까운/먼 거리 또는 카메라 조리개의 관점에서 영사 매트릭스를 정의하는 데 아무런 문제가 없어야합니다. 즉석에서 재정의하려는 투영 행렬 (뷰 행렬이 아닙니다)입니다. – jwlaughton
도움이된다면 View 및 Projection 행렬 계산 방법을 보여주는 Objective C 코드를 게시했습니다. 이 계산은 내가 resizeGL이라고 부르는 메소드에서 즉시 수행됩니다. 클리핑이 투영 행렬에서 수행되는 것을 볼 수 있습니다. – jwlaughton