如何在 Scenekit 的 3D 模型上添加文字(评论)?

Posted

技术标签:

【中文标题】如何在 Scenekit 的 3D 模型上添加文字(评论)?【英文标题】:How to add words(comment) on 3D model in Scenekit ? 【发布时间】:2019-07-05 20:54:39 【问题描述】:

我使用 Scenekit 在我的应用中展示了一个 3D 模型。模型可以通过手势旋转、缩放、移动。现在我需要在屏幕上添加一些 cmets 来解释模型的每个部分是什么(例如心脏模块,包括心肌,血管......)。 cmets应始终跟随模型的一部分,当模型变换时,字的大小不会改变,始终面向用户。但我不知道如何实现。

我的想法是3D世界坐标到屏幕坐标,并在SCNView上添加UILabels,当模型变换时,改变UILabels框架。但我不知道如何进行坐标转换。 当然,这可能是更好的方法,我不知道。 谢谢。

【问题讨论】:

【参考方案1】:

这个 sn-p 取自 ARKit 项目,但关于将文本标签附加到 SCNNode 并始终面向用户,这就是您所需要的 -

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? 
        guard let featureAnchor = anchor as? FeatureAnchor else 
            return nil
        
        let feature = featureAnchor.feature

        let billboardConstraint = SCNBillboardConstraint()
        billboardConstraint.freeAxes = SCNBillboardAxis.Y

        let sphere = SCNSphere(radius: Global.dotRadius)
        sphere.firstMaterial?.transparency = Global.annotationTransparency
        sphere.firstMaterial?.diffuse.contents = UIColor.yellow
        sphere.firstMaterial?.specular.contents = UIColor.white
        let node = SCNNode(geometry: sphere)
        node.constraints = [billboardConstraint]

        let text = SCNText(string: feature.description, extrusionDepth: Global.textDepth)
        text.chamferRadius = Global.textDepth
        text.firstMaterial?.transparency = Global.annotationTransparency
        text.firstMaterial?.diffuse.contents = UIColor.green
        text.firstMaterial?.specular.contents = UIColor.white
        text.firstMaterial?.isDoubleSided = true
        text.font = Global.textFont
        text.alignmentMode = kCAAlignmentCenter

        let (min, max) = text.boundingBox
        let dx: Float = (max.x - min.x) / 2.0 // x = center
        let dy: Float = min.y // y = bottom
        let dz: Float = Float(Global.textDepth) / 2.0 // z = center

        let textNode = SCNNode(geometry: text)
        textNode.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)
        textNode.scale = SCNVector3Make(Global.textScale, Global.textScale, Global.textScale)

        node.addChildNode(textNode)

        return node
    

【讨论】:

谢谢,我这样做了,它奏效了。但是 textNodes 在远处看起来很小,相反却很大。如何让它们看起来一样大? 这个我没试过,不过可能你可以根据距离通过SCNTransformConstraint调整比例。

以上是关于如何在 Scenekit 的 3D 模型上添加文字(评论)?的主要内容,如果未能解决你的问题,请参考以下文章

3D 模型无法在 Scenekit 中正确加载

iOS - Scenekit3D引擎初探之 - 导入模型+上传服务器+下载并简单设置

3d 模型 SceneKit/ARKit 的哪种格式文件更好用

SceneKit:简单的3D游戏场景搭建

Scenekit:如何获取节点的所有材质?

在 Blender 中创建的 3D 模型上使用材质