swift - 如何在 Swift 2.1 中使用滑动/点击(动态)为 3D 对象着色

标签 swift 3d sprite-kit textures scenekit

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

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

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

之前:

Before

之后:

object after run

我不知道为什么纹理会以这种方式爆炸。

谢谢!

最佳答案

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

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

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

base image image in SKScene on SCNMaterial

要解决此问题,您需要进行两步坐标转换:

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

coordinate transformation

您可以在 SKScene 中或在将 SpriteKit 内容纹理映射到 SceneKit 对象的 SCNMaterialProperty 中执行此操作。我喜欢 SCNMaterialProperty 方法——只需为其 contentsTransform 设置适当的矩阵即可属性:

let translate = SCNMatrix4MakeTranslation(0, 1, 0)
let yFlippedTranslate = SCNMatrix4Scale(translate, 1, -1, 1)
material.diffuse.contentsTransform = yFlippedTranslate

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

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

关于swift - 如何在 Swift 2.1 中使用滑动/点击(动态)为 3D 对象着色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34515243/

相关文章:

swift - 在 Swift 中对 'grouped' Firebase 数据进行排序

Swift:UISearchController 不在窗口层次结构中

swift - 使用函数 swift 自动更新 NSView

c++ - 旋转几何以对齐方向 vector

css - scaleZ() CSS 转换函数有什么作用?

swift - 如何将 Sprite 添加到 View Controller ?

ios - 具有与多个子类共享的 BaseGame 类的单个 GKScene

swift - Sprite-kit:在圆形路径中移动元素

swift - tvOS PressesBegan 调用得太晚(在焦点已经改变之后)

python - 使用具有 > 2 个参数的用户定义函数的 matplotlib 绘制 3d 曲面