SceneKit - 在3D对象上绘图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SceneKit - 在3D对象上绘图相关的知识,希望对你有一定的参考价值。

我创建了在3d对象上绘制的示例应用程序,输出图形不平滑(如图所示)。我花了将近一天的时间来弄清楚仍然无法解决的问题。可能是什么问题? enter image description here

我正在创建如下的自定义绘图几何

//I am creating self.drawingNode touches begin and adding to the rootnode
//points are nothing but 2d points from touches

func createGeometryForPoints(points:[CGPoint]) -> SCNGeometry {

    var all_3d_points:[SCNVector3] = []

    for point in points {

        let result = self.get3dPoint(point)

        if result.1 == true {
            all_3d_points.append(result.0)
        } else {
            print("INVALID POINT")
        }
    }

    var indices: [Int32] = []
    var index:Int32 = 0

    var previousIndex:Int32 = -1

    for _ in all_3d_points {

        if(previousIndex != -1) {

            indices.append(previousIndex)
        }
        indices.append(index)
        index = index + 1
        previousIndex = index
    }

    if indices.count > 0 {
        indices.removeLast();
    }

    let indexData = NSData(bytes: indices, length: sizeof(Int32) * indices.count)

    let source = SCNGeometrySource.init(vertices: all_3d_points, count: all_3d_points.count)
    let element = SCNGeometryElement.init(data: indexData, primitiveType: .Line, primitiveCount: indices.count/2, bytesPerIndex: sizeof(Int32))

    let line = SCNGeometry(sources: [source], elements: [element])
    line.materials.first?.diffuse.contents = UIColor.redColor()
    line.materials.first?.doubleSided = true

    return line
}

func get3dPoint(point:CGPoint) -> (SCNVector3,Bool) {

    var canAdd = false
    let scnView = self.view as! SCNView
    var unprojectedStartPoint = SCNVector3.init(x:Float(point.x), y:Float(point.y), z:0)

    let hitResults = scnView.hitTest(point, options: nil)
    if hitResults.count > 0 {

        let result: AnyObject! = hitResults[0]
        if hitResults.count > 1 {
            print("SOME PROBLEM")
        }
        unprojectedStartPoint = result.localCoordinates
        unprojectedStartPoint = result.node.convertPosition(unprojectedStartPoint, toNode: self.drawingNode!)

        canAdd = true
    }

    return (unprojectedStartPoint,canAdd)
}

编辑

我正在考虑找到偏移以及相机方向或正常,因为我是scenekit的新手,我没有得到如何将这个偏移添加到绘图节点,在这个方向寻找帮助

func createMarkup() -> Void {   
    let drawingNode = SCNNode()
    drawingNode.renderingOrder = 1000
    self.parentNode!.addChildNode(drawingNode)
    let geometry = self.createGeometryForPoints(allPoints,node: drawingNode)
    drawingNode.geometry = geometry
    drawingNode.geometry?.materials.first?.doubleSided = true
}

编辑:2

通过在命中测试的正常情况下添加次要偏移来解决问题

let offsetToAvoidFlickering: Float = 0.05
unprojectedStartPoint = unprojectedStartPoint + result.localNormal.normalized() * offsetToAvoidFlickering
答案

我怀疑你有深度精度问题;看起来你的部分线被剪裁了,因为它们是球体的相交部分。尝试绘制禁用深度测试的线。

另一答案

SceneKit State of the Union Demo示例代码显示了类似的效果,您可以在圆环上绘画。它更强大,因为你可以绘制任何东西(不仅仅是线条,而是从纹理等中飞溅)并且效率更高,因为它不依赖于创建新的几何体。

以上是关于SceneKit - 在3D对象上绘图的主要内容,如果未能解决你的问题,请参考以下文章

在 Vision 识别的坐标上叠加 3D 对象的最佳方式

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

如何通过SceneKit和Model I / O在.OBJ 3d模型上应用.MTL文件

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

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

Swift 3 - SceneKit 获取 3d 模型比例值