2017-08-01 33 views
5

我有一架飛行中的飛機,我正在跟蹤,並且還顯示了飛機的跟蹤路線。我正在繪製圓柱體作爲繪製路徑的線條。它在2點之間繪製一條線。我有一個最初設置爲(0,200,200)的cameraNode。那時我可以看到飛機。但是當我開始我的飛行。它走出屏幕。我想要2件東西:相機沒有在Scenekit中跟隨飛機

  1. 只跟隨飛機(路徑無所謂)。
  2. 顯示整個路徑和飛機。

我試圖找到最小廣告最大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代碼。

謝謝!

+0

如果我理解正確,你問如何實現兩個不同的相機行爲?另外,你能澄清你的意思嗎?「跟隨飛機」?相機是否應該與飛機保持最小距離,或者只是更新以觀察其方向? –

+0

@ErikFoss是的,我想要2種行爲:1.跟着飛機(相機將只關注飛機而不是路徑)。 2.顯示整個路徑和飛機在一個屏幕上。相機必須與飛機保持一定的距離。 – Dhara

回答

2

您描述的第一個行爲最容易通過鏈接瞄準飛機的查看約束和距離約束來實現。

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上定義。如果可能,我建議使用它,除非你想自己潛入三角。您可以使用您的場景視圖的默認相機控制器或創建一個臨時實例,以適合您的應用程序的需求。

+0

邊界框意味着找到最大值和最小值x,y,z並找出平均值?另外,你可以給出一個示例代碼如何使用frameNodes。 – Dhara

+0

嗯,我不知道你是如何存儲你想要構建的節點,所以我不能爲你寫這個部分。你需要做的第一件事是把它們放在一個數組中。然後檢索或創建一個相機控制器;如果不使用場景視圖的默認攝像機控制器,只需創建一個新實例('let cameraController = SCNCameraController()')並指定當前視角('cameraController.pointOfView = sceneView.pointOfView')。然後調用'frameNodes(_ :)',傳遞數組('cameraController.frameNodes(nodes)')。這應該是你需要做的一切! –

+0

「邊界框」是指包圍所有節點的矩形體積。該邊界框的中心是朝向或遠離的點,以達到構築節點的目標距離。 –