Um @rickster 's Antwort zu erweitern, hier ist eine gute Möglichkeit, die obere linke 3x3 einer 4x4 Matrix in Swift zu nehmen, die Vorteile der erweiterten SIMD Unterstützung in der iOS 11/tvOS 11/High Sierra Version von SceneKit:
extension float4 {
var xyz: float3 {
return float3(x, y, z)
}
init(_ vec3: float3, _ w: Float) {
self = float4(vec3.x, vec3.y, vec3.z, w)
}
}
extension float4x4 {
var upperLeft3x3: float3x3 {
let (a,b,c,_) = columns
return float3x3(a.xyz, b.xyz, c.xyz)
}
init(rotation: float3x3, position: float3) {
let (a,b,c) = rotation.columns
self = float4x4(float4(a, 0),
float4(b, 0),
float4(c, 0),
float4(position, 1))
}
}
Dann Ihr Agent aktualisieren Sie Ihre Knotens Ausrichtung übereinstimmen, dann würden Sie schreiben:
agent.rotation = node.simdTransform.upperLeft3x3
Oder, wenn der betreffende Knoten nicht an der „Wurzel“ Ebene (wie in, ein direktes Kind des rootNode), möchten Sie möglicherweise die WorldTransform des Knotens verwenden:
agent.rotation = node.simdWorldTransform.upperLeft3x3
EDIT: Wenn der betreffende Knoten eine dynamische Physik Körper angebracht hat, oder mit einem SCNTransaction Block animiert wird, wird der Präsentationsknoten des Knotens wird genauer seine aktuelle Position auf dem Bildschirm reflektieren:
agent.position = node.presentation.simdWorldPosition
agent.rotation = node.presentation.simdWorldTransform.upperLeft3x3
BEARBEITEN: Code oben hinzugefügt, um in die andere Richtung zu gehen und den Knoten so zu verschieben, dass er dem Agenten entspricht.
node.simdTransform = float4x4(rotation: agent3d.rotation, position: agent3d.position)
Beachten Sie, dass, wenn Sie einen Physik Körper an den Knoten angeschlossen ist, es kinematic
eher sein sollte als dynamic
, wenn Sie direkt auf diese Weise modifiziert werden, gehst zu verwandeln die Knotens.
Danke für das Posten, sehr hilfreich! Dieser Code ist so viel sauberer als das, was mir eingefallen ist. – Phi
Einverstanden, das ist wirklich hilfreich. – possen