我有一架正在飞行的飞机,并且还在向我展示飞机所遵循的路径。我正在将圆柱体绘制为绘制路径的线。在2点之间画一条线。我有一个初始设置为(0,200,200)的cameraNode。那时我可以看到飞机了。但是当我开始飞行时。它不显示在屏幕上。我想要两件事:
我尝试找到最小广告最大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
}
第二种行为可以通过确定飞机的边界框及其在相机的局部坐标空间中的所有路径段,然后更新相机到该边界框中心的距离以对视口(viewport)中的所有这些节点进行构图来实现。
frameNodes(_:)
是实现此功能的便捷方法,已在iOS 11中引入,并在SCNCameraController
上定义。如果可能的话,我建议您使用它,除非您想自己研究三角函数。您可以使用场景 View 的默认相机 Controller 或创建一个临时实例,以适合您的应用程序的需要。关于ios - 相机未跟随Scenekit中的飞机,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45447924/