将 SCNPlane 大小调整为特定的屏幕大小
Adjust SCNPlane size to a specific screen size
在我的应用程序中,用户使用 Core Graphics 在屏幕上绘制一个 2D 矩形。一旦他们松开鼠标,我需要创建一个 SCNPlane 并将其以相同的屏幕大小和位置放置到我的 SceneKit 场景中。我计划将平面的 z 位置设置为远离相机的恒定值(假设距离相机 10 个单位)。
我遇到问题的部分是如何定位和缩放平面,使其看起来与他们在 Core Graphics 中绘制的完全一样。顺便说一句,Core Graphics 视图位于 SceneKit 视图之上,大小相同。
我计划使用广告牌约束,使飞机正确面对相机。
我确定使用相机的属性可以通过一些数学运算来完成此操作,但我不知道如何操作。
最好的办法是制作一个屏幕对齐的容器,其原点和比例设置为您提供像素对齐和您选择的零零位置。
您的积木是 sceneView.unprojectPoint 和 sceneView.frame
import Cocoa // (or UIKit for iOS)
import SceneKit
import PlaygroundSupport;
// create a scene view with an empty scene
var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
var scene = SCNScene()
sceneView.scene = scene
// have it show in your playground
PlaygroundPage.current.liveView = sceneView;
// a camera
var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(0, 0, 3)
scene.rootNode.addChildNode(cameraNode)
var origin = sceneView.unprojectPoint(SCNVector3(0,0,0))
var viewWidth = sceneView.frame.width;
var topRight = sceneView.unprojectPoint(SCNVector3(sceneView.frame.width, 0, 0));
var scale = 2 * (topRight.x - origin.x) / sceneView.frame.width
var container = SCNNode()
origin.z *= -1
origin.x = -2 * topRight.x;
origin.y = -2 * topRight.y;
container.position = origin;
container.scale = SCNVector3(scale, -scale, scale)
cameraNode.addChildNode(container);
func addBox(w:CGFloat, h:CGFloat, x:CGFloat, y:CGFloat) {
let box = SCNNode(geometry: SCNPlane(width: w, height: h))
box.geometry?.firstMaterial?.diffuse.contents = NSColor.red
//SCNPlane geometry is still center-origin
box.position = SCNVector3(x + w / 2, y + h / 2,0)
container.addChildNode(box)
}
addBox(w: 10, h:10, x: 290, y:290)
addBox(w: 10, h:10, x: 0, y:0)
addBox(w: 10, h:10, x: 0, y:290)
addBox(w: 10, h:10, x: 290, y:0)
在我的应用程序中,用户使用 Core Graphics 在屏幕上绘制一个 2D 矩形。一旦他们松开鼠标,我需要创建一个 SCNPlane 并将其以相同的屏幕大小和位置放置到我的 SceneKit 场景中。我计划将平面的 z 位置设置为远离相机的恒定值(假设距离相机 10 个单位)。
我遇到问题的部分是如何定位和缩放平面,使其看起来与他们在 Core Graphics 中绘制的完全一样。顺便说一句,Core Graphics 视图位于 SceneKit 视图之上,大小相同。
我计划使用广告牌约束,使飞机正确面对相机。
我确定使用相机的属性可以通过一些数学运算来完成此操作,但我不知道如何操作。
最好的办法是制作一个屏幕对齐的容器,其原点和比例设置为您提供像素对齐和您选择的零零位置。
您的积木是 sceneView.unprojectPoint 和 sceneView.frame
import Cocoa // (or UIKit for iOS)
import SceneKit
import PlaygroundSupport;
// create a scene view with an empty scene
var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
var scene = SCNScene()
sceneView.scene = scene
// have it show in your playground
PlaygroundPage.current.liveView = sceneView;
// a camera
var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(0, 0, 3)
scene.rootNode.addChildNode(cameraNode)
var origin = sceneView.unprojectPoint(SCNVector3(0,0,0))
var viewWidth = sceneView.frame.width;
var topRight = sceneView.unprojectPoint(SCNVector3(sceneView.frame.width, 0, 0));
var scale = 2 * (topRight.x - origin.x) / sceneView.frame.width
var container = SCNNode()
origin.z *= -1
origin.x = -2 * topRight.x;
origin.y = -2 * topRight.y;
container.position = origin;
container.scale = SCNVector3(scale, -scale, scale)
cameraNode.addChildNode(container);
func addBox(w:CGFloat, h:CGFloat, x:CGFloat, y:CGFloat) {
let box = SCNNode(geometry: SCNPlane(width: w, height: h))
box.geometry?.firstMaterial?.diffuse.contents = NSColor.red
//SCNPlane geometry is still center-origin
box.position = SCNVector3(x + w / 2, y + h / 2,0)
container.addChildNode(box)
}
addBox(w: 10, h:10, x: 290, y:290)
addBox(w: 10, h:10, x: 0, y:0)
addBox(w: 10, h:10, x: 0, y:290)
addBox(w: 10, h:10, x: 290, y:0)