私はモデル(例えば、4つの壁を持つ建物)を作成し、それをSketchupを使用して.deaファイルとしてエクスポートしました。その後、私はタップゲストをシーンに追加し、シーンのどの壁がタップされているかを調べます。私は結果を得ました - 壁の正確な名前(ID)が、私はその地位を得ていませんでした。位置は常に - (x:0、y:0、z:0)です。タップした各壁に新しいSCNNodeを追加したいので、シーンの壁の正確な位置が必要です。既存のシーンのノードの位置を取得する方法は?
スクリーンショット:スクリーンショットのように
、私は、最初の建物の正面側壁にタップが、結果はゼロベクトルです。
私はすべてのソリューションを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
}
}
コード –
を試しましたか?http://stackoverflow.com/questions/26785453/how-to-get-the-real-position-of-a-sub-node-in-scenekit-after-rotation ? –
@Harvant S.私は試してみましたが、動作していません.plsコードを確認してください。 – KSR