我想要在SCNPlane上重复一个32x32 .png图像。我得到的代码(见下文)导致图像被拉伸以适应平面的大小,而不是重复。
CODE:
let planeGeo = SCNPlane(width: 15, height: 15)
let imageMaterial = SCNMaterial()
imageMaterial.diffuse.contents = UIImage(named: "art.scnassets/grid.png")
planeGeo.firstMaterial = imageMaterial
let plane = SCNNode(geometry: planeGeo)
plane.geometry?.firstMaterial?.diffuse.wrapS = SCNWrapMode.repeat
plane.geometry?.firstMaterial?.diffuse.wrapT = SCNWrapMode.repeat
答案 0 :(得分:9)
我修好了。似乎图像被放大了。如果我imageMaterial.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
,图像会重复。
答案 1 :(得分:6)
在ARKit中实现平面可视化时遇到了同样的问题。我想将检测到的平面可视化为棋盘图案。我通过使用正确配置的SCNNode创建名为“PlaneNode”的自定义SCNMaterial来修复它。材质使用wrapS,wrapT = .repeat并根据平面本身的大小正确计算尺度。
看起来像这样:
看看下面的代码,内联注释包含解释。
class PlaneNode : SCNNode {
init(planeAnchor: ARPlaneAnchor) {
super.init()
// Create the 3D plane geometry with the dimensions reported
// by ARKit in the ARPlaneAnchor instance
let planeGeometry = SCNPlane(width:CGFloat(planeAnchor.extent.x), height:CGFloat(planeAnchor.extent.z))
// Instead of just visualizing the grid as a gray plane, we will render
// it in some Tron style colours.
let material = SCNMaterial()
material.diffuse.contents = PaintCode.imageOfViewARPlane
//the scale gives the number of times the image is repeated
//ARKit givest the width and height in meters, in this case we want to repeat
//the pattern each 2cm = 0.02m so we divide the width/height to find the number of patterns
//we then round this so that we always have a clean repeat and not a truncated one
let scaleX = (Float(planeGeometry.width) / 0.02).rounded()
let scaleY = (Float(planeGeometry.height) / 0.02).rounded()
//we then apply the scaling
material.diffuse.contentsTransform = SCNMatrix4MakeScale(scaleX, scaleY, 0)
//set repeat mode in both direction otherwise the patern is stretched!
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
//apply material
planeGeometry.materials = [material];
//make a node for it
self.geometry = planeGeometry
// Move the plane to the position reported by ARKit
position.x = planeAnchor.center.x
position.y = 0
position.z = planeAnchor.center.z
// Planes in SceneKit are vertical by default so we need to rotate
// 90 degrees to match planes in ARKit
transform = SCNMatrix4MakeRotation(-Float.pi / 2.0, 1.0, 0.0, 0.0);
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(planeAnchor: ARPlaneAnchor) {
guard let planeGeometry = geometry as? SCNPlane else {
fatalError("update(planeAnchor: ARPlaneAnchor) called on node that has no SCNPlane geometry")
}
//update the size
planeGeometry.width = CGFloat(planeAnchor.extent.x)
planeGeometry.height = CGFloat(planeAnchor.extent.z)
//and material properties
let scaleX = (Float(planeGeometry.width) / 0.02).rounded()
let scaleY = (Float(planeGeometry.height) / 0.02).rounded()
planeGeometry.firstMaterial?.diffuse.contentsTransform = SCNMatrix4MakeScale(scaleX, scaleY, 0)
// Move the plane to the position reported by ARKit
position.x = planeAnchor.center.x
position.y = 0
position.z = planeAnchor.center.z
}
}
答案 2 :(得分:0)
您可以从“场景工具箱”查看器中学习它,假设您的场景工具箱中有SCNplane
创建场景文件拖动平面
尺寸为12英寸(米)为0.3048
然后选择漫反射中的图像
现在您有一个带有4个网格的图像,如图像
我们希望每个盒子都以英寸为单位显示,因此对于12英寸,我们需要12个盒子* 12个盒子,因为我们有12英寸盒子
进行计算。首先,我们需要将0.3048米转换为英寸
这是米/ 0.0254 的答案是12。
但是我们需要在每个英寸上显示每个网格,因此我们还需要除以12/4 = 3
现在转到显示材料检查器并将比例值更改为3
您可以看到12英寸平面的12个盒子。
希望对您有帮助
答案 3 :(得分:0)