Swift SceneKit SCNP物理车轮指向车辆中心

Swift SceneKit SCNP物理车轮指向车辆中心,swift,scenekit,Swift,Scenekit,我正在尝试使用Swift 2以及场景编辑器和.scnassets使SceneKit Physical Vehicle工作。我正在适应 我还尝试了一些模型I/O功能,比如SkyBox和法线贴图生成 一切正常,除了车轮绕转向轴旋转180度,以便轮毂盖指向汽车中心: 指向内部的轮毂盖 车轮朝着正确的方向旋转,汽车可以很好地驾驶和操控,但它看起来很奇怪(而且左右轴距比它应该的要窄) 如果我注释掉SCNPhysicsVehicle和SCNPhysicsVehicle车轮代码,使其仅为带有底盘物理主体的几

我正在尝试使用Swift 2以及场景编辑器和.scnassets使SceneKit Physical Vehicle工作。我正在适应

我还尝试了一些模型I/O功能,比如SkyBox和法线贴图生成

一切正常,除了车轮绕转向轴旋转180度,以便轮毂盖指向汽车中心:

指向内部的轮毂盖

车轮朝着正确的方向旋转,汽车可以很好地驾驶和操控,但它看起来很奇怪(而且左右轴距比它应该的要窄)

如果我注释掉SCNPhysicsVehicle和SCNPhysicsVehicle车轮代码,使其仅为带有底盘物理主体的几何图形,几何图形将正确显示,轮毂指向外侧:

轮毂盖指向外侧

在定义SCNPhysicsVehicleWheel之前,我尝试使用
wheelnode0.rotation
旋转wheelnodes,但没有效果

我试着用
wheel0.axex=scinvector3(x:1,y:0,z:0)
反转轮轴,这使车轮朝向正确的方向,轮毂向外(它们仍然以正确的方向旋转),但汽车向后移动(即与车轮旋转方向相反)

感觉轴的平移方式有些奇怪,但我不知道是什么。我试过使用Apple演示版中的原始.dae模型,并将其转换为.scn文件。我在.scnassets文件夹内外都尝试过它(以防它与上轴的scnassets自动校正有关)。我试着反转方向盘的方向轴,但结果只是方向盘指向空中

这是我的车辆创建功能,以及我尝试过的所有东西。此处为完整回购:。有人能看到这里出了什么问题吗?提前谢谢

