2016-09-07 3 views
0

Я пытаюсь создать плоский цилиндр в SceneKit, используя SCNCylinder. Я хочу, чтобы цилиндр был помещен в сцену в том месте, где пользователь забирает экран.Создание SCNCylinder в SceneKit в позиции касания неточно

Мой текущий подход работает, но по какой-то причине цилиндр не точно расположен в положении касания. В зависимости от части экрана цилиндр иногда находится в середине положения касания, а иногда и на значительную величину. Надеюсь, скриншот хорошо иллюстрирует проблему.

Offset when creating SCNCylinder at screenpos

Я в настоящее время SCNSphere, в котором находится камера. Нажимая экранную точку со сферой, я получаю луч к тесту. Затем я беру нормальный вектор луча и позиционирую Цилиндр по вектору, умноженному на 6.

Есть ли у кого-нибудь представление о том, что проблема с этим подходом и почему я испытываю это смещение?

Это, как я в настоящее время создать SCNCylinder:

- (IBAction)longPressGesture:(UILongPressGestureRecognizer *)sender { 
    if (sender.state == UIGestureRecognizerStateBegan) { 
     CGPoint location = [sender locationInView:self.sceneView]; 
     NSArray *hitTestResult = [self.sceneView hitTest:location options:nil]; 

     if (hitTestResult.count == 1) { 
      SCNHitTestResult *sphereHit = hitTestResult.firstObject; 
      // Get ray coordinates from local camera position 
      SCNVector3 localCoordinates = sphereHit.worldNormal; 
      localCoordinates = SCNVector3Make(localCoordinates.x * 6, localCoordinates.y * 6, localCoordinates.z * 6); 
      [self addCylinder:SCNVector3Make(localCoordinates.x, localCoordinates.y, localCoordinates.z)]; 
     } 
    } 
} 

- (void)addCylinder:(SCNVector3)position { 
    SCNCylinder *cylinder = [SCNCylinder cylinderWithRadius:0.5 height:0.01]; 
    SCNNode *cylinderNode = [SCNNode nodeWithGeometry:cylinder]; 

    // Create LookAt Contstraint 
    NSMutableArray *constraints = [NSMutableArray new]; 
    SCNLookAtConstraint *lookAtCameraConstraint = [SCNLookAtConstraint lookAtConstraintWithTarget:cameraNode]; 
    lookAtCameraConstraint.gimbalLockEnabled = YES; 
    [constraints addObject:lookAtCameraConstraint]; 

    // Turn 90° Constraint 
    SCNTransformConstraint *turnConstraint = [SCNTransformConstraint transformConstraintInWorldSpace:NO withBlock:^SCNMatrix4(SCNNode * _Nonnull node, SCNMatrix4 transform) { 
     transform = SCNMatrix4Mult(SCNMatrix4MakeRotation(M_PI_2, 1, 0, 0), transform); 
     return transform; 
    }]; 
    [constraints addObject:turnConstraint]; 

    cylinderNode.constraints = constraints; 

    cylinderNode.position = position; 

    SCNNode *rootNode = self.sceneView.scene.rootNode; 
    [rootNode addChildNode:cylinderNode]; 
} 

ответ

0

Каждый SCNSphere в SceneKit создается из полигонов. Количество полигонов и, следовательно, зернистость a SCNSphere сетка определяется свойством segmentCount.

Documentation of SCNSphere

По умолчанию значение segmentCount установлено значение 48, которое не очень мелкозернистой. Выполнение hitTest: на SCNSphere с низким сегментомCount приведет к получению полигонов, которые имеют смещение по сравнению с фактической точкой касания. При увеличении сегмента (например, до 96) сегменты в горизонтальном и вертикальном направлениях увеличиваются, а смещение уменьшается.

Имейте в виду, что увеличение segmentCount повлияет на производительность.

Смежные вопросы