2017-03-29 8 views
2

ÜBERARBEITET PROBLEM:Ausrichten von SCNText mit SCNBox in iOS SceneKit mit BoundingBox?

Ich verstehe nicht, warum der weiße Knoten zentriert ist, wenn es eine Box oder Kugel ist, aber nicht, wenn es Text ist. Sie können die whiteGeometry-Variable kommentieren oder auskommentieren, um zu sehen, wie jede unterschiedliche Geometrie angezeigt wird. Ich dachte ursprünglich, dass ich den Text manuell zentrieren müsste, indem ich die Breite der Box und den Text festlege und die Position des Textes berechne. Muss ich das tun? Warum verhält sich der Text anders?

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") 

ORIGINAL PROBLEM (OLD):

Lassen Sie uns sagen, ich habe zwei SCNBox Knoten (ich vereinfacht dies deutlich zu machen, aber die Lösung muss für andere Geometrien arbeiten). Eine große schwarze Box und eine kleine weiße Box. Ich möchte die weiße Box vor der schwarzen Box zentrieren.

Um dies zu tun, muss ich die Breite und Höhe der beiden Knoten bestimmen. Denken Sie daran, dass der Knoten etwas anderes als eine Box wie eine Kugel oder ein Text sein kann. Soweit ich das beurteilen kann, kann die Breite/Höhe nur über die Eigenschaft "boundingBox" in der Geometrie bestimmt werden. Es hat einen Min- und Max-Wert, der im Apple Referenzhandbuch NICHT klar und vollständig beschrieben ist. Um die Höhe zu erhalten, scheint es so zu sein, dass ich es auf der Basis von boundingBox.max.y und boundingBox.min.y berechnen würde. Wenn ich das Beispiel einer 10x10x10 Box betrachte, kann ich nicht sehen, wie ich 10,0 als Höhe erreichen kann, da max.y 5,20507812

z.B.

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)") 

ergibt:

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

Warum ist max.y = 5,20507812? Wie soll ich die Höhe/Breite bestimmen?

Siehe auch: SCNBoundingVolume

+1

Ist die weiße Box ein Kindknoten der Blackbox? Machst du eine Übersetzung, schwenkst du usw., damit es vorne erscheint? Es wäre hilfreich, wenn Sie mehr Code schreiben könnten. – sambro

+1

Ich habe das Code-Snippet auf einem Spielplatz ausgeführt und für jeden Wert +/- 5 erhalten. –

+0

Ja, ich habe die weiße Box zu einem Kind der Blackbox gemacht. Wenn es kein Kind der Blackbox ist, ist der Wert von max.y 5.0. Ich überarbeite den Code in einem Swift-Spielplatz, um das Problem zu klären. – user3246173

Antwort

2

Ich glaube, ich verstehe jetzt.

Es sieht so aus, als ob Sie versuchen, einen Text vor ein Objekt zu stellen, wobei der Text auf das Objekt bezogen auf die Kamera zentriert ist. Und diese Frage geht nicht darum, Boxen per se zu begrenzen. Recht?

Sie sehen ein anderes Verhalten, da die weiße Geometrie eine Kugel oder ein SCNText ist, da SCNText eine andere Ursprungskonvention als die anderen konkreten SCNGeometry-Klassen verwendet. Andere Geometrien stellen den Ursprung in den Mittelpunkt. SCNText platziert es unten links im Text. Wenn ich mich richtig erinnere, bedeutet "niedriger" den unteren Teil der Schrift (niedrigster Unterlängenwert), nicht die Grundlinie.

Sie müssen also die Begrenzungsbox des Textes berechnen und berücksichtigen, wenn Sie den Textknoten positionieren, um ihn zentriert zu bekommen. Dies müssen Sie für die anderen Geometrietypen nicht tun. Wenn sich das bedeckte Objekt oder die Kamera bewegt, müssen Sie den Strahl von der Kamera zum bedeckten Objekt in der Render-Schleife berechnen und die Position des Textes aktualisieren.

Swift Scenekit - Centering SCNText - the getBoundingBoxMin:Max issue ist relevant.

Wenn Sie nur Overlay-Text möchten, ist es möglicherweise einfacher, den Text in ein SKScene-Overlay zu schreiben. Ein Beispiel dafür ist https://github.com/halmueller/ImmersiveInterfaces/tree/master/Tracking%20Overlay (Warnung, Bit-Rot kann gesetzt haben, ich habe diesen Code schon lange nicht mehr ausprobiert).

+0

Ich habe diesen anderen Beitrag vor dem Posten gelesen. Es hat nicht geholfen, da es veraltet, unvollständig usw. war. Ich habe den obigen Code aktualisiert. Ich habe einige Berechnungen für Box Breite/Höhe und Text Breite/Höhe hinzugefügt. Ich versuche, die Position des Textes manuell festzulegen, aber er stimmt nicht richtig überein. Es wäre hilfreich, wenn ich die Begrenzungsbox visuell von der Box und den Textknoten sehen könnte. – user3246173

+0

Eine Frage, die ich habe, ist, ob es ein sizeToFit für SCNText gibt? Wenn Sie den Text für einen SCNText-Knoten festlegen, wird die Größe auf die Mindestgröße angepasst, um den Text anzupassen, oder handelt es sich um einen anderen Standard? – user3246173

+0

Ich fand 'SKScene' Overlay einfach zu tun, aber schrecklich in der Leistung. Es verwendet verschwenderisch CPU, um Koordinaten zu konvertieren. Statischer Knoten ist in Ordnung. Wenn Sie jedoch möchten, dass 2D-Label den 3D-Knoten verfolgt, ist dies ein sofortiger Performance-Kill. In meinem Experiment habe ich ~ 30 Tracking-Labels in einer Szene angezeigt und die Bildrate wurde auf 20 fps gesenkt. –