func setupCar() -> SCNNode {
    let carScene = SCNScene(named: "art.scnassets/rc_car.scn") //rc_car.dae
    let chassisNode = carScene!.rootNode.childNodeWithName("rccarBody", recursively: true)!
    chassisNode.position = SCNVector3Make(0, 10, 30)
    //chassisNode.rotation = SCNVector4(0, 1, 0, CGFloat(M_PI))
    let body = SCNPhysicsBody.dynamicBody()
    body.allowsResting = false
    body.mass = 80
    body.restitution = 0.1
    body.friction = 0.5
    body.rollingFriction = 0
    chassisNode.physicsBody = body
    scnScene.rootNode.addChildNode(chassisNode)
     //getNode("rccarBody", fromDaePath: "rc_car.dae")
    let wheelnode0 = chassisNode
        .childNodeWithName("wheelLocator_FL", recursively: true)!
    let wheelnode1 = chassisNode
        .childNodeWithName("wheelLocator_FR", recursively: true)!
    let wheelnode2 = chassisNode
        .childNodeWithName("wheelLocator_RL", recursively: true)!
    let wheelnode3 = chassisNode
        .childNodeWithName("wheelLocator_RR", recursively: true)!

    //wheelnode0.geometry!.firstMaterial!.emission.contents = UIColor.blueColor()
    //        SCNTransaction.begin()
    //        wheelnode0.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(M_PI)) //CGFloat(M_PI)
    //        wheelnode1.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(M_PI))
    //        wheelnode2.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(M_PI))
    //        wheelnode3.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(M_PI))
    //        SCNTransaction.commit()
    //        wheelnode0.eulerAngles = SCNVector3Make(0, Float(M_PI), 0 )
    let wheel0 = SCNPhysicsVehicleWheel(node: wheelnode0)
    let wheel1 = SCNPhysicsVehicleWheel(node: wheelnode1)
    let wheel2 = SCNPhysicsVehicleWheel(node: wheelnode2)
    let wheel3 = SCNPhysicsVehicleWheel(node: wheelnode3)
    //        wheel0.steeringAxis = SCNVector3Make(0, -1, 1) //wheels point up in the air with 0,1,0
    //        wheel1.steeringAxis = SCNVector3Make(0, -1, 1)
    //        wheel2.steeringAxis = SCNVector3Make(0, -1, 1)
    //        wheel3.steeringAxis = SCNVector3Make(0, -1, 1)
    //        
    //        wheel0.axle = SCNVector3(x: 1,y: 0,z: 0) //wheels face and spin the right way, but car moves in opposite direction with 1,0,0
    //        wheel1.axle = SCNVector3(x: 1,y: 0,z: 0)
    //        wheel2.axle = SCNVector3(x: 1,y: 0,z: 0)
    //        wheel3.axle = SCNVector3(x: 1,y: 0,z: 0)
           // wheel0.steeringAxis = SCNVector3()
    //        var min = SCNVector3(x: 0, y: 0, z: 0)
    //        var max = SCNVector3(x: 0, y: 0, z: 0)
    //        wheelnode0.getBoundingBoxMin(&min, max: &max)
    //        let wheelHalfWidth = Float(0.5 * (max.x - min.x))
    //        var w0 = wheelnode0.convertPosition(SCNVector3Zero, toNode: chassisNode)
    //        w0 = w0 + SCNVector3Make(wheelHalfWidth, 0, 0)
    //        wheel0.connectionPosition = w0
    //        var w1 = wheelnode1.convertPosition(SCNVector3Zero, toNode: chassisNode)
    //        w1 = w1 - SCNVector3Make(wheelHalfWidth, 0, 0)
    //        wheel1.connectionPosition = w1
    //        var w2 = wheelnode2.convertPosition(SCNVector3Zero, toNode: chassisNode)
    //        w2 = w2 + SCNVector3Make(wheelHalfWidth, 0, 0)
    //        wheel2.connectionPosition = w2
    //        var w3 = wheelnode3.convertPosition(SCNVector3Zero, toNode: chassisNode)
    //        w3 = w3 - SCNVector3Make(wheelHalfWidth, 0, 0)
    //        wheel3.connectionPosition = w3

    vehicle = SCNPhysicsVehicle(chassisBody: chassisNode.physicsBody!,
                                wheels: [wheel0, wheel1, wheel2, wheel3])
    scnScene.physicsWorld.addBehavior(vehicle)
    return chassisNode

}
我找到了一个解决方案: (但不是我所希望的解决方案)

我的解决方案是调整“FrontLeftWheel”的连接位置,使其向右移动,从而起到了“FrontRightWheel”的作用。
和“FrontRightWheel”,如此向左,以至于它扮演了“FrontLeftWheel”的角色。
我也为背部做了这个。

基本上,你有:

SCNVector3Make(wheelHalfWidth, 0, 0)
我将其替换为:

SCNVector3Make(wheelHalfWidth * 5.2, 0, 0)
但是,您可能需要摆弄数字“5.2”来匹配您的衣领(.dae)

注: 不要忘记更换:

 vehicle = SCNPhysicsVehicle(chassisBody: chassisNode.physicsBody!,
                            wheels: [wheel0, wheel1, wheel2, wheel3])
与:


这样,当您使用car.wheels[0]时,
您得到了您期望的车轮

我认为您的问题在于您没有设置每个车轮的连接位置。苹果默认的Objective代码很难翻译成swift

wheel0.connectionPosition = SCNVector3FromFloat3(SCNVector3ToFloat3([wheel0Node convertPosition:SCNVector3Zero toNode:chassisNode]) + (vector_float3){wheelHalfWidth, 0.0, 0.0});
wheel1.connectionPosition = SCNVector3FromFloat3(SCNVector3ToFloat3([wheel1Node convertPosition:SCNVector3Zero toNode:chassisNode]) - (vector_float3){wheelHalfWidth, 0.0, 0.0});
wheel2.connectionPosition = SCNVector3FromFloat3(SCNVector3ToFloat3([wheel2Node convertPosition:SCNVector3Zero toNode:chassisNode]) + (vector_float3){wheelHalfWidth, 0.0, 0.0});
wheel3.connectionPosition = SCNVector3FromFloat3(SCNVector3ToFloat3([wheel3Node convertPosition:SCNVector3Zero toNode:chassisNode]) - (vector_float3){wheelHalfWidth, 0.0, 0.0});
这四行翻译(忽略重复)

