简体   繁体   English

将 SCNPlane 大小调整为特定的屏幕大小

[英]Adjust SCNPlane size to a specific screen size

In my application, the user draws a 2D rectangle on the screen using Core Graphics.在我的应用程序中,用户使用 Core Graphics 在屏幕上绘制一个 2D 矩形。 Once they release their mouse I need to create a SCNPlane and place it into my SceneKit scene at the same screen size and position.一旦他们松开鼠标,我需要创建一个 SCNPlane 并将其放置在我的 SceneKit 场景中,屏幕大小和位置相同。 I plan on setting the z position of the plane to a constant value away from the camera (lets say 10 units away from the camera).我计划将平面的 z 位置设置为远离相机的恒定值(假设距相机 10 个单位)。

The part I'm having trouble with is how to position and scale the plane so it looks exactly like what they drew in Core Graphics.我遇到麻烦的部分是如何定位和缩放平面,使其看起来与他们在 Core Graphics 中绘制的完全一样。 BTW the Core Graphics view is on top of the SceneKit view at the same size.顺便说一句,Core Graphics 视图位于相同大小的 SceneKit 视图之上。

I plan on using the billboard constraint so the plane is facing the camera properly.我计划使用广告牌约束,使飞机正确面对相机。

I'm sure there is some math to accomplish this using the camera's properties, but I have no clue how to do it.我确信有一些数学方法可以使用相机的属性来实现这一点,但我不知道如何去做。

Best bet is to make a screen-aligned container with its origin and scale set to give you pixel-alignment and your choice of zero-zero location.最好的办法是制作一个屏幕对齐的容器,其原点和比例设置为您提供像素对齐和您选择的零零位置。

your building blocks are sceneView.unprojectPoint and sceneView.frame你的积木是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)

结果:视图的每个角都有 10 个像素的块

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM