• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - ARKit - 如何在另一个 SCNNode 中包含 SCNText(对话泡泡)

[复制链接]
菜鸟教程小白 发表于 2022-12-12 14:40:06 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在尝试在 ARKit 的对话泡泡中创建一个带有简单文本的报价生成器。

我可以用文本显示对话泡泡,但文本总是从中间开始溢出到对话泡泡之外。

任何让它在对话泡泡左上角对齐并在对话泡泡内环绕的帮助将不胜感激。

结果

enter image description here

class SpeechBubbleNode: SCNNode {
    private let textNode = TextNode()

    var string: String? {
        didSet {
            textNode.string = string
        }
    }

    override init() {
        super.init()

        // Speech Bubble
        let plane = SCNPlane(width: 200.0, height: 100.0)
        plane.cornerRadius = 4.0
        plane.firstMaterial?.isDoubleSided = true
        geometry = plane

        // Text Node
        textNode.position = SCNVector3(position.x, position.y, position.z + 1.0)
//        textNode.position = convertPosition(SCNVector3(0.0, 0.0, 1.0), to: textNode)
//        textNode.position = SCNVector3(0.0, 0.0, position.z + 1.0)
        addChildNode(textNode)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

class TextNode: SCNNode {
    private let textGeometry = SCNText()

    var string: String? {
        didSet {
            updateTextContainerFrame()
            textGeometry.string = string
        }
    }

    override init() {
        super.init()

        textGeometry.truncationMode = CATextLayerTruncationMode.middle.rawValue
        textGeometry.isWrapped = true
        textGeometry.alignmentMode = CATextLayerAlignmentMode.left.rawValue

        let blackMaterial = SCNMaterial()
        blackMaterial.diffuse.contents = UIColor.black
        blackMaterial.locksAmbientWithDiffuse = true
        textGeometry.materials = [blackMaterial]

        geometry = textGeometry
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    private func updateTextContainerFrame() {
        let (min, max) = boundingBox
        let width = CGFloat(max.x - min.x)
        let height = CGFloat(max.y - min.y)
        print("width :",max.x - min.x,"height :",max.y - min.y,"depth :",max.z - min.z)
        textGeometry.containerFrame = CGRect(x: 0.0, y: 0.0, width: width, height: height)
//        textGeometry.containerFrame = CGRect(origin: .zero, size: CGSize(width: 1.0, height: 1.0))
    }
}

实现

private func makeSpeechBubbleNode(forBobbleheadNode bobbleheadNode: BobbleheadNode) {
    let node = SpeechBubbleNode()
    node.position = sceneView.scene.rootNode.convertPosition(bobbleheadNode.position, to: node)
    node.scale = SCNVector3(0.002, 0.002, 0.002)

    sceneView.scene.rootNode.addChildNode(speechBubbleNode)
    self.speechBubbleNode = speechBubbleNode

    speechBubbleNode.string = "Some random string that could be long and should wrap within speech bubble"
}



Best Answer-推荐答案


我遇到了同样的问题,最后我解决了如下问题:

  • 创建一个 SCNText 并将其作为几何图形添加到 SCNNode:

    let string = "Coverin text with a plane "
    let text = SCNText(string: string, extrusionDepth: 0.1)
    text.font = UIFont.systemFont(ofSize: 1)
    text.flatness = 0.005
    let textNode = SCNNode(geometry: text)
    let fontScale: Float = 0.01
    textNode.scale = SCNVector3(fontScale, fontScale, fontScale)
    
  • Coordinate the text pivot form left bottom to center :

    let (min, max) = (text.boundingBox.min, text.boundingBox.max)
    let dx = min.x + 0.5 * (max.x - min.x)
    let dy = min.y + 0.5 * (max.y - min.y)
    let dz = min.z + 0.5 * (max.z - min.z)
    textNode.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)
    
  • 创建一个 PlaneNode 并将文本节点添加为 PlaneNode 的子节点:

    let width = (max.x - min.x) * fontScale
    let height = (max.y - min.y) * fontScale
    let plane = SCNPlane(width: CGFloat(width), height: CGFloat(height))
    let planeNode = SCNNode(geometry: plane)
    planeNode.geometry?.firstMaterial?.diffuse.contents = UIColor.green.withAlphaComponent(0.5)
    planeNode.geometry?.firstMaterial?.isDoubleSided = true
    planeNode.position = textNode.position
    textNode.eulerAngles = planeNode.eulerAngles
    planeNode.addChildNode(textNode)
    
  • 最后将 PlaneNode 添加到 sceneView:

    sceneView.scene.rootNode.addChildNode(planeNode)
    

这就是结果:

enter image description here

关于ios - ARKit - 如何在另一个 SCNNode 中包含 SCNText(对话泡泡),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50731775/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap