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