在 SceneKit 节点周围添加边框

Posted

技术标签:

【中文标题】在 SceneKit 节点周围添加边框【英文标题】:adding a border around SceneKit node 【发布时间】:2016-12-02 21:18:10 【问题描述】:

我正在尝试通过点击手势突出显示 SceneKit 中的选定节点。不幸的是,我无法完成它。我能做的最好的事情是在点击节点时更改材质。

let material = key.geometry!.firstMaterial!
material.emission.contents = UIColor.blackColor()

有人可以建议我只在对象周围添加边框或轮廓而不是更改整个节点的颜色的方法吗?

【问题讨论】:

您的意思是SKSpriteNode 对吗?不是SKNode 抱歉有任何混淆,我正在使用场景套件.. scnnode 【参考方案1】:

基于@Karl Sigiscar 的答案和 SO 中的另一个答案,我想出了这个:

func createLineNode(fromPos origin: SCNVector3, toPos destination: SCNVector3, color: UIColor) -> SCNNode 
    let line = lineFrom(vector: origin, toVector: destination)
    let lineNode = SCNNode(geometry: line)
    let planeMaterial = SCNMaterial()
    planeMaterial.diffuse.contents = color
    line.materials = [planeMaterial]

    return lineNode


func lineFrom(vector vector1: SCNVector3, toVector vector2: SCNVector3) -> SCNGeometry 
    let indices: [Int32] = [0, 1]

    let source = SCNGeometrySource(vertices: [vector1, vector2])
    let element = SCNGeometryElement(indices: indices, primitiveType: .line)

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



func highlightNode(_ node: SCNNode) 
    let (min, max) = node.boundingBox
    let zCoord = node.position.z
    let topLeft = SCNVector3Make(min.x, max.y, zCoord)
    let bottomLeft = SCNVector3Make(min.x, min.y, zCoord)
    let topRight = SCNVector3Make(max.x, max.y, zCoord)
    let bottomRight = SCNVector3Make(max.x, min.y, zCoord)


    let bottomSide = createLineNode(fromPos: bottomLeft, toPos: bottomRight, color: .yellow)
    let leftSide = createLineNode(fromPos: bottomLeft, toPos: topLeft, color: .yellow)
    let rightSide = createLineNode(fromPos: bottomRight, toPos: topRight, color: .yellow)
    let topSide = createLineNode(fromPos: topLeft, toPos: topRight, color: .yellow)

    [bottomSide, leftSide, rightSide, topSide].forEach 
        $0.name = kHighlightingNode // Whatever name you want so you can unhighlight later if needed
        node.addChildNode($0)
    


func unhighlightNode(_ node: SCNNode) 
    let highlightningNodes = node.childNodes  (child, stop) -> Bool in
        child.name == kHighlightingNode
    
    highlightningNodes.forEach 
        $0.removeFromParentNode()
    

【讨论】:

线条太细了,能不能让线条看起来更粗一些? 实现了这个,但是没有行是可见的......节点被添加了,但不可见......【参考方案2】:

SCNNode 符合 SCNBoundingVolume 协议。

此协议定义了getBoundingBoxMin:max: 方法。

使用它来获取连接到节点的几何体边界框的最小和最大坐标。

然后使用 SceneKit 基元类型SCNGeometryPrimitiveTypeLine 来绘制边界框的线条。检查 SCNGeometryElement。

【讨论】:

您能否发布一些示例代码以说明如何执行此操作?即使我正在寻找相同的解决方案【参考方案3】:

如果您的节点是原始形状,您可以将UIImage 设置为diffuse。图像将被拉伸以覆盖您的节点。如果您使用带有边框的图像,这将转化为在您的节点上创建边框。

planeGeometry.firstMaterial?.diffuse.contents = UIImage(named: "blueSquareOutline.png")

【讨论】:

以上是关于在 SceneKit 节点周围添加边框的主要内容,如果未能解决你的问题,请参考以下文章

Scenekit - 将子节点(平面节点)添加到相机前面的父节点(球体节点)

在图像周围添加透明边框

使用imagick PHP在png图像周围添加边框

如何在单个图像周围添加边框,同时保持图像并排对齐?

SceneKit:向相机节点添加定向光没有效果

是否可以在堆栈视图中的按钮周围添加“较小”边框?