2017-07-05 22 views
5

Tôi có hình ảnh 32x32 .png mà tôi muốn lặp lại qua SCNPlane. Mã tôi đã có (Xem bên dưới) dẫn đến hình ảnh được kéo dài để vừa với kích thước của mặt phẳng, thay vì lặp lại.Lặp lại kết cấu trên mặt phẳng trong SceneKit

Mã sản phẩm:

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 

Trả lời

7

tôi cố định nó. Có vẻ như hình ảnh đã được phóng to. Nếu tôi làm imageMaterial.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0), hình ảnh sẽ lặp lại.

+0

tìm cách để thực hiện việc này trong GUI? – jfisk

+0

@jfisk Thật không may là không. Đoán tốt nhất của tôi là sử dụng sprites theo một cách nào đó, nhưng tôi đã không xem xét nó đủ để đưa ra một câu trả lời hay. – krntz

2

Tôi gặp phải vấn đề giống hệt nhau khi triển khai trực quan hóa máy bay trong ARKit. Tôi muốn hình dung mặt phẳng được phát hiện như một mẫu bàn cờ. Tôi đã sửa nó bằng cách tạo một tùy chỉnh SCNNode được gọi là "PlaneNode" với cấu hình chính xác SCNMaterial. Vật liệu sử dụng wrapS, wrapT = .repeat và tính toán tỉ lệ chính xác dựa trên kích thước của bản thân mặt phẳng.

Trông như thế này:

enter image description here

Hãy nhìn vào mã bên dưới, các ý kiến ​​inline chứa lời giải thích.

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 

    } 
} 
+0

được minh họa độc đáo – MoVod

Các vấn đề liên quan