Dharini
Dharini

Reputation: 857

How to get accurate CGpoint for drawing UIBezierpath on sceneview from touchesMoved method?

UIBezierpath displays somewhere else on real world

make collection of CGPoint from below code

 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let location = touches.first?.location(in: self.sceneView) else {
            return
        }
        arrayCGPoints.append(location)
    }

& display Bazierpath using below code

func updateBazierPath(){        

        if arrayCGPoints.count > 0 {

            let bezierPath = UIBezierPath()

            var i : Int = 0
            for varPoint in arrayCGPoints{

                if i == 0 {
                    bezierPath.move(to: varPoint)
                }
                else{
                    bezierPath.addLine(to: varPoint)
                }
                i += 1
            }
            bezierPath.close()
        }
        // Add shape
        let shape = SCNShape(path: bezierPath, extrusionDepth: 0.2)
        let shapeNode = SCNNode(geometry: shape)
    self.sceneView.scene.rootNode.addChildNode(shapeNode)

        shapeNode.geometry?.firstMaterial?.isDoubleSided = true
        shapeNode.geometry!.firstMaterial?.diffuse.contents = UIColor.blue
        shapeNode.position.z = -0.2
        shapeNode.eulerAngles.x = -.pi / 2
    }

also tried convert CGPoints into meters

arrayCGPoints.append(CGPoint(x: location.x/100, y: location.y/100))

still not working

Upvotes: 1

Views: 216

Answers (1)

Voltan
Voltan

Reputation: 1213

This will draw a node @ 0,0,0 with an outline of what the person dragged from, translating screen coords to world. I created a separate array of SCNVector3's that are the coords in 3d space (you could drop some nodes on the screen at these points to prove the positions). Also note the append is x,z,z (not scenepoint.y). My camera is looking at 0,0,0 from 0,15,0.1. This will at least give you a visual on what was happening to z and hopefully does answer the question you asked.

If you want the resulting shape to stay lined up with exactly where the user touched, that's not solved here.

var shapeNode = SCNNode()

func updateBazierPath()
{
    for vPoints in arrayCGPoints
    {
        let projectedPoint = gameScene.projectPoint(SCNVector3(0, 0, 0))
        let scenePoint = gameScene.unprojectPoint(SCNVector3(vPoints.x, vPoints.y, CGFloat(projectedPoint.z)))
        scenePoints.append(SCNVector3(scenePoint.x, scenePoint.z, scenePoint.z))
    }
    let bezierPath = UIBezierPath()
    bezierPath.move(to: CGPoint(x: CGFloat(scenePoints[0].x), y: CGFloat(scenePoints[0].y)))
    for vCount in 1...scenePoints.count - 1
    {
        bezierPath.addLine(to: CGPoint(x: CGFloat(scenePoints[vCount].x), y: CGFloat(scenePoints[vCount].y)))
    }
    bezierPath.close()

    shapeNode.removeFromParentNode()
    let shape = SCNShape(path: bezierPath, extrusionDepth: 0.5)
    shapeNode = SCNNode(geometry: shape)
    shapeNode.geometry?.firstMaterial?.isDoubleSided = true
    shapeNode.geometry!.firstMaterial?.diffuse.contents = UIColor.yellow
    //let action = SCNAction.repeatForever(SCNAction.rotate(by: .pi, around: SCNVector3(1, 0, 0), duration: 5))
    //shapeNode.runAction(action)
    shapeNode.position = SCNVector3(0, 0, 0)
    shapeNode.eulerAngles.x = -.pi / 2
    gNodes.gameNodes.addChildNode(shapeNode)
}

Upvotes: 1

Related Questions