【问题标题】:How can I rotate 3d object using right and left arrows in Swift? (SceneKit)如何在 Swift 中使用左右箭头旋转 3d 对象? (场景套件)
【发布时间】:2021-10-15 01:03:33
【问题描述】:

如何让用户使用我在下方放置的左右箭头移动对象,而不是手动移动它?

“allowscameracontrol”允许用户用手旋转对象。但我只是希望它使用箭头旋转。 ** -> sceneView.allowsCameraControl = true**

import UIKit
import SceneKit

class ViewController: UIViewController {
    
    @IBOutlet weak var sceneView: SCNView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
       // 1: Load .obj file
        let scene = SCNScene(named: "converse_obj.obj")
        
       //Add camera node
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
       //Place camera
        cameraNode.position = SCNVector3(x: 0, y: 10, z: 35)
        //*Set camera on scene
        scene?.rootNode.addChildNode(cameraNode)
        
      //Adding light to scene
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light?.type = .omni
        lightNode.position = SCNVector3(x: 0, y: 10, z: 35)
        scene?.rootNode.addChildNode(lightNode)
        
        // 6: Creating and adding ambien light to scen
        let ambientLightNode = SCNNode()
        ambientLightNode.light = SCNLight()
        ambientLightNode.light?.type = .ambient
        ambientLightNode.light?.color = UIColor.darkGray
        scene?.rootNode.addChildNode(ambientLightNode)
        


        // Allow user to manipulate camera
        sceneView.allowsCameraControl = true
        

        
        // Set background color
        sceneView.backgroundColor = UIColor.white
        
        // Allow user translate image
        sceneView.cameraControlConfiguration.allowsTranslation = false
        
        // Set scene settings
        sceneView.scene = scene
        
    }
    
    
}

【问题讨论】:

  • 提示:CATransform3DRotate(_:_:_:_:_:)

标签: swift scenekit


【解决方案1】:

我之前没用过 SceneKit。

我不确定您是要旋转相机还是旋转包含对象的节点。从它的命名方式来看,它听起来像是allowsCameraControl 旋转相机。在任何情况下,您都可以使用rotationMatrixAroundZ 创建一个旋转矩阵,然后将其乘以该矩阵,得到您想要旋转的任何东西。

如果您想要旋转相机,您的代码可能如下所示:

func rotateCameraZByDegrees(_ zRotation: Double) {
    let radians = zRotation / 180.0 * Double.pi
    let rotationZ = rotationMatrixAroundZ(radians: radians)
    
    cameraNode.transform = SCNMatrix4(simd_mul(simd_float4x4(cameraNode.transform), rotationZ))
}

如果您想旋转对象的节点,并且对象的节点名为 sneakersNode,请将最后一行更改为:

    sneakersNode.transform = SCNMatrix4(simd_mul(simd_float4x4(sneakersNode.transform), rotationZ))

【讨论】:

  • 我认为allowsCameraControl 设置会对相机节点的变换应用旋转,就像上面的代码一样。因此,如果您愿意,您应该能够同时使用基于手指的旋转和箭头。
【解决方案2】:

stackO 中的这篇文章 [31881911] 向您展示了箭头键的一些示例。

打开allowsCameraControl = false

这篇文章 [68506605] 看到我的答案 - 创建一个相机控制类让事情变得更容易。

对于您的旋转,只需直接旋转对象 - 有几种方法可以做到这一点。

func resetRotation()
    {
        for (_, vNode) in displayNodes
        {
            vNode.node.removeAllActions()
        }
        vRotate0 = SCNAction.rotateTo(x: 0, y: 0, z: 0, duration: 2)
        vRotate1 = SCNAction.rotateBy(x: 0, y: CGFloat(GLKMathDegreesToRadians(450)), z: 0, duration: 3)
        vRotate2 = SCNAction.rotateBy(x: 0, y: CGFloat(GLKMathDegreesToRadians(-90)), z: 0, duration: 1)
        vRotate3 = SCNAction.rotateBy(x: CGFloat(GLKMathDegreesToRadians(-45)), y: 0, z: 0, duration: 1)
        vRotate4 = SCNAction.rotateBy(x: CGFloat(GLKMathDegreesToRadians(45)), y: 0, z: 0, duration: 1)
        
        seq = SCNAction.sequence([vRotate0, vRotate1, vRotate2, vRotate3, vRotate4, vRotate3, vRotate4])
        allSeq = SCNAction.repeatForever(seq)
        for (_, vNode) in displayNodes
        {
            vNode.node.runAction(allSeq)
        }
    }

您可以使用一些序列 - 因此您的对象可以进行 360 度旋转并停止,以较慢的速度返回 90 度,无论您想要什么。上面永远重复,但你可以把它拿出来。

或者只是按左键,旋转 Y += n 度。

【讨论】:

    猜你喜欢
    • 2015-09-14
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 2017-05-05
    相关资源
    最近更新 更多