List
SceneKit관련 질문입니다.
Posted Date: 2018-06-26 4:49     Edited Date: 2018-07-06 6:39     Writer: inactive

아직 SceneKit에 대한 정확인 이해가 없어서 그런데 사이트에 올라와 있는 방식으로는

func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval)

를 통해 계속 렌더링하면서 트레킹 매니져에서 이미지가 디텍팅 되어있을 때, 해당 좌표를 기준으로 대상 객체를 렌더링을 하는 것으로 보여집니다.

 

제가 원하는 방법은 타겟 이미지가 디텍팅되어있을 때, addChildNode방식으로 특정 객체를 띄우려고 합니다. 하지만 위 함수의 파라미터에서 scene은 

타겟팅된 객제가 아닌 것으로 보여지는데요... 올려주신 예제를 통하여 제가 원하는 방식으로 특정 객체를 띄울 수 있을까요?

Posted Date: 2018-06-26 6:51     Edited Date: 2018-06-26 6:51     Writer: slkim

addChildNode 방식으로 타겟이 디텍팅 되었을때 추가하시려면, Scenekit 샘플에서 MarkerViewController.swift 보시면 cameraNode에 addChildNode하는 부분이 viewDidLoad에 있습니다. 그부분을 

func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval)

에서 적용하시면 될것 같습니다.

let foxScene = SCNScene(named: "art.scnassets/ship.scn")!

firstNode = foxScene.rootNode

firstTransform = firstNode.transform

cameraNode.addChildNode(firstNode)

이부분을 renderer에서 구현 하시면 됩니다. 이미지에 대한 타겟 네임은 

let trackable:MasTrackable = result.getTrackable(i)

trackable.getName() 을 통해서 얻으실 수 있습니다.

Posted Date: 2018-06-26 7:52     Edited Date: 2018-06-26 7:52     Writer: inactive

가이드해주신대로 하니 객체표현은 잘 됩니다. 그런데 일단 타겟이 인식되면 그 위에 계속 보여지는 것이고, '타겟 이미지에 위치에만' 객체가 보여지게하는 것은 안되네요.

기존 예제를 보니 아마 trackable에서 matrix로 해당 '타겟 좌표를 얻어' 렌더링 하는 것 같은데, addChildNode방식으로는 불가능한 것 일까요?

Posted Date: 2018-06-26 7:57     Edited Date: 2018-06-26 7:57     Writer: slkim

말씀하신 부분이 정확하게 트래킹이 않된다는것인가요?

트래킹 부분은 

firstNode.transform = SCNMatrix4Mult(firstTransform, poseSCNMatrix4)

firstNode.scale = SCNVector3Make(3.0, 3.0, 3.0)

이렇게 적용하셔야 이미지에 붙어서 이동하게 됩니다.

firstTransform은 컨텐츠의 기존 위치이고 poseSCNMatrix4는 타겟 이미지의 중점위치입니다.

Posted Date: 2018-06-27 2:57     Edited Date: 2018-06-27 2:57     Writer: inactive

아래와 같은 방식으로 수정되면 되지 않나요?? (동작하는 모습을 레코딩했는데, 파일첨부는 할 수가 없군요...)

아래와같이 작성하면 이미지 디텍팅시 객체가 위에 나타나게되는데 카메라를 이리저리 돌려도 타겟 중심점위에 있는게 아니라 화면 자체에 붙어서 보여집니다.ㅠ(제가 원하는 것은 카메라를 이리저리 이동해도 타겟 이미지위에 딱 붙어서 보여지게 하고 싶은 것입니다.)

if trackable.getName() == "Lego" {

                    let foxScene = SCNScene(named: "art.scnassets/ship.scn")!

                    if foxNode == nil {

                        foxNode = foxScene.rootNode

                        foxTransform = foxNode.transform

                        foxNode.transform = SCNMatrix4Mult(foxTransform, poseSCNMatrix4)

                        foxNode.position = SCNVector3(0.0, 0.0, -3.0)

                        foxNode.scale = SCNVector3(3.0, 3.0, 3.0)

                        

                        cameraNode.addChildNode(foxNode)

                    }

                }

Posted Date: 2018-06-27 4:41     Edited Date: 2018-06-27 4:41     Writer: slkim

if trackable.getName() == "Lego" {
    if(foxScene == nil) {
         foxScene = SCNScene(named: "art.scnassets/ship.scn")!
         firstNode = foxScene.rootNode
         firstTransform = firstNode.transform
         cameraNode.addChildNode(firstNode)
    } 

    if(firstNode != nil) {
        firstNode.transform = SCNMatrix4Mult(firstTransform, poseSCNMatrix4)
        firstNode.scale = SCNVector3Make(3.0, 3.0, 3.0)
    }
}

이런식으로 하셔야 합니다. ship.scn을 계속 로드할 필요는 없으시고, 해당 컨텐츠가 로드 되고 나면 "Lego"라는 이미지가 보여지면 poseSCNMatrix4이 매트릭스를 해당 Node에 적용시켜서 이미지에 붙어다니게 해야합니다.

Posted Date: 2018-06-28 9:52     Edited Date: 2018-06-28 9:52     Writer: inactive

음..말씀해주신대로 수정하니 컨텐츠가 해당 이미지위에 그려지고 있습니다. 하지만 역시나 한 부분에 딱 고정되어 있는 것은 아니고, 타겟 이미지내에 움직이긴 하네요;;(파일 첨부). 말씀하신 것이 아래 그림과 같이 나타나는 결과인 것인가요?

 

그리고 트래킹 부분이 벗어낫을 때, 해당 컨텐츠를 제거하고 싶은데, 아래와같이 구현하면 EXC_BAD_ACCESS 에러가나네요...

단순히 removeFromParentNode()만 호출해서는 안되는 것인가요??

            cameraNode.enumerateChildNodes({ (child: SCNNode, _: UnsafeMutablePointer<ObjCBool>) in

                if let name = child.name {

                    print("name:\(name)")

                }

                if child.name == "ship" {

                    child.removeFromParentNode()

                }

            })

어떤식으로 구현해야 할까요??

Posted Date: 2018-07-05 6:22     Edited Date: 2018-07-05 6:22     Writer: inactive

답변 부탁드겠습니다ㅠ

Posted Date: 2018-07-06 5:01     Edited Date: 2018-07-06 5:01     Writer: slkim

답변이 늦어져서 죄송합니다.

1. 이미지에 붙어서 트래킹 되는것이 맞습니다. 무언가 잘못 적용된것 같네요.

2. 노드를 제거하기 위해서는 메인 스레드에서 해야하는것 같습니다.

관련된 소스 첨부해 드립니다.

https://www.dropbox.com/s/evnq908iioszve1/ImageViewController.swift?dl=0

Posted Date: 2018-07-06 6:39     Edited Date: 2018-07-06 6:39     Writer: inactive

네! 감사합니다!! 궁금한 내용은 다 해결되었네요!!

주신 소스를 가지고 참고하도록 하겠습니다! :)