2016-11-25 12 views
1

私はモデル(例えば、4つの壁を持つ建物)を作成し、それをSketchupを使用して.deaファイルとしてエクスポートしました。その後、私はタップゲストをシーンに追加し、シーンのどの壁がタップされているかを調べます。私は結果を得ました - 壁の正確な名前(ID)が、私はその地位を得ていませんでした。位置は常に - (x:0、y:0、z:0)です。タップした各壁に新しいSCNNodeを追加したいので、シーンの壁の正確な位置が必要です。既存のシーンのノードの位置を取得する方法は?

スクリーンショット:スクリーンショットのように

enter image description here

、私は、最初の建物の正面側壁にタップが、結果はゼロベクトルです。

私はすべてのソリューションをstackOverflowとインターネットで試しましたが、成功しませんでした。誰か助けてくれますか?

DAEファイル:

http://www.filefactory.com/file/40y2ef86hgm3/Sample3d.dae

コード:あなたは添付ファイルで

import UIKit 
import QuartzCore 
import SceneKit 
import SpriteKit 
import AVFoundation 

class SceneViewController: UIViewController, UIGestureRecognizerDelegate { 

    //Data handlers 
    var currentSceneView: SCNView? = nil 
    var cameraOrbit = SCNNode() 
    let cameraNode = SCNNode() 
    let camera = SCNCamera() 
    var sceneText = SCNText() 

    //HANDLE PAN CAMERA 
    var lastWidthRatio: Float = 0 
    var lastHeightRatio: Float = 0.2 
    var WidthRatio: Float = 0 
    var HeightRatio: Float = 0.2 
    var fingersNeededToPan = 1 
    var maxWidthRatioRight: Float = 0.2 
    var maxWidthRatioLeft: Float = -0.2 
    var maxHeightRatioXDown: Float = 0.02 
    var maxHeightRatioXUp: Float = 0.4 

    //HANDLE PINCH CAMERA 
    var pinchAttenuation = 20.0 //1.0: very fast ---- 100.0 very slow 
    var lastFingersNumber = 0 
    var myScene = SCNScene() 


    // MARK: - View Lifecycle methods 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     // create a new scene 
     let scene = SCNScene(named: "Sample3d.dae")! 


     myScene = scene 

