在触摸位置的 SceneKit 中创建 SCNCylinder 不准确
Creating SCNCylinder in SceneKit at touch position isn't accurate
我正在尝试使用 SCNCylinder
在 SceneKit 中创建一个扁平圆柱体。我希望将圆柱体放置在场景中用户点击屏幕的位置。
我目前的方法可行,但由于某种原因,圆柱体没有准确地放置在触摸位置。根据屏幕的不同部分,圆柱体有时位于触摸位置的中间,有时会偏离很多。我希望屏幕截图能够很好地说明问题。
我目前有一个 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];
}
SceneKit 中的每个 SCNSphere
都是由多边形创建的。 SCNSphere
网格的多边形数量和粒度由 segmentCount
属性.
确定
默认情况下,segmentCount
值设置为 48,这不是很精细。对具有低 segmentCount 的 SCNSphere
执行 hitTest:
将导致检索与实际触摸点相比具有偏移量的多边形。
通过增加 segmentCount(例如增加到 96),水平和垂直方向的段数增加,偏移量将减少。
请记住,增加 segmentCount
会对性能产生影响。
我正在尝试使用 SCNCylinder
在 SceneKit 中创建一个扁平圆柱体。我希望将圆柱体放置在场景中用户点击屏幕的位置。
我目前的方法可行,但由于某种原因,圆柱体没有准确地放置在触摸位置。根据屏幕的不同部分,圆柱体有时位于触摸位置的中间,有时会偏离很多。我希望屏幕截图能够很好地说明问题。
我目前有一个 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];
}
SceneKit 中的每个 SCNSphere
都是由多边形创建的。 SCNSphere
网格的多边形数量和粒度由 segmentCount
属性.
默认情况下,segmentCount
值设置为 48,这不是很精细。对具有低 segmentCount 的 SCNSphere
执行 hitTest:
将导致检索与实际触摸点相比具有偏移量的多边形。
通过增加 segmentCount(例如增加到 96),水平和垂直方向的段数增加,偏移量将减少。
请记住,增加 segmentCount
会对性能产生影响。