0

ベクトルの配列を NSValue に変換するにはどうすればよいですか? たとえば、単一の SCNVector4 の便利な開始がありますが、それを配列に使用するにはどうすればよいですか?

お気に入り:

let v1 = SCNVector4(x: 0.0, y: 0.0, z: 0.0, w: 0.0)
let v2 = SCNVector4(x: 1.0, y: 0.0, z: 0.0, w: 0.0)

let value = NSValue(scnVector4: v1) // that works
let arrayValue = NSValue(scnVectors4: [v1, v2]) // that obviously doesnt work :( What will work?

=== 文脈 ===

シェーダー修飾子 (SceneKit 内) を使用して、シェーダーにポイントを渡したい。シェーダーのコードは次のとおりです。

uniform vec4 u_points[7];

ポイントをシェーダーに渡そうとしています:

material.setValue(points, forKey: "u_points") // points is a [SCNVector4] with length 7

これはうまくいきません。単一のベクトル ( uniform vec4 u_point;) がある場合、次のことができます。

material.setValue(NSValue(vec4: points[0]), forKey: "u_point")

そしてそれはうまくいきます。同様に、シェーダーが長さ 1 の配列 (つまりuniform vec4 u_points[1];) を使用している場合、前のバインディングも機能します。したがって、配列の代わりに長さ 4x7=28 のベクトルを渡すことができれば、うまくいくはずです。

==== 試行 ====

1/ NSNumber の NSArray

コメントで述べたようにsetValue、入力には何でも取ることができるので、NSNumber の NSArray で試しました。

let points = [v1, v2]
let a = points.map({ return [$0.x, $0.y, $0.z] })
.flatMap({ return $0 })
  .map({ return NSNumber(value: $0) }) // a is [NSNumber] of length 2x4 = 8

material.setValue(NSArray(array: a), forKey: "u_points")

しかし、それはうまくいきません

2/ SCNVector3 の NSArray: 機能しませんでした

3/ SCNVector3 の NSValue の NSArray: 機能しませんでした

4/ NSNumber の NSArray の NSArray: 機能しませんでした

Apple が何らかの優れたドキュメントを持っていれば素晴らしいことです...

4

1 に答える 1

0

これで問題が解決するかどうかはわかりませんがNSValue、固定サイズの配列を含めることができます。

let v1 = SCNVector4(x: 0.0, y: 0.0, z: 0.0, w: 0.0)
let v2 = SCNVector4(x: 1.0, y: 0.0, z: 0.0, w: 0.0)

let value = NSValue(scnVector4: v1) // that works
let arrayValue = NSValue(bytes: [v1, v2], objCType: "[2{SCNVector4=ffff}]")

classのリファレンスNSValueType Encodingsを確認してください。

init(バイト:objCType:)

宣言

init(bytes value: UnsafeRawPointer,  
     objCType type: UnsafePointer<Int8>)

パラメータ - 値 | 新しい値オブジェクトに格納されるデータへのポインター。

タイプ | @encode() コンパイラ ディレクティブによって提供される、Objective-C 型の値。このパラメーターを C 文字列としてハードコーディングしないでください。

@encode()Swift ではディレクティブを使用できないため、型をハードコーディングする必要がある場合があります。

于 2016-09-09T23:44:14.463 に答える