2017-03-29 9 views
2

改訂された問題:SCNTextをiOSのSCNBoxに合わせるSceneKitとboundingBox?

ホワイトノードがボックスまたは球の場合は中央に配置され、テキストの場合は白ノードが中央に配置される理由はわかりません。 whiteGeometry変数のコメント/コメントを解除して、それぞれのジオメトリがどのように表示されるかを確認できます。もともと、ボックスとテキストの幅を決め、テキストの位置を計算することで、手動でテキストの中心を合わせなければならないと考えていました。私はそれをする必要がありますか?テキストの動作が異なるのはなぜですか?

import SceneKit 
import PlaygroundSupport 

let scene = SCNScene() 
let sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 500, height: 500)) 
sceneView.scene = scene 
sceneView.backgroundColor = .darkGray 
sceneView.autoenablesDefaultLighting = true 
sceneView.allowsCameraControl = true 
PlaygroundPage.current.liveView = sceneView 

// Camera 
let cameraNode = SCNNode() 
cameraNode.camera = SCNCamera() 
scene.rootNode.addChildNode(cameraNode) 
cameraNode.position = SCNVector3(x: 0, y: 0, z: 25) 
sceneView.pointOfView = cameraNode 

let blackGeometry = SCNBox(width: 10.0, height: 10.0, length: 10.0, chamferRadius: 0) 
blackGeometry.firstMaterial?.diffuse.contents = UIColor.black 
print("blackGeometry min=\(blackGeometry.boundingBox.min)") 
print("blackGeometry max=\(blackGeometry.boundingBox.max)") 
let blackNode = SCNNode(geometry: blackGeometry) 
blackNode.position = SCNVector3(x: 0, y: 0, z: 0) 
scene.rootNode.addChildNode(blackNode) 

// let whiteGeometry = SCNBox(width: 3.0, height: 3.0, length: 3.0, chamferRadius: 0) 
let whiteGeometry = SCNText(string: "L", extrusionDepth: 0) 
whiteGeometry.alignmentMode = kCAAlignmentLeft 
whiteGeometry.font = UIFont.systemFont(ofSize: 8.0) 
// let whiteGeometry = SCNSphere(radius: 3.0) 
whiteGeometry.firstMaterial?.diffuse.contents = UIColor.white 
print("whiteGeometry min=\(whiteGeometry.boundingBox.min)") 
print("whiteGeometry max=\(whiteGeometry.boundingBox.max)") 
let whiteNode = SCNNode(geometry: whiteGeometry) 

let boxWidth = blackGeometry.boundingBox.max.x - blackGeometry.boundingBox.min.x 
let boxHeight = blackGeometry.boundingBox.max.y - blackGeometry.boundingBox.min.y 
print("boxWidth=\(boxWidth)") 
print("boxHeight=\(boxHeight)") 

let txtWidth = whiteGeometry.boundingBox.max.x - whiteGeometry.boundingBox.min.x 
let txtHeight = whiteGeometry.boundingBox.max.y - whiteGeometry.boundingBox.min.y 
print("txtWidth=\(txtWidth)") 
print("txtHeight=\(txtHeight)") 

whiteNode.position = SCNVector3(x: -5.0, y: -5.0, z: 10) 
scene.rootNode.addChildNode(whiteNode) 
//blackNode.addChildNode(whiteNode) 

print("done") 

元の問題(OLD):

のは、私は2つのSCNBoxノード(私はそれを明確にするために、これを単純化していますが、溶液は、他の幾何学的形状のために働かなければならない)を持っているとしましょう。大きな黒い箱と小さな白い箱。私は白いボックスを黒いボックスの前に置いて欲しい。

これを行うには、2つのノードの幅と高さを決定する必要があります。ノードは、球やテキストのようなボックス以外のものになる可能性があることに注意してください。私が知ることから、幅/高さを決定する唯一の方法は、ジオメトリのboundingBoxプロパティを使用することです。最小値と最大値は、Appleのリファレンスマニュアルにはっきりと記載されていません。高さを取得するには、boundingBox.max.yとboundingBox.min.yに基づいて計算するようです。したがって、10x10x10ボックスの下の例を見ると、高さとして10.0を得る方法がわかりません。5.20507812

let box = SCNBox(width: 10.0, height: 10.0, length: 10.0, chamferRadius: 0) 
print("box min=\(box.boundingBox.min)") 
print("box max=\(box.boundingBox.max)") 

利回り:

box min=SCNVector3(x: -5.0, y: -5.0, z: -5.0) 
box max=SCNVector3(x: 5.0, y: 5.20507812, z: 5.0) 

なぜmax.y = 5.20507812のですか?高さ/幅はどのように決定するのですか?

も参照してください:SCNBoundingVolume

+1

ホワイトボックスはブラックボックスの子ノードですか?それを正面に現れるように翻訳やピボットなどをしていますか?より多くのコードを投稿することができれば助かります。 – sambro

+1

私はそのコードスニペットを遊び場で走らせ、各値に対して+/- 5を得ました。 –

+0

はい、私はホワイトボックスをブラックボックスの子供にしました。ブラックボックスの子ではない場合、最大値は5.0です。問題を明確にするためにSwiftのプレイグラウンドでコードを修正しています。 – user3246173

答えて

2

私は今理解だと思います。

オブジェクトの前にテキストを配置しようとしているように見えます。テキストはカメラを基準にオブジェクトの中央に配置されています。そして、この質問は箱自体を囲むことではありません。右?

SCNTextが他の具体的なSCNGeometryクラスとは異なる起点規則を使用するため、白色のジオメトリが球体またはSCNTextで異なる動作があります。他のジオメトリは原点を中央に置きます。 SCNTextはテキストの左下にそれを置きます。私が正しく覚えていれば、 "下"はベースラインではなく、フォントの下端(最も低いディケイダー)を意味します。

テキストの境界ボックスを計算し、テキストノードを配置するときにそれを考慮する必要があります。他のジオメトリタイプでは、これを行う必要はありません。カバーされたオブジェクトまたはカメラが動いている場合は、レンダリングループでカメラから対象オブジェクトまでのレイを計算し、テキストの位置を更新する必要があります。

Swift Scenekit - Centering SCNText - the getBoundingBoxMin:Max issueが該当します。

オーバレイテキストだけが必要な場合は、テキストをSKSceneオーバーレイに入れる方が簡単です。その例がhttps://github.com/halmueller/ImmersiveInterfaces/tree/master/Tracking%20Overlayにあります(警告、ビットロートが設定されている可能性がありますが、私はそのコードをしばらく試していません)。

+0

投稿する前に他の投稿を読んでいます。これは時代遅れだったので、役に立たなかった、不完全な、など...私は上記のコードを更新しました。ボックスの幅/高さとテキストの幅/高さの計算をいくつか追加しました。テキストの位置を手動で設定しようとしましたが、正しく配置されません。ボックスとテキストノードの境界ボックスを視覚的に見ることができれば役に立ちます。 – user3246173

+0

私が持っている1つの質問は、SCNTextのsizeToFitがあるかどうかです。 SCNTextノードのテキストを設定すると、テキストに合う最小サイズになっていますか、それとも他のデフォルトですか? – user3246173

+0

私は 'SKScene'オーバーレイがやりやすいが、パフォーマンスは恐ろしいことが分かった。 CPUを無駄に使用して座標を変換します。静的ノードは正常です。しかし、2dラベルで3dノードを追跡したい場合は、即座にパフォーマンスを低下させます。私の実験では、シーンに〜30個のトラッキングラベルを表示し、フレームレートは20fpsに落としました。 –

関連する問題