2017-08-23 7 views
1

私は、Scenekit(そしてARKit、これはこの質問にとって重要ではありませんが)アプリケーションで、GameplayKitを使って楽しんでいます。GameplayKit + SceneKit、GKAgentローテーション変換

具体的には、私はBehaviorのEntities、Components、Agentsを使用していますが、1つのことを除いて、すべてがうまくいっています。

コンポーネント内でGKAgentを使用してシーンを移動し、他のオブジェクトを避けることができました。それはすべて機能しているようだ。しかし、私は "回転"プロパティではなく、GKAgentの位置を動かすことしかできません。

import Foundation 
import SceneKit 
import GameplayKit 

class MoveComponent: GKScnComponent, GKAgentDelegate { 

    //this class is abbreviated for perfunctory sakes 

    func agentWillUpdate(_ agent: GKAgent) { 
    guard let visualComponent = entity?.component(ofType: self.visualType) as? VisualComponent else { 
     return 
    } 

    //works with just "position", but turns possessed with both rotation and position 
    agentSeeking.rotation = convertToFloat3x3(float4x4: visualComponent.parentMostNode.simdTransform) 
    agentSeeking.position = visualComponent.parentMostNode.simdPosition 
    } 

    func agentDidUpdate(_ agent: GKAgent) { 
    guard let visualComponent = entity?.component(ofType: self.visualType) as? VisualComponent else { 
     return 
    } 

    //works with just "position", but turns possessed with both rotation and position 
    visualComponent.parentMostNode.simdPosition = agentSeeking.position 
    visualComponent.parentMostNode.simdTransform = convertToFloat4x4(float3x3: agentSeeking.rotation) 
    } 

} 

私は、この質問のおかげで3×3行列と4×4行列の間にいくつかの変換コードを書かれている: Converting matrix_float3x3 rotation to SceneKit

import Foundation 
import GameplayKit 

func convertToFloat3x3(float4x4: simd_float4x4) -> simd_float3x3 { 
    let column0 = convertToFloat3 (float4: float4x4.columns.0) 
    let column1 = convertToFloat3 (float4: float4x4.columns.1) 
    let column2 = convertToFloat3 (float4: float4x4.columns.2) 

    return simd_float3x3.init(column0, column1, column2) 
} 

func convertToFloat3(float4: simd_float4) -> simd_float3 { 
    return simd_float3.init(float4.x, float4.y, float4.z) 
} 

func convertToFloat4x4(float3x3: simd_float3x3) -> simd_float4x4 { 
    let column0 = convertToFloat4 (float3: float3x3.columns.0) 
    let column1 = convertToFloat4 (float3: float3x3.columns.1) 
    let column2 = convertToFloat4 (float3: float3x3.columns.2) 
    let identity3 = simd_float4.init(x: 0, y: 0, z: 0, w: 1) 

    return simd_float4x4.init(column0, column1, column2, identity3) 
} 

func convertToFloat4(float3: simd_float3) -> simd_float4 { 
    return simd_float4.init(float3.x, float3.y, float3.z, 0) 
} 

私はこのすべてにはほとんど新たなんだ、と私はありません線形代数学者なので、私の行列変換関数が正確に何をしているのかわからないのは100%確信していません。

私はちょうどエージェントの "位置"プロパティを使用しても問題ありませんが、エージェントからノードへのローテーション/トランスフォームを追加すると、すべてが処理されます。

私が間違っていることを考えて/ポインタ/助けてください?

答えて

0

私はそれを理解しました。これを実現するためには行列の乗算が重要です。 3Dゲーム開発の経験があれば誰でも精神的な努力なしでそれを教えてくれたでしょう:)

func agentWillUpdate(_ agent: GKAgent) { 
    guard let visualComponent = entity?.component(ofType: self.visualType) as? VisualComponent else { 
     return 
    } 

    agentSeeking.position = visualComponent.parentMostNode.simdPosition 

    let rotation = visualComponent.parentMostNode.rotation 
    let rotationMatrix = SCNMatrix4MakeRotation(rotation.w, rotation.x, rotation.y, rotation.z) 
    let float4x4 = SCNMatrix4ToMat4(rotationMatrix) 

    agentSeeking.rotation = convertToFloat3x3(float4x4: float4x4) 
    } 


func agentDidUpdate(_ agent: GKAgent) { 
    guard let visualComponent = entity?.component(ofType: self.visualType) as? VisualComponent else { 
     return 
    } 

// visualComponent.parentMostNode.simdPosition = agentSeeking.position 
    let rotation3x3 = agentSeeking.rotation 
    let rotation4x4 = convertToFloat4x4(float3x3: rotation3x3) 
    let rotationMatrix = SCNMatrix4FromMat4(rotation4x4) 
    let position = agentSeeking.position 

    let translationMatrix = SCNMatrix4MakeTranslation(position.x, position.y, position.z) 
    let transformMatrix = SCNMatrix4Mult(rotationMatrix, translationMatrix) 

    visualComponent.parentMostNode.transform = transformMatrix 
    } 

私は誰かがこの点を知りたがっていますか?

関連する問題