2017-01-14 5 views
2

私はプログラムで作成された平面を持っています。平面が持つ1つの頂点の座標を取得したいと思います。このような何か:print(Plane.vertices[1].position)と、それはのようなものに印刷されることがあります:(X:1を、Y:1)、およびprint(Plane.vertices[2].position)プリント(X - 1、Y:1)ノードシーンキットの頂点の位置を取得する

enter image description here これは私が飛行機を作成する方法です。

let positions = [SCNVector3Make( 0, -0.1, 0), 
         SCNVector3Make( 0.3, -0.1, 0), 

         SCNVector3Make( 0, 0.1, 0), 
         SCNVector3Make( 0.3, 0.1, 0), 
         ] 
     let indices :[UInt16] = [ 

      0, 1, 2, 
      1, 3, 2, 
      ] 

     let vertexSource = SCNGeometrySource(vertices: positions, count: 4) 
     let indexData = NSData(bytes: indices, length: MemoryLayout<CInt>.size * indices.count) 


     let newElement = SCNGeometryElement(data: NSData(bytes: indices, length: indices.count * MemoryLayout<Int16>.size) as Data, primitiveType: .triangles , primitiveCount: 2, bytesPerIndex: MemoryLayout<Int16>.size) 

     let geometry = SCNGeometry(sources: [vertexSource], elements: [newElement]) 
     custom = SCNNode(geometry: geometry) 
     scene.rootNode.addChildNode(custom!) 
     custom?.position = SCNVector3Make(0, 0, 0) 

これは何とか変換で行うことができると思いますが、カスタムの変換にはわかりにくいm11、m12、m13などの奇妙なものがたくさんあります。

+0

私は問題を探って、変換に関する多くのスタックオーバーフローに関する質問を見ましたが、scnmatrix mのものの意味を説明しません。この記事は、英語が私の母国語ではなく、英語でいくつかのことを記述するのが難しいため、私はシーンキットについて何も読んでいないように思えるかもしれません – Asphys

+1

この質問と飛行機の頂点に関するあなたのもう一つの質問から、私はまだ理解しませんあなたが見たいと思う効果。あなたは私達に荒い鉛筆のスケッチを描いてそれをアップロードできますか? –

+0

@HalMueller私は彼が彼の飛行機オブジェクトを構築するために作成した各頂点のシーン座標の後ろだと思います。 – Confused

答えて

4

これは、最初の一見よりも複雑な質問です。

SceneKitは、ノードを生成するために使用されたジオメトリの座標を元の縮尺/基準で保存します。オブジェクトが作成されてもそれらは変更されません。 SCNPlaneまたはSCNBoxのようなプリミティブの場合、これらのジオメトリはシーン内で共有されます。したがって、異なる位置、回転、および拡大率で異なるプレーンまたはボックスの束がある場合は、SCNGeometrySourceを照会するときに同じ頂点を取得します。ここでの検索についての良い議論があります:Extracting vertices from scenekit。しかし、そのアプローチは、あなたのローカル座標空間のコーナーを与えることはありません。

我々はSCNNodeSCNGeometryに取り組む二つの機能を持っている:boundingBoxboundingSphere(彼らはプロトコルSCNBoundingVolumeで定義されています)。 boundingBoxでは、最小値と最大値の2つのポイントが得られます。立方体の2つの反対側の角から、平面の頂点を見つけることができます。しかし、もう一つの合併症があります。これらの関数はいずれもローカル座標(ノード自体が使用する座標系)で応答を返します。だから私たちはまだ立ち往生しています:私の飛行機や箱のすべてが同じバウンディングボックスを持っています。

私が思いついた答えは、SCNNodeのconvertPosition(_, to: node)を使ってシーンのルートノードを渡すことでした。それは最終的に私にルートノードの座標空間にバウンディングボックスを与えます。

for node in [custom1, custom2, plainPlane1, plainPlane2] { 
    print(node.name!) 
    print(node.boundingBox.max) 
    print(node.boundingBox.min) 
    print(node.convertPosition(node.boundingBox.min, to: scene.rootNode)) 
    print(node.convertPosition(node.boundingBox.max, to: scene.rootNode)) 
} 

