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}]")

检查的引用NSValue类型编码

初始化(字节:objCType:)

宣言

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

参数 - 值 | 指向要存储在新值对象中的数据的指针。

类型 | 由 @encode() 编译器指令提供的 Objective-C 类型的值。不要将此参数硬编码为 C 字符串。

您可能需要对类型进行硬编码,因为@encode()指令在 Swift 中不可用。

于 2016-09-09T23:44:14.463 回答