如何在 Swift 2.1 中使用 slide/tap(动态)为 3D 对象着色

How to color a 3D object with slide/tap (dynamically) in Swift 2.1

我必须构建一个 Swift 应用程序,可以使用各种手势为 3D 对象着色。我有一个作为 SceneKit 对象导入的 Collada 文件。我找不到用水龙头给它上色的方法。我尝试从 WWDC 示例转换 Obj-C,但它对我不起作用。

我尝试在 3D 对象上应用 SpriteKit 作为纹理,但结果是这样:

当用户点击屏幕时,应用程序应获取 3D 对象的纹理坐标,然后在该点添加一个 SpriteKit 节点。

之前:

之后:

我不知道为什么纹理会那样爆炸。

谢谢!

SpriteKit 场景坐标系统并不像图像那样映射到纹理坐标。图像中的像素坐标 y-axis 向下增加;在 SpriteKit 场景中,y-axis 上升。

如果您只是将该 SpriteKit 场景映射到一个 SCNPlane 这是 SceneKit 场景中唯一的东西,这将更加明显 — 您会看到图像被翻转了。

左图:从包中加载的图像,右图:填充 SKScene 映射到平面(带注释)的图像

要解决此问题,您需要 two-step 坐标转换:

  1. 将原点 y-coordinate 向上平移 SKScene
  2. 的高度
  3. 将 y-coordinates 缩放 -1,以便增加的坐标向下而不是向上

您可以在 SKScene 中执行此操作,也可以在 SCNMaterialProperty 中执行此操作,即 texture-maps SpriteKit 内容到 SceneKit 对象上。我赞成 SCNMaterialProperty 方法——只需为其 contentsTransform 属性:

设置适当的矩阵
let translate = SCNMatrix4MakeTranslation(0, 1, 0)
let yFlippedTranslate = SCNMatrix4Scale(translate, 1, -1, 1)
material.diffuse.contentsTransform = yFlippedTranslate

请注意,如果您还尝试使用 material 的纹理坐标(通过 SCNHitTestResult)将 touch/click 事件映射到 SpriteKit 场景中,则需要在那里执行类似的转换:

let texcoord = result.textureCoordinatesWithMappingChannel(0)
sprite.position.x = texcoord.x * skScene.size.width
sprite.position.y = (1 - texcoord.y) * skScene.size.height