菜鸟教程小白 发表于 2022-12-11 20:00:56

iOS ARKit + SceneKit 物理接触检测缩放问题


                                            <p><p>我有一个简单的 3d 区域,其中包含 4 面墙,每面都是一个 SCNNode,具有简单的 SCNBox 几何形状、矩形形状,并附有匹配的 SCNPhysicsBody。 SCNPhysicsBody 使用 SCNPhysicsShape.ShapeType.boundingBox,并设置为静态类型。这是一个代码片段:</p>

<pre><code>      let size = (self.levelNode.boundingBox.max - self.levelNode.boundingBox.min) * self.levelNode.scale

      //x //z
      let geometryA = SCNBox(width: CGFloat(size.x), height: CGFloat(1 * self.levelNode.scale.x), length: 0.01, chamferRadius: 0)
      let geometryB = SCNBox(width: CGFloat(size.z), height: CGFloat(1 * self.levelNode.scale.x), length: 0.01, chamferRadius: 0)

      geometryA.firstMaterial?.diffuse.contents = UIColor(red: 0.0, green: 0.2, blue: 1.0, alpha: 0.65)
      geometryB.firstMaterial?.diffuse.contents = UIColor(red: 0.0, green: 0.2, blue: 1.0, alpha: 0.65)


      let nodeA = SCNNode(geometry: geometryA)
      nodeA.position += self.levelNode.position
      nodeA.position += SCNVector3(0, 0.25 * self.levelNode.scale.y, -size.z/2)
      nodeA.name = &#34;Boundary-01&#34;

      let nodeB = SCNNode(geometry: geometryA)
      nodeB.position += self.levelNode.position
      nodeB.position += SCNVector3(0, 0.25 * self.levelNode.scale.y, size.z/2)
      nodeB.name = &#34;Boundary-03&#34;

      let nodeC = SCNNode(geometry: geometryB)
      nodeC.position += self.levelNode.position
      nodeC.position += SCNVector3(-size.x/2, 0.25 * self.levelNode.scale.y, 0)
      nodeC.eulerAngles = SCNVector3(0, -Float.pi/2, 0)
      nodeC.name = &#34;Boundary-02&#34;

      let nodeD = SCNNode(geometry: geometryB)
      nodeD.position += self.levelNode.position
      nodeD.position += SCNVector3(size.x/2, 0.25 * self.levelNode.scale.y, 0)
      nodeD.eulerAngles = SCNVector3(0, Float.pi/2, 0)
      nodeD.name = &#34;Boundary-04&#34;

      let nodes =

      for node in nodes {
            //
            let shape = SCNPhysicsShape(geometry: node.geometry!, options: [
                SCNPhysicsShape.Option.type : SCNPhysicsShape.ShapeType.boundingBox])
            let body = SCNPhysicsBody(type: .static, shape: shape)
            node.physicsBody = body
            node.physicsBody?.isAffectedByGravity = false
            node.physicsBody?.categoryBitMask = Bitmask.boundary.rawValue
            node.physicsBody?.contactTestBitMask = Bitmask.edge.rawValue
            node.physicsBody?.collisionBitMask = 0

            scene.rootNode.addChildNode(node)
            node.physicsBody?.resetTransform()
      }
</code></pre>

<p>在这个区域内,我会定期生成实体。每个都有一个 SCNBox 几何体,这次是立方体形状,比墙壁小,物理体的参数与上述相同。</p>

<p>为了简化我的实体在该游戏区域内的行为,我正在计算它们的行进路径,然后将 SCNAction 应用于相关节点以移动它们。 SCNAction 移动节点和附加到它的物理体。</p>

<p>我正在使用 SCNPhysicsWorld 联系人代理来检测实体何时到达边界墙之一。然后我从那堵墙上计算出它在另一个方向上的随机轨迹,清除它的 Action ,并应用一个新的移动 SCNAction。 </p>

<p>这就是有趣的地方......</p>

<p>当这个“世界”的比例为 1:1 时。在标准 SCNScene 和使用 ARKit 投影的场景中,接触都被检测为正常。可见接触,即实体方向的可见变化似乎与预期的一样接近边界。当我检查每个联系人的contact.penetrationDistance时,它们的值是例如0.00294602662324905.</p>

<p>但是,当我在 ARKit 中将这个“世界”的比例更改为更小,比如相当于 10 厘米宽时,模拟就会崩溃。 </p>

<p>实体和边界节点之间的接触在检测到接触时,它们之间存在较大的可见间隙。然而,contact.penetrationDistance 的大小与以前相同。</p>

<p>我打开了 ARSCNView 调试选项以在渲染中显示物理形状,它们看起来都是正确的比例,与它们节点的边界框相匹配。</p>

<p>从上面的代码示例中可以看出,边界节点是在我缩放关卡后生成的,在我的 AR 用户设置过程中。它们被添加到场景的根节点,而不是作为关卡节点的子节点。相同的代码被用于生成实体。</p>

<p>之前我曾尝试在物理体上使用 resetTransform() 函数,但是在我缩放关卡后,这并没有产生可靠的物理体缩放,所以我决定在之后生成边界和实体的节点水平已被缩放。 </p>

<p>在 Apple 的文档中,确实声明如果 SCNPhysicsBody 不是自定义形状,它将采用应用于它的节点几何图形的比例。我不会受此影响,因为在将缩放应用到关卡之后,我正在生成几何图形及其各自的节点。 </p>

<p>目前的一个假设是物理模拟在如此小的范围内分崩离析。但我不是依靠模拟力来移动 body ......</p>

<p>有没有更合适的方式来扩展物理世界? </p>

<p>或者,我是否正在盯着 SCNPhysicsWorld 中的错误,目前这是我无法控制的。 </p>

<p>我确实考虑过的一个解决方案是以 1:1 的比例运行整个模拟但隐藏起来,然后将这些运动应用于较小的实体。可以想象,那会影响整个场景的表现……</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>第一次接触的穿透距离为负值,表示存在间隙。当您按比例缩小模拟大小时,此差距似乎不会按比例缩小。 </p>

<p>作为解决上述过量问题的一种方法,我在 Contact Delegate 中对联系人进行了额外检查,以不获取为特定类别检测到的第一个联系人,而是确保穿透距离值为正,因此确保存在是两个对象之间的重叠,然后触发与边界连接的实体的方向变化。 </p></p>
                                   
                                                <p style="font-size: 20px;">关于iOS ARKit &#43; SceneKit 物理接触检测缩放问题,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/49771646/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/49771646/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: iOS ARKit &#43; SceneKit 物理接触检测缩放问题