SceneKit:在父级内部垂直居中缩放SCNNode?

时间:2016-08-24 21:54:05

标签: ios scenekit scnnode

目标是缩放SCNNode并将其垂直居中于其父级。

但是,缩放SCNNode不会影响其边界框,并且计算缩放高度不起作用。如果没有准确的高度,您如何将节点垂直居中于其父节点内?

要说明使用缩放高度的问题,请参阅附件Tiki.dae。资产的原始高度(如边界框所示)为324.36。但是,如果将Y刻度设置为0.01,则高度不会变为~3.24。它变得小于3,你可以通过在高度为3(半径为1.5)的球体内舒适地拟合它来证明。

下面的代码尝试将缩放节点置于其父节点中心,但它不起作用。

注意:参考节点是WWDC 2015狐狸演示中的狐狸/熊猫参考节点。

            // Create reference node
            let referenceNode = SCNReferenceNode(URL: referenceURL)
            referenceNode?.load()

            // Scale reference node
            let scale = Float(3)
            referenceNode?.scale = SCNVector3(x: scale, y: scale, z: scale)

            // Create geometry for sphere
            let sphereGeometry = SCNSphere(radius: (gridSphere.geometry as! SCNSphere).radius)
            //sphereGeometry.materials = gridSphere.geometry!.materials
            sphereGeometry.firstMaterial!.diffuse.contents = gPurpleColor

            // Create sphere to hold reference node, position at same place as <gridSphere>
            let liveSphere = SCNNode(geometry: sphereGeometry)
            liveSphere.position = gridSphere.position

            // Center reference node inside <liveSphere>
            var min = SCNVector3Zero
            var max = SCNVector3Zero
            referenceNode?.getBoundingBoxMin(&min, max: &max)
            let referenceNodeHeight = max.y - min.y
            referenceNode?.position = SCNVector3(x: 0, y: 0 - referenceNodeHeight, z: 0)

            // Add reference node to <liveSphere>
            liveSphere.addChildNode(referenceNode!)

            // This value never changes no matter the scale value???
            print(referenceNodeHeight)

1 个答案:

答案 0 :(得分:0)

这是一个Playground,它将一个立方体(代替您的参考节点)添加为球体的子项。立方体响应缩放(请参阅“//缩放参考节点”后面的行。)

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

import Cocoa
import SceneKit
import XCPlayground

public class GizmoNode: SCNNode {

    required public override init() {
        super.init()
        let axisLength = CGFloat(3.0)
        let offset = CGFloat(axisLength/2.0)
        let axisSide = CGFloat(0.2)
        let chamferRadius = CGFloat(axisSide)

        let xBox = SCNBox(width: axisLength, height: axisSide, length: axisSide, chamferRadius: chamferRadius)
        xBox.firstMaterial?.diffuse.contents = NSColor.redColor()
        let yBox = SCNBox(width: axisSide, height: axisLength, length: axisSide, chamferRadius: chamferRadius)
        yBox.firstMaterial?.diffuse.contents = NSColor.greenColor()
        let zBox = SCNBox(width: axisSide, height: axisSide, length: axisLength, chamferRadius: chamferRadius)
        zBox.firstMaterial?.diffuse.contents = NSColor.blueColor()
        let xNode = SCNNode(geometry: xBox)
        let yNode = SCNNode(geometry: yBox)
        let zNode = SCNNode(geometry: zBox)
        self.addChildNode(xNode)
        self.addChildNode(yNode)
        self.addChildNode(zNode)
        print (xNode.position)
        print (yNode.position)
        print (zNode.position)
        xNode.position.x = offset
        yNode.position.y = offset
        zNode.position.z = offset
        print (xNode.pivot)
        print (yNode.pivot)
        print (zNode.pivot)
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

let sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
let scene = SCNScene()

sceneView.scene = scene
sceneView.backgroundColor = NSColor.blackColor()
sceneView.allowsCameraControl = true

let gizmo = GizmoNode()
scene.rootNode.addChildNode(gizmo)

XCPlaygroundPage.currentPage.liveView = sceneView

// Create reference node
let cubeSize = CGFloat(0.5)
let cubeGeometry = SCNBox(width: cubeSize, height: cubeSize, length: cubeSize, chamferRadius: 0.0)
let referenceNodeStandIn = SCNNode(geometry: cubeGeometry)
//referenceNodeStandIn?.load()
let cubeColor = NSColor.whiteColor().colorWithAlphaComponent(0.5)
cubeGeometry.firstMaterial!.diffuse.contents = cubeColor

// Scale reference node
let scale = CGFloat(8)
referenceNodeStandIn.scale = SCNVector3(x: scale, y: scale, z: scale)

// Create geometry for sphere
let sphereRadius = CGFloat(2.0)
let sphereGeometry = SCNSphere(radius: sphereRadius)
//sphereGeometry.materials = gridSphere.geometry!.materials
let gPurpleColor = NSColor.purpleColor().colorWithAlphaComponent(1.0)
sphereGeometry.firstMaterial!.diffuse.contents = gPurpleColor

// Create sphere to hold reference node, position at same place as <gridSphere>
let liveSphere = SCNNode(geometry: sphereGeometry)
//liveSphere.position = gridSphere.position
scene.rootNode.addChildNode(liveSphere)

// Center reference node inside <liveSphere>
var min = SCNVector3Zero
var max = SCNVector3Zero
referenceNodeStandIn.getBoundingBoxMin(&min, max: &max)
print("min: \(min) max: \(max)")
let referenceNodeHeight = max.y - min.y
//referenceNodeStandIn.position = SCNVector3(x: 0, y: 0 - referenceNodeHeight, z: 0)

// Add reference node to <liveSphere>
liveSphere.addChildNode(referenceNodeStandIn)

// This value never changes no matter the scale value because it's in local coordinate space
print("reference node height", referenceNodeHeight)