2016-05-16 1 views
1

私はSceneKitを初めて使うので、私がやっていることはまさに正しいアプローチではない可能性があります。だから私の一般的な意図は次のとおりです。SCNGeometryElementプリミティブに物理を追加する

私は、プレーヤーが移動する「トンネル」を構築しています。これは手続き的にトンネルを生成します。私は自分のトンネルのメッシュを表すポイントの位置を決定しています。次にポイントを三角形でつなぎ合わせてスキンにします。私は自分の三角形を生成するには、次の方法を使用しています:これは正常に動作し、私のトンネルはトンネルのように見える

func addTriangleFromPositions(scene: SCNScene, point1: SCNVector3, point2: SCNVector3, point3: SCNVector3) 
{ 
    let vector12 = GLKVector3Make(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z) 
    let vector32 = GLKVector3Make(point3.x - point2.x, point3.y - point2.y, point3.z - point2.z) 
    let normalVector = SCNVector3FromGLKVector3(GLKVector3CrossProduct(vector12, vector32)) 


    let positions: [SCNVector3] = [point1, point2, point3] 
    let normals: [SCNVector3] = [normalVector, normalVector, normalVector] 
    let indices: [Int32] = [0, 2, 1] 
    let vertexSource = SCNGeometrySource(vertices: positions, count: positions.count) 
    let normalSource = SCNGeometrySource(normals: normals, count: normals.count) 
    let indexData = NSData(bytes: indices, length: sizeof(Int32) * indices.count) 

    let element = SCNGeometryElement(data: indexData, primitiveType: .Triangles, primitiveCount: indices.count, bytesPerIndex: sizeof(Int32)) 
    let geometry = SCNGeometry(sources: [vertexSource, normalSource], elements: [element]) 

    let material = SCNMaterial() 
    material.diffuse.contents = UIColor(red: 41.0/256.0, green: 16.0/256.0, blue: 0, alpha: 1) 

    geometry.materials = [material] 
    let node = SCNNode(geometry: geometry) 
    scene.rootNode.addChildNode(node) 
} 

。しかし、自分のノードにPhysicsBodyを追加して静的なボディにすると(トンネルにクラッシュする可能性がありますが、トンネルの壁は動かない)、私のアプリケーションはEXC_BAD_ADDRESSでクラッシュし始めます。私は最初のいくつかの三角形を追加した後に実際にクラッシュするので、このようにいくつかの三角形を追加するときに発生する問題があると思われます。

これをテストするために、テストプロジェクトを作成し、ただ1つの三角形を追加し、そのPhysicsBodyを静的ボディに設定します。それはクラッシュしませんが、私の三角形の形を取るのではなく、物理的なボディが起点の単一点に見えます。

ので、いくつかの質問:

  1. これは、カスタムジオメトリを生成するために、一般的には、悪い方法ですか?私が本当に幾分不規則な形をしたいと思っていて、それにPhysicsBodyを持たせたいのであれば、ポイントを接続するための三角形を作る以外の方法がありますか?
  2. 私の三角形のフィジックスボディを作成する理由は何ですか?

ありがとうございます。

答えて

4

SceneKitはカスタムジオメトリのためにphysics shapeを作成することに注意することが重要です。この物理形状は、ではなく、は作成したメッシュと同じジオメトリを持ちますが、デフォルトではメッシュの外側に凸包を作成しています。私の推測では、凸包アルゴリズムは、ノーマルが内側に向いている(?)トンネルメッシュでは機能しない可能性があります。しかし、それがうまくいったとしても、トンネルの外側の周りにはメッシュがついてしまうので、そこを飛行することはできません。

SCNPhysicsShapeを作成してSCNPhysicsShapeTypeConcavePolyhedronを指定する場合は、SCNPhysicsShapeTypeKeyを使用することが考えられます。このアプローチをとっているなら、トンネルをその周りのセグメントとその長さに沿って分割することもお勧めします。

Tube segmentation

この理由はたくさんあります。視野錐台の外にあるときにセグメント全体(ノード)がSceneKitによってカリングされるので、レンダリングのパフォーマンスに役立つはずです。衝突検出のパフォーマンスに役立つはずです(SceneKitはメッシュベースの衝突をチェックする前にバウンディングボックスチェックを行います)生成アルゴリズムが機能するはずです。

トンネルを表すいくつかのジオメトリプリミティブ(SCNSphereSCNBoxなど)を生成し、複数のシェイプで構成されるSCNPhysicsShapeを作成することもできます。これは手続き的に生成された島の周りにシェイプを構築する方法です。各灰色のボックスはSCNBoxです。

enter image description here

SceneKitはかなり親切適切なデバッグオプションをオンにして、すべての物理形状が表示されます(おそらくメタルのみ)。例えば; scenekitView.debugOptions = SCNDebugOptions.ShowPhysicsShapes

SCNGeometryを生成する方法に何も問題はありません。特にメッシュに多数の三角形がある場合は、注意する必要があります。

希望します。

+0

ありがとうございます。あなたの島は素晴らしいようです。私はトンネルがコンセプトに似ていることを想像しました。キャラクターがあなたの島を歩き回ることができるようにすることが目標だったとしましょう。すべてのポリゴンが歩いていくための硬いサーフェスだったようです。おそらく、ポリゴンごとに物理学のボディを作成するのは計算コストが高すぎます。これは私がそれに近づく方法でした。代わりに、ポリゴン自体が物理的なボディに近似するように、あなたの島のいくつかのセクションの曲率におおよそ一致するSCNPhysicsShapeTypeConcavePolyhedronボディの束を作成しますか? – Dan

+0

TBH私は、あなたが当初提案したのと同じように、自分のメッシュを 'SCNPhysicsShape'に提供する方法が本当に好きです。 SceneKitの開発者は、多量のポリゴンで接触検出を遅らせる可能性を減らしたかったと思います。ポリゴンごとに物理シェイプを作成すると、表示しようとしているポリゴンよりも接触ポリゴンの多い物理シェイプになります。かなり正確な結果が必要なので、何かを歩くのは難しいです。私は 'SCNPhysicsShapeTypeConcavePolyhedron'があなたの最高のショットだと思っています。あなたのジオメトリをどのようにラップするかをほとんど制御できないことに気をつけてください。 – lock

関連する問題