4 点之间的 Scenekit 形状 [英] Scenekit shape between 4 points

查看:20
本文介绍了4 点之间的 Scenekit 形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于我在上一个问题中采用的路线:

Given that the route I was taking in a previous question:

ARKit- 在 Swift 3 中的平面上的 2 个矢量点之间放置一个 SCNPlane

...似乎有缺陷,我正在寻找其他选择.我可以在 2 个节点之间画一条线,然后我可以在这些节点之上创建节点,有效地在一个正方形中,但即使我在它们之间画线,我也不能把它变成一个形状.是否可以在 Scenekit 中绘制一个形状(正方形),其中 4 个角中的每一个都连接到一个节点.

...seems to be flawed, I'm looking at other options. I can draw a line between 2 nodes, I can then create nodes above those, effectively in a square but even if I draw lines between them all, I can't make that into a shape. Is it possible in Scenekit to draw a shape (square) where each of the 4 corners joins to a node.

我可以创建一个平面,将其放置在一个节点上,变换枢轴然后旋转,但它并不总是有效,但 SCNGeometry 线可以.

I can create a plane, position it on a node, transform the pivot and then rotate but it doesn't always work but SCNGeometry lines do.

谢谢

推荐答案

所以答案,至少我的解决方案是使用 SCNGeometry 三角形.我想要一个正方形(而不是立方体)作为增强现实中的墙,所以我简单地使用映射墙的 4 个角的 4 个节点构建了 2 个三角形.

So the answer, at least my solution is to use SCNGeometry triangles. I wanted a square (rather than a cube) to act as a wall in Augmented Reality so I simply built 2 triangles using the 4 nodes that mapped the 4 corners of a wall.

构建三角形的类:

extension SCNGeometry {

    class func triangleFrom(vector1: SCNVector3, vector2: SCNVector3, vector3: SCNVector3) -> SCNGeometry {

        let indices: [Int32] = [0, 1, 2]

        let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])

        let element = SCNGeometryElement(indices: indices, primitiveType: .triangles)

        return SCNGeometry(sources: [source], elements: [element])
    }
}

两个三角形的点是 [p1, p2, p4] 和 [p1, p3, p4] 使用以下方法调用:

The points for the 2 triangles are [p1, p2, p4] and [p1, p3, p4] called using the following:

let thirdPoint = firstPoint.clone()
thirdPoint.position = SCNVector3Make(thirdPoint.position.x, 
thirdPoint.position.y + Float(1.5), thirdPoint.position.z)
sceneView.scene.rootNode.addChildNode(thirdPoint)

let fourthPoint = secondPoint.clone()
fourthPoint.position = SCNVector3Make(fourthPoint.position.x, 
fourthPoint.position.y + Float(1.5), fourthPoint.position.z)
sceneView.scene.rootNode.addChildNode(fourthPoint)

let triangle = SCNGeometry.triangleFrom(vector1: firstPoint.position, vector2: secondPoint.position, vector3: fourthPoint.position)
let triangleNode = SCNNode(geometry: triangle)
triangleNode.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
triangleNode.geometry?.firstMaterial?.isDoubleSided = true
sceneView.scene.rootNode.addChildNode(triangleNode)

let triangle2 = SCNGeometry.triangleFrom(vector1: firstPoint.position, vector2: thirdPoint.position, vector3: fourthPoint.position)
let triangle2Node = SCNNode(geometry: triangle2)
triangle2Node.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
triangle2Node.geometry?.firstMaterial?.isDoubleSided = true
sceneView.scene.rootNode.addChildNode(triangle2Node)

这都是基于通过在 ARKit 中选择墙的底部 2 个点来创建 2 个初始节点.

This is all based on creating 2 initial nodes by selecting the bottom 2 points of a wall in ARKit.

希望这对寻找类似答案的其他人有意义.

Hope that makes sense to anybody else searching for a similar answer.

添加材质

这是一个稍微不同的扩展和向其添加材质的代码,墙的最终结果保持不变:

Here's a slightly different extension and the code to add a material to it, the end result of a wall remains the same:

extension SCNGeometry {

    class func Quad() -> SCNGeometry {

        let verticesPosition = [
            SCNVector3(x: -0.242548823, y: -0.188490361, z: -0.0887458622),
            SCNVector3(x: -0.129298389, y: -0.188490361, z: -0.0820985138),
            SCNVector3(x: -0.129298389, y: 0.2, z: -0.0820985138),
            SCNVector3(x: -0.242548823, y: 0.2, z: -0.0887458622)
        ]

        let textureCord = [
            CGPoint(x: 1, y: 1),
            CGPoint(x: 0, y: 1),
            CGPoint(x: 0, y: 0),
            CGPoint(x: 1, y: 0),
        ]

        let indices: [CInt] = [
            0, 2, 3,
            0, 1, 2
        ]

        let vertexSource = SCNGeometrySource(vertices: verticesPosition)
        let srcTex = SCNGeometrySource(textureCoordinates: textureCord)
        let date = NSData(bytes: indices, length: MemoryLayout<CInt>.size * indices.count)

        let scngeometry = SCNGeometryElement(data: date as Data, 
primitiveType: SCNGeometryPrimitiveType.triangles, primitiveCount: 2, 
bytesPerIndex: MemoryLayout<CInt>.size)

        let geometry = SCNGeometry(sources: [vertexSource,srcTex], 
elements: [scngeometry])

        return geometry


    }

}

然后只需在 viewDidLoad() 中调用它并应用材质

Then simply call it in viewDidLoad() and apply a material

let scene = SCNScene()

let quad = SCNGeometry.Quad()

let (min, max) = quad.boundingBox

let width = CGFloat(max.x - min.x)
let height = CGFloat(max.y - min.y)

quad.firstMaterial?.diffuse.contents = UIImage(named: "wallpaper.jpg")
quad.firstMaterial?.diffuse.contentsTransform = SCNMatrix4MakeScale(Float(width), Float(height), 1)
quad.firstMaterial?.diffuse.wrapS = SCNWrapMode.repeat
quad.firstMaterial?.diffuse.wrapT = SCNWrapMode.repeat

let node = SCNNode()
node.geometry = quad
scene.rootNode.addChildNode(node)

sceneView.scene = scene

这篇关于4 点之间的 Scenekit 形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