在SceneKit中,摄像机没有跟踪飞机 [英] Camera is not following the airplane in Scenekit

查看:26
本文介绍了在SceneKit中,摄像机没有跟踪飞机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一架正在飞行的飞机,我正在跟踪它,我还显示了飞机所走的路线。我画圆柱体作为画路径的线。这就像是在两个点之间划了一条线。我有一个CameraNode,最初设置为(0,200,200)。在这一点上我可以看到飞机。但当我开始飞行的时候。它从屏幕上消失了。我想要两样东西:

  1. 只跟随飞机(路径无关紧要)。
  2. 显示整个路径和飞机。

我试着求最小ad max x,y和z并取平均值,但不起作用。如果你看到下面的GIF,它太大了,飞机已经从屏幕上移出了

我是这样设置相机的:

- (void)setUpCamera {
SCNScene *workingScene = [self getWorkingScene];
_cameraNode = [[SCNNode alloc] init];
_cameraNode.camera = [SCNCamera camera];
_cameraNode.camera.zFar = 500;
_cameraNode.position = SCNVector3Make(0, 60, 50);
[workingScene.rootNode addChildNode:_cameraNode];

SCNNode *frontCameraNode = [SCNNode node];
frontCameraNode.position = SCNVector3Make(0, 100, 50);
frontCameraNode.camera = [SCNCamera camera];
frontCameraNode.camera.xFov = 75;
frontCameraNode.camera.zFar = 500;
[_assetActivity addChildNode:frontCameraNode]; //_assetActivity is the aircraft node.

}

以下是我如何更改不起作用的摄像头位置:

- (void)showRealTimeFlightPath {


DAL3DPoint *point = [self.aircraftLocation convertCooridnateTo3DPoint];
DAL3DPoint *previousPoint = [self.previousAircraftLocation convertCooridnateTo3DPoint];
self.minCoordinate = [self.minCoordinate findMinPoint:self.minCoordinate currentPoint:point];
self.maxCoordinate = [self.minCoordinate findMaxPoint:self.maxCoordinate currentPoint:point];
DAL3DPoint *averagePoint = [[DAL3DPoint alloc] init];
averagePoint = [averagePoint averageBetweenCoordiantes:self.minCoordinate maxPoint:self.maxCoordinate];

SCNVector3 positions[] = {
    SCNVector3Make(point.x,point.y,point.z) ,
    SCNVector3Make(previousPoint.x,previousPoint.y,previousPoint.z)
};
SCNScene *workingScene = [self getWorkingScene];
DALLineNode *lineNodeA = [[DALLineNode alloc] init];
[lineNodeA init:workingScene.rootNode v1:positions[0] v2:positions[1] radius:0.1 radSegementCount:6 lineColor:[UIColor greenColor]] ;
[workingScene.rootNode addChildNode:lineNodeA];
self.previousAircraftLocation = [self.aircraftLocation mutableCopy];
self.cameraNode.position = SCNVector3Make(averagePoint.x, averagePoint.y, z);
self.pointOfView = self.cameraNode;

}

欢迎使用快速或目标c代码。

谢谢!!

推荐答案

您描述的第一个行为最容易通过链接注视约束和距离约束来实现,这两个约束都指向飞机。

let lookAtConstraint = SCNLookAtConstraint(target: aircraft)

let distanceConstraint = SCNDistanceConstraint(target: aircraft)
distanceConstraint.minimumDistance = 10 // set to whatever minimum distance between the camera and aircraft you'd like
distanceConstraint.maximumDistance = 10 // set to whatever maximum distance between the camera and aircraft you'd like

camera.constraints = [lookAtConstraint, distanceConstraint]

iOS 10及更早版本,您可以使用SCNTransformConstraint实现距离约束。下面是一个基本的(虽然有点难看的😛)实现,它使用线性内插来更新节点的位置。

func normalize(_ value: Float, in range: ClosedRange<Float>) -> Float {
    return (value - range.lowerBound) / (range.upperBound - range.lowerBound)
}

func interpolate(from start: Float, to end: Float, alpha: Float) -> Float {
    return (1 - alpha) * start + alpha * end
}

let target = airplane

let minimumDistance: Float = 10
let maximumDistance: Float = 15

let distanceConstraint = SCNTransformConstraint(inWorldSpace: false) { (node, transform) -> SCNMatrix4 in
    let distance = abs(sqrt(pow(target.position.x - node.position.x, 2) + pow(target.position.y - node.position.y, 2) + pow(target.position.z - node.position.z, 2)))

    let normalizedDistance: Float

    switch distance {
    case ...minimumDistance:
        normalizedDistance = self.normalize(minimumDistance, in: 0 ... distance)
    case maximumDistance...:
        normalizedDistance = self.normalize(maximumDistance, in: 0 ... distance)
    default:
        return transform
    }

    node.position.x = self.interpolate(from: target.position.x, to: node.position.x, alpha: normalizedDistance)
    node.position.y = self.interpolate(from: target.position.y, to: node.position.y, alpha: normalizedDistance)
    node.position.z = self.interpolate(from: target.position.z, to: node.position.z, alpha: normalizedDistance)

    return transform
}
第二种行为可以通过确定飞机的边界框及其在摄影机局部坐标空间中的所有路径段来实现,然后更新摄影机到该边界框中心的距离以框显视口中的所有这些节点。frameNodes(_:)是在iOS 11中引入的一种实现此功能的便捷方法,在SCNCameraController中定义。如果可能的话,我建议你使用它,除非你想自己一头扎进三角学。您可以使用场景视图的默认摄像头控制器或创建一个临时实例,视您的应用程序的需要而定。

这篇关于在SceneKit中,摄像机没有跟踪飞机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