通过添加或减去向量_float3,车轮定位在正确的位置


另外,请记住,您不能缩放场景中的节点,否则可能会发生奇怪的事情。

遇到同样的问题,我的解决方案是旋转所有轮子节点,使Y轴指向下方。我认为重力是一种向下的力。

。但我无法让它工作,因为它与Swift 2有太多不兼容之处。这是我的回复:事实上,当我启动演示的原始Objective C版本时,它的轮毂盖也指向内部-(我仍然想知道,当您将节点定义为SCNPhysicsVehicleWheel时,为什么轮子的几何体会像这样旋转。谢谢!我确实想知道“轮毂帽是否指向”这是因为车轮被调换成圆形,所以我将左前轮涂成蓝色,以确保它仍然处于左前位置。有一件事,你确定你不是指“-5.2”?我还试着将车轮抬起。我发现车辆左侧的“up”为负Y
SCInvector3Make(wheelHalfWidth*-5.2,-wheelHalfWidth,0)
,而在右侧它是正Y。这是一个棍棒,但似乎可以工作,车辆是可驾驶和可操纵的(现在有了更宽的轴距)。我将此标记为公认的答案,尽管对我来说是“-5.2”。Repo已更新。感谢专业爆破师!
wheel0.connectionPosition = SCNVector3FromFloat3(SCNVector3ToFloat3([wheel0Node convertPosition:SCNVector3Zero toNode:chassisNode]) + (vector_float3){wheelHalfWidth, 0.0, 0.0});
wheel1.connectionPosition = SCNVector3FromFloat3(SCNVector3ToFloat3([wheel1Node convertPosition:SCNVector3Zero toNode:chassisNode]) - (vector_float3){wheelHalfWidth, 0.0, 0.0});
wheel2.connectionPosition = SCNVector3FromFloat3(SCNVector3ToFloat3([wheel2Node convertPosition:SCNVector3Zero toNode:chassisNode]) + (vector_float3){wheelHalfWidth, 0.0, 0.0});
wheel3.connectionPosition = SCNVector3FromFloat3(SCNVector3ToFloat3([wheel3Node convertPosition:SCNVector3Zero toNode:chassisNode]) - (vector_float3){wheelHalfWidth, 0.0, 0.0});
let wheel0Position = wheel0Node.convertPosition(SCNVector3Zero, to: chassisNode)
let vector0Float3 = vector_float3(wheel0Position.x, wheel0Position.y, wheel0Position.z) + vector_float3(wheelHalfWidth, 0,0)
wheel0.connectionPosition = SCNVector3(vector0Float3.x, vector0Float3.y, vector0Float3.z)

let wheel1Position = wheel1Node.convertPosition(SCNVector3Zero, to: chassisNode)
let vector1Float3 = vector_float3(wheel1Position.x, wheel1Position.y, wheel1Position.z) - vector_float3(wheelHalfWidth, 0,0)
wheel1.connectionPosition = SCNVector3(vector1Float3.x, vector1Float3.y, vector1Float3.z)

let wheel2Position = wheel2Node.convertPosition(SCNVector3Zero, to: chassisNode)
let vector2Float3 = vector_float3(wheel2Position.x, wheel2Position.y, wheel2Position.z) + vector_float3(wheelHalfWidth, 0,0)
wheel2.connectionPosition = SCNVector3(vector2Float3.x, vector2Float3.y, vector2Float3.z)

let wheel3Position = wheel3Node.convertPosition(SCNVector3Zero, to: chassisNode)
let vector3Float3 = vector_float3(wheel3Position.x, wheel3Position.y, wheel3Position.z) - vector_float3(wheelHalfWidth, 0,0)
wheel3.connectionPosition = SCNVector3(vector3Float3.x, vector3Float3.y, vector3Float3.z)