我必须构建一个可以使用各种手势为 3D 对象着色的 Swift 应用程序。我有一个作为 SceneKit 对象导入的 Collada 文件。我找不到用水龙头给它上色的方法。我尝试从 WWDC 示例转换 Obj-C,但它对我不起作用。
我尝试在 3D 对象上应用 SpriteKit 作为纹理,但结果是这样:
当用户点击屏幕时,应用程序应获取 3D 对象的纹理坐标,然后在该点添加一个 SpriteKit 节点。
之前:
之后:
我不知道为什么纹理会以这种方式爆炸。
谢谢!
最佳答案
SpriteKit 场景坐标系统并不像图像那样映射到纹理坐标。图像中的像素坐标具有向下增加的 y 轴;在 SpriteKit 场景中,y 轴向上。
如果您只是将该 SpriteKit 场景映射到一个 SCNPlane
上,这是 SceneKit 场景中唯一的东西,这会更加明显 — 您会看到图像被翻转了。
左图:从包中加载的图像,右图:填充映射到平面的 SKScene
的图像(带有注释)
要解决此问题,您需要进行两步坐标转换:
- 将原点 y 坐标向上平移
SKScene
的高度
- 将 y 坐标缩放 -1,以便增加的坐标向下而不是向上
您可以在 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/