ios - SceneKit - 不同平面的纹理映射
问题描述
我想在场景包中平铺一个自定义平面。平面是可以具有任何形状的多边形。这是contentTransform
和 uv 源纹理坐标:
let textureCoordinates = [ CGPoint(x: 0, y: 0),
CGPoint(x: 1, y: 0),
CGPoint(x: 0, y: 1),
CGPoint(x: 1, y: 1)
//...
polygonDiffuse.contentsTransform = .init(m11: 2.5, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 2.5, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0, m42: 0, m43: 0, m44: 1)
我应该如何更改纹理映射以防止所有多边形平面的图块被拉伸?
解决方案
既然你说“任何”形状,这里有几个例子。您必须将它们旋转到位。你可能需要调整你的纹理,但是是的——它会拉伸。如果图像只是“必须是正方形的,您可以对动态多边形的大小进行一些数学运算,并将一个四边形面板居中在贝塞尔轮廓内,也许使用相同的背景来覆盖重叠。
func getPentPanelSelectorNode(vPanelType: panelTypes, vUp: Int) -> SCNNode
{
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: -6.9, y: -10.15))
bezierPath.addLine(to: CGPoint(x: 6.9, y: -10.15))
bezierPath.addLine(to: CGPoint(x: 15.2, y: 3.22))
bezierPath.addLine(to: CGPoint(x: 0.2, y: 13.40))
bezierPath.addLine(to: CGPoint(x: -15.2, y: 3.22))
bezierPath.close()
let plane = SCNShape(path: bezierPath, extrusionDepth: 0.1)
let topMaterial = SCNMaterial()
topMaterial.diffuse.contents = UIColor.green
topMaterial.locksAmbientWithDiffuse = true
plane.materials = [topMaterial]
let vNode = SCNNode(geometry: plane)
}
func getTriPanelNode(vPanelType: panelTypes, vUp: Int) -> SCNNode
{
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: -2.0, y: -1.5))
bezierPath.addLine(to: CGPoint(x: 2.0, y: -1.5))
bezierPath.addLine(to: CGPoint(x: 0.0, y: 1.5))
bezierPath.addLine(to: CGPoint(x: -2.0, y: -1.5))
bezierPath.close()
let plane = SCNShape(path: bezierPath, extrusionDepth: 0.0001)
plane.materials = []
plane.materials = setTriPanelTextures(vPanelType: vPanelType, vUp: vUp)
plane.firstMaterial?.isDoubleSided = false
let vNode = SCNNode(geometry: plane)
}
编辑 - 我只是试图向您发送几个不同的贝塞尔路径示例。这些只是三角形和五边形面板。
func setTriPanelTextures(vPanelType: panelTypes, vUp: Int) -> [SCNMaterial]
{
let topMaterial = SCNMaterial()
switch vPanelType
{
case .normal: topMaterial.diffuse.contents = "art.scnassets/Images/Panels/TileNormal.png"; break
case .entry: topMaterial.diffuse.contents = "art.scnassets/Images/Panels/TileEntryTri.png"; break
case .exit: topMaterial.diffuse.contents = "art.scnassets/Images/Panels/TileExitTri.png"; break
case .path: topMaterial.diffuse.contents = "art.scnassets/Images/Panels/TilePathTri.png"; break
case .occupied: topMaterial.diffuse.contents = "art.scnassets/Images/Panels/TileNormal.png"; break
}
topMaterial.locksAmbientWithDiffuse = true
return [topMaterial]
}
推荐阅读
- java - Java 中 OSI PI 中的 Kerberos 身份验证
- azure - Azure SignalR 服务错误 - 消息速率达到限制
- typescript - 如果隐藏了 TypeScript 中的全局对象,如何访问它?
- android - 清单合并失败。添加并链接 react-native-splash-screen 后
- hive - 允许在配置单元表的字段中使用空值
- corda - 在 3.1 版中使用节点的问题在不同的机器上
- asp.net - VS 切换到设计器视图时 Windows 窗体崩溃
- python - 如何在python的选项中保留换行符?
- javascript - 如何手动触发特定字段的验证?
- ionic-framework - 一旦用户通过扫描机扫描条形码而不使用点击操作,我想调用一个 ionic 3 事件/方法