     addCameraNode(scene: scene) 
     prepareScene(scene: scene) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Release any cached data, images, etc that aren't in use. 
    } 

    // MARK: - Private APIs 


    func addCameraNode(scene : SCNScene){ 
     // create and add a camera to the scene 
     let cameraNode = SCNNode() 
     cameraNode.camera = SCNCamera() 
     scene.rootNode.addChildNode(cameraNode) 

     // place the camera 
     cameraNode.position = SCNVector3(x: 0, y: 0, z: 15) 

     // create and add a light to the scene 
     let lightNode = SCNNode() 
     lightNode.light = SCNLight() 
     lightNode.light!.type = SCNLight.LightType.omni 
     lightNode.position = SCNVector3(x: 0, y: 10, z: 10) 
     // scene.rootNode.addChildNode(lightNode) 

     cameraNode.addChildNode(lightNode) 

     // create and add an ambient light to the scene 
     let ambientLightNode = SCNNode() 
     ambientLightNode.light = SCNLight() 
     ambientLightNode.light!.type = SCNLight.LightType.ambient 
     ambientLightNode.light!.color = UIColor.darkGray 
     // scene.rootNode.addChildNode(ambientLightNode) 
     cameraNode.addChildNode(ambientLightNode) 

     //Create a camera like Rickster said 
     camera.usesOrthographicProjection = true 
     camera.orthographicScale = 1 
     //camera.orthographicScale = 100 
     camera.zNear = 1 
     camera.zFar = 100 

     cameraNode.position = SCNVector3(x: 0, y: 0, z: 20) 
     cameraNode.camera = camera 
     cameraOrbit = SCNNode() 
     cameraOrbit.addChildNode(cameraNode) 
     scene.rootNode.addChildNode(cameraOrbit) 
    } 

    func prepareScene(scene : SCNScene){ 
     self.navigationItem.title = "3D Scene" 
     //initial camera setup 
     self.cameraOrbit.eulerAngles.y = Float(-3 * M_PI) * lastWidthRatio 
     self.cameraOrbit.eulerAngles.x = Float(-M_PI) * lastHeightRatio 

     // retrieve the SCNView 
     let scnView = self.view as! SCNView 

     currentSceneView = scnView 

     // set the scene to the view 
     scnView.scene = scene 

     // allows the user to manipulate the camera 
     scnView.allowsCameraControl = true 

     // show statistics such as fps and timing information 
     scnView.showsStatistics = true 

     // configure the view 
     scnView.backgroundColor = UIColor.black 

     //allows the user to manipulate the camera 
     scnView.allowsCameraControl = false //not needed 

     // add a tap gesture recognizer 
     let panGesture = UIPanGestureRecognizer(target: self, action: #selector(SceneViewController.handlePan(_:))) 
     scnView.addGestureRecognizer(panGesture) 

     // add a pinch gesture recognizer 
     let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(SceneViewController.handlePinch(_:))) 
     scnView.addGestureRecognizer(pinchGesture) 

     let tap = UITapGestureRecognizer(target: self, action: #selector(SceneViewController.handleTap(_:))) 
     tap.delegate = self 
     scnView.addGestureRecognizer(tap) 
    } 

    // MARK: - Guesture Recognition methods 

    func handleTap(_ gestureRecognize: UIGestureRecognizer) { 

     let location: CGPoint = gestureRecognize.location(in: currentSceneView)// for example from a tap gesture recognizer 
     let hits = self.currentSceneView?.hitTest(location, options: nil) 
     if let tappedNode = hits?.first?.node { 
addVideoNodeToScene(presentNode: tappedNode) 

     } 
    } 


func addVideoNodeToScene(presentNode: SCNNode){ 

     if let path = Bundle.main.path(forResource: "Sample", ofType: "mp4") { 
      let videoUrl = NSURL(fileURLWithPath: path) 
      let player = AVPlayer(url: videoUrl as URL) 
      let videoNode = SKVideoNode(avPlayer: player) 
      let size = CGSize(width: 1024, height: 512) 
      videoNode.size = size 
      videoNode.position = CGPoint(x: size.width/2.0,y :size.height/2.0) 
      let spriteScene = SKScene(size: size) 
      spriteScene.addChild(videoNode) 

      let cubeMaterial = SCNMaterial() 
      cubeMaterial.diffuse.contents = spriteScene 
      cubeMaterial.isDoubleSided = true 

      let v1 = SCNVector3(x: 0,y: 0,z: 0) 
      let v2 = SCNVector3(x: 0,y: 0,z: 0) 
      let dx:Float = Float(v1.x - v2.x)/2.0 
      let dy:Float = Float(v1.y - v2.y) 

      var plane = SCNPlane() 
      plane = SCNPlane.init(width: 0.35, height: 0.35) 
      let planeNode = SCNNode(geometry: plane) 

      plane.firstMaterial?.isDoubleSided = true 
      planeNode.rotation = SCNVector4(x: 0, y: 0, z: 1, w: Float(M_PI)) 
      planeNode.geometry?.firstMaterial = cubeMaterial 
      planeNode.position = presentNode.position 
      planeNode.position.z = planeNode5.position.z + 0.15 

      myScene.rootNode.addChildNode(planeNode) 

      videoNode.play() 
     } 
    } 


    func handlePan(_ gestureRecognize: UIPanGestureRecognizer) { 

     let numberOfTouches = gestureRecognize.numberOfTouches 
     let translation = gestureRecognize.translation(in: gestureRecognize.view!) 

     if (numberOfTouches==fingersNeededToPan) { 

      WidthRatio = Float(translation.x)/Float(gestureRecognize.view!.frame.size.width) + lastWidthRatio 
      HeightRatio = Float(translation.y)/Float(gestureRecognize.view!.frame.size.height) + lastHeightRatio 

      // HEIGHT constraints 
      if (HeightRatio >= maxHeightRatioXUp) { 
       HeightRatio = maxHeightRatioXUp 
      } 
      if (HeightRatio <= maxHeightRatioXDown) { 
       HeightRatio = maxHeightRatioXDown 
      } 

      // WIDTH constraints 
      if(WidthRatio >= maxWidthRatioRight) { 
       WidthRatio = maxWidthRatioRight 
      } 
      if(WidthRatio <= maxWidthRatioLeft) { 
       WidthRatio = maxWidthRatioLeft 
      } 

      self.cameraOrbit.eulerAngles.y = Float(-5 * M_PI) * WidthRatio 
      self.cameraOrbit.eulerAngles.x = Float(-2 * M_PI) * HeightRatio 

      //print("Height: \(round(HeightRatio*100))") 
      //print("Width: \(round(WidthRatio*100))") 

      //for final check on fingers number 
      lastFingersNumber = fingersNeededToPan 
     } 

     lastFingersNumber = (numberOfTouches>0 ? numberOfTouches : lastFingersNumber) 

     if (gestureRecognize.state == .ended && lastFingersNumber==fingersNeededToPan) { 
      lastWidthRatio = WidthRatio 
      lastHeightRatio = HeightRatio 
      //print("Pan with \(lastFingersNumber) finger\(lastFingersNumber>1 ? "s" : "")") 
     } 

    } 

    func handlePinch(_ gestureRecognize: UIPinchGestureRecognizer) { 
     let pinchVelocity = Double.init(gestureRecognize.velocity) 
     //print("PinchVelocity \(pinchVelocity)") 

     camera.orthographicScale -= (pinchVelocity/pinchAttenuation) 

     //print("PinchVelocity \(camera.orthographicScale)") 

     if camera.orthographicScale <= 0.5 { 
      camera.orthographicScale = 0.5 
     } 

     if camera.orthographicScale >= 5 { 
      camera.orthographicScale = 5 
     } 

    } 

    // MARK: - ViewController Orientation methods 

    override var shouldAutorotate : Bool { 
     return true 
    } 

    override var supportedInterfaceOrientations : UIInterfaceOrientationMask { 
     if UIDevice.current.userInterfaceIdiom == .phone { 
      return .allButUpsideDown 
     } else { 
      return .all 
     } 
    } 

    // MARK: - Status bar methods 

    override var prefersStatusBarHidden : Bool { 
     return true 
    } 
} 
+0

コード –

+0

を試しましたか?http://stackoverflow.com/questions/26785453/how-to-get-the-real-position-of-a-sub-node-in-scenekit-after-rotation ? –

+0

@Harvant S.私は試してみましたが、動作していません.plsコードを確認してください。 – KSR

答えて

1

は、各ノードは(0, 0, 0)上に配置が異なるeuler angleを持っています。私は他の3Dモデルをチェックしているので、あなたのコードは絶対にうまく動作します。あなたの3Dデザイナーに連絡してモデルを修正するように頼んでください。

daeを編集者(Xcode)に開き、すべてeuler angleから(0, 0, 0)に変更し、要件に応じてノードの位置を変更することをお勧めします。

+0

答えにサンプル3Dモデルを添付できますか?私はそれをチェックしたい。 – KSR

+0

申し訳ありませんが、NDAのためにできません。私は何かすることを提案することができます。エディタ(Xcode)のOpen daeはすべてのオイラー角を(0、0、0)にし、要件に応じてノードの位置を変更します。時間がかかることがあります。 –

+0

オクラブン、私はあなたに戻ってみるつもりです..あなたの助けをありがとう.. – KSR

関連する問題