2013-06-06 4 views
0

나는 화면을 번역 GLKMathUnproject()를 사용하려고 기하학 좌표있어의 형상을 반환하지만 내 일상은 항상 화면의 중앙에 어떤 형상을 반환합니다.내 GLKMathUnproject는 항상 센터 화면

내 unproject 코드는 다음과 같습니다

+ (GLKVector3) gluUnproject: (GLKVector3) screenPoint 
        inView: (UIView*) view 
      withModelMatrix: (GLKMatrix4) model 
       projection: (GLKMatrix4) projection 
{ 
    CGSize viewSize = view.bounds.size; 
    int viewport[4]; 
    viewport[0] = 0.0f; 
    viewport[1] = 0.0f; 
    viewport[2] = viewSize.width; 
    viewport[3] = viewSize.height; 

    bool success; 
    GLKVector3 result = GLKMathUnproject(screenPoint, model, projection, &viewport[0], &success); 

    return result; 
} 

그리고 내 전화는 다음과 같습니다

- (void) handleSingleTap: (UIGestureRecognizer*) sender 
{ 
    UITapGestureRecognizer *tapper = (UITapGestureRecognizer*) sender; 
    CGPoint tapPoint = [tapper locationInView: self.view]; 

    // Find tapped point on geometry 
    MyObject *bd = [worldObjects objectAtIndex: 0]; // the object on which I'm trying to sense the tap. 
    // NOTE: bd is planar, along X/Z, with Y=0. Visually, it's several little 
    // ..squares (like a big checkerboard), and I'm trying to determine 
    // ..in which square the user tapped. 
    // At this point. eyesAt is { someX, y, someZ } and lookAt is { someX, 0, someZ } and 
    // ..upVector is { 0, 0, -1 }. We Zoom our view of the board in/out by 
    // ..changing eyesAt.y 
    float tapZ = (self.eyesAt.y - self.zNear)/(self.zFar - self.zNear); // % of the Z-depth. eyesAt.y = distance to geometry. 
    GLKVector3 tapPoint3 = GLKVector3Make(tapPoint.x, tapPoint.y, tapZ); 
    GLKVector3 tapAt = [MFglkUtils gluUnproject: tapPoint3 inView: self.view withModelMatrix: bd.modelviewMatrix projection: [self projectionMatrix]]; 
    // etc., snip -- do stuff with the tapAt point. 

문제는 내 항상에 무엇이든의 기하학적 점을 반환 gluUnproject 내가 도청하는 위치에 관계없이 화면의 중간.

편집 : 은 "항상 센터 근처"문제는 반환 X/Z 값은 항상 매우-근처 제로 있다는 것입니다, 나의 형상이 원점을 중심으로.

문제가 내 tapZ 값으로 자리 잡고 것처럼 보인다. 내 이해이 "는 farZ 평면에서"및 그 사이의 값과 1 개 수단의 "nearZ 평면에서"0 수단 사이의 비율이다 0-1에서의 값이어야한다는 것이다.

// gives very-very small results 
    tapZ = (self.eyesAt.y - self.zNear)/(self.zFar - self.zNear); // % deep through the view frustum 

    // gives Z=0, and very small results 
    glReadPixels(viewPoint.x, viewPoint.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &tapZ); 

    // gives approximately-correct results 
    tapZ = 0.99943; // found through trial & error 

    // gives Z=1, and too-big results 
    glReadPixels(viewPoint.x, viewPoint.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &tapZ); 
    tapZ = 1. - tapZ; 

은 분명히, 내가 올바른 tapZ 값을 전달해야하지만 나는 그것을 도착하는 방법을 이해하지 않습니다 다양한 tapZ 값으로 실험, 나는 본 적이!

답변

0

좋아, 휴! 이 문제는 내 tapZ 값임을 밝혀 상기 문제는 깊이 버퍼의 Z 값이 선형 적이된다는 사실과 관련된다. (그 이상한 소리에 대한 자세한 내용은 here을 참조하십시오.) 어쨌든 glProject()를 사용하여 문제의 지오메트리 조각을 화면까지 투영합니다 (단, 나는 바둑판 모양의 오버 헤드 뷰를 사용하고 있습니다!). 나에게 내가 원하는 Z 가치를 준다.

- (GLKVector3) vectorFromTapPoint: (CGPoint) tapPoint 
{ 
    tapPoint.y = (self.view.bounds.size.height - tapPoint.y); 

    BlockDiagram *bd = [worldObjects objectAtIndex: 0]; 

    // find Z-depth of center of board 
    GLKVector3 v3Zero = { 0, 0, 0 }; 
    int viewport[4]; 
    glGetIntegerv(GL_VIEWPORT, viewport); 
    GLKVector3 worldZero = GLKMathProject(v3Zero, bd.modelviewMatrix, [self projectionMatrix], viewport); 

    // Find tapped point on geometry 
    float tapZ = worldZero.z; 
    GLKVector3 tapPoint3 = GLKVector3Make(tapPoint.x, tapPoint.y, tapZ); 
    GLKVector3 tapAt = [MFglkUtils gluUnproject: tapPoint3 inView: self.view withModelMatrix: bd.modelviewMatrix projection: [self projectionMatrix]]; 

    return tapAt; 
} 

및 gluUnProject가 수정되었습니다 :

+ (GLKVector3) gluUnproject: (GLKVector3) screenPoint 
        inView: (UIView*) view 
      withModelMatrix: (GLKMatrix4) model 
       projection: (GLKMatrix4) projection 
{ 
    int viewport[4]; 
    glGetIntegerv(GL_VIEWPORT, viewport); 

    bool success; 
    GLKVector3 result = GLKMathUnproject(screenPoint, model, projection, &viewport[0], &success); 

    return result; 
} 

참고 : 올바르게 지향 뷰포트 준에 대한이 glGet *()을 요구 (내 응용 프로그램은 최종 결과 코드는 다음과 같이 밝혀졌다 풍경) 가치도 중요합니다!