このシーンのため

 
custom 1 
SCNVector3(x: 0.300000011920929, y: 0.100000001490116, z: 0.0) 
SCNVector3(x: 0.0, y: -0.100000001490116, z: 0.0) 
SCNVector3(x: 0.0, y: -0.100000001490116, z: -1.0) 
SCNVector3(x: 0.300000011920929, y: 0.100000001490116, z: -1.0) 
custom 2 
SCNVector3(x: 0.300000011920929, y: 0.100000001490116, z: 0.0) 
SCNVector3(x: 0.0, y: -0.100000001490116, z: 0.0) 
SCNVector3(x: 0.200000002980232, y: 0.429289322037836, z: -1.07071067796216) 
SCNVector3(x: 0.500000014901161, y: 0.570710677962164, z: -0.929289322037836) 
plain plane 1 
SCNVector3(x: 0.5, y: 1.0, z: 0.0) 
SCNVector3(x: -0.5, y: -1.0, z: 0.0) 
SCNVector3(x: -0.5, y: -1.0, z: -2.0) 
SCNVector3(x: 0.5, y: 1.0, z: -2.0) 
plain plane 2 
SCNVector3(x: 0.5, y: 1.0, z: 0.0) 
SCNVector3(x: -0.5, y: -1.0, z: 0.0) 
SCNVector3(x: -9.18485139438876e-18, y: -0.300000011920929, z: -1.84999999403954) 
SCNVector3(x: 9.18485139438876e-18, y: 0.300000011920929, z: -2.15000000596046) 

を生産する:あなたは、変換行列を述べた

 
//: Playground - noun: a place where people can play 

import Cocoa 
import SceneKit 
import PlaygroundSupport 

let positions = [SCNVector3Make( 0, -0.1, 0), 
       SCNVector3Make( 0.3, -0.1, 0), 
       SCNVector3Make( 0, 0.1, 0), 
       SCNVector3Make( 0.3, 0.1, 0), 
] 
let indices :[UInt16] = [ 
    0, 1, 2, 
    1, 3, 2, 
] 

let vertexSource = SCNGeometrySource(vertices: positions, count: 4) 
let indexData = NSData(bytes: indices, length: MemoryLayout.size * indices.count) 

let newElement = SCNGeometryElement(data: NSData(bytes: indices, 
               length: indices.count * MemoryLayout.size) as Data, 
            primitiveType: .triangles , 
            primitiveCount: 2, 
            bytesPerIndex: MemoryLayout.size) 

let sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 600, height: 400)) 
sceneView.allowsCameraControl = true 
sceneView.autoenablesDefaultLighting = true 
sceneView.backgroundColor = NSColor.darkGray 
sceneView.showsStatistics = true 
PlaygroundPage.current.liveView = sceneView 

let scene = SCNScene() 
sceneView.scene = scene 

let geometry = SCNGeometry(sources: [vertexSource], elements: [newElement]) 
geometry.firstMaterial?.diffuse.contents = NSColor.red 
geometry.firstMaterial?.isDoubleSided = true 
let custom1 = SCNNode(geometry: geometry) 
custom1.position = SCNVector3Make(0, 0, -1) 
custom1.name = "custom 1" 
scene.rootNode.addChildNode(custom1) 

let custom2 = SCNNode(geometry: geometry) 
custom2.position = SCNVector3Make(0.2, 0.5, -1) 
custom2.rotation = SCNVector4Make(1, 0, 0, CGFloat(M_PI_4)) 
custom2.name = "custom 2" 
scene.rootNode.addChildNode(custom2) 

let plainPlaneGeometry = SCNPlane(width: 1, height: 2) 
plainPlaneGeometry.firstMaterial?.diffuse.contents = NSColor.yellow 
plainPlaneGeometry.firstMaterial?.isDoubleSided = true 
let plainPlane1 = SCNNode(geometry: plainPlaneGeometry) 
plainPlane1.position = SCNVector3Make(0, 0, -2) 
plainPlane1.name = "plain plane 1" 
scene.rootNode.addChildNode(plainPlane1) 

let plainPlane2 = SCNNode(geometry: plainPlaneGeometry) 
plainPlane2.position = SCNVector3Make(0, 0, -2) 
plainPlane2.rotation = SCNVector4Make(0, 1, 0, CGFloat(M_PI_2)) 
plainPlane2.scale = SCNVector3Make(0.3, 0.3, 0.3) 
plainPlane2.name = "plain plane 2" 
scene.rootNode.addChildNode(plainPlane2) 

for node in [custom1, custom2, plainPlane1, plainPlane2] { 
    print(node.name!) 
    print(node.boundingBox.max) 
    print(node.boundingBox.min) 
// print(node.transform) 
    print(node.convertPosition(node.boundingBox.min, to: scene.rootNode)) 
    print(node.convertPosition(node.boundingBox.max, to: scene.rootNode)) 
} 

enter image description here

ここでは、以下のフルMacOSの遊び場です。 Need better and simpler understanding of CATransform3D(2つの優れたWikipediaの記事を引用しています)、そして簡単に概要をダイジェストするのは、http://sketchytech.blogspot.com/2014/12/explaining-catransform3d-matrix.htmlです。

関連する問題