2017-12-28 80 views
2

私は拡張現実のiPhoneアプリケーションを構築しており、大量のSceneKitノードをレンダリングする必要があります。私は、デザインパターンに記載されているFlyweightデザインパターンをGamma、Helm、Johnson、およびVlissidesで統合したいと考えています。またチュートリアルここFlyweight Design Pattern しかし、私は実装の問題とスウィフトがオブジェクトを処理する方法に問題があります。Swift SceneKitを使用したフライウェイトデザインパターン。オブジェクトリユース

TL; DR:は、私は何度もARSCNView以上に同じSCNNodeを追加し、それは異なる位置に表示することができスウィフトにおける方法はありますか?

Boxというクラスがあり、フライウェイトを利用したいSCNBoxをビルドしています。 本来の状態Boxの寸法です。 外的状態はその色と位置です。

ボックスクラス

class Box { 
    var size:CGFloat 
    var position:(Float, Float, Float) 
    var color:UIColor 
    var node:SCNNode! 

    init(color:UIColor){ 
     self.color = color 
     /*Set the following below as default values*/ 
     self.size = CGFloat(0.05) //Side length 
     self.position = (0,0,0) 
     self.createBox() 
    } 

    private func createBox() -> Void { 
     /*Creating box and setting its color*/ 
     self.node = SCNNode(geometry: SCNBox(width: size, height: size, length: size, chamferRadius: 0)) 
     self.node.geometry?.firstMaterial?.diffuse.contents = self.color 
    } 

    func draw(sceneView: ARSCNView) -> Void { 
     sceneView.scene.rootNode.addChildNode(self.node) 
    } 
} 

私はそうオブジェクトを再利用する場合は、同じ色の前のオブジェクトは、他の新しいものを作成するかどうかをチェック辞書とデザインを実装するファクトリクラスを持っています。ボックスを表示するARSCNViewオブジェクトを保持

ファクトリクラス

class BoxFactory{ 
    var hash:[UIColor:Box] = [UIColor:Box]() 
    func getBox(color c:UIColor) -> Box { 
     /*Check if box of color c already exists*/ 
     if(self.hash[c] != nil){ 
      return self.hash[c]! 
     } 
     /*Create a new box if it does not*/ 
     let b:Box = Box(color: c) 
     self.hash[c] = b 
     return b 
    } 
} 

そして、いくつかのビューコントローラ。

let factory:BoxFactory = BoxFactory() 

/*Create two boxes of same color. One on the left and on the right*/ 
let leftBox:Box = factory.getBox(color: UIColor.green) 
leftBox.position = SCNVector3(-0.1,0,0) 
leftBox.draw(sceneView: self.sceneView) 

let rightBox:Box = factory.getBox(color: UIColor.green) 
rightBox.position = SCNVector3(0.1,0,0) 
rightBox.draw(sceneView: self.sceneView) 

ただし、1つの緑色のボックスのみが生成されます。右のもの2番目のgetBox()コールは、最初の位置の下の画像を上書きします。誰かが、このパターンの実装、またはスウィフト、オブジェクトの再利用のこのパターンを達成するのに役立つことができる任意のアドバイスを持っていますか?

*サイドノートオブジェクトの位置を色とともにハッシュする必要はありません。私は多くのBoxの色とポジションを持っているので、同じオブジェクトを再利用するという考え全体を打ち破ります。

Only one green box

+0

私はこれについてお手伝いできると思いますが、私はいくつかのことを知る必要があります。ボックスにはライフサイクルがありますか?それは "削除"されるか、アプリの終わりまで持続するでしょうか? –

+0

@AndreaMugnaini一部のボックスは実行時に削除され、一部は最後まで存続します。これは、ユーザーがボックスと対話するかどうかによって異なります。 – Miket25

+1

あなたのボックスは同時に表示されるので、 'clone()'や 'flattenedClone()'を使うべきです:https://developer.apple.com/documentation/scenekit/scnnode/1408046-clone https ://developer.apple.com/documentation/scenekit/scnnode/1407960-flattenedclone –

答えて

1

SceneKitはすでにあなたのためにそれを処理します。ジオメトリのメッシュを自動的にキャッシュして、ジオメトリ間で効率的に再利用できるようにします。ジオメトリ間でマテリアルを共有することもできます。同じシェーダにつながる重複したマテリアルがあると、SceneKitはそのシェーダを1度だけコンパイルします。

+0

興味深いことに、参考にしてください。 – Miket25

+0

https://developer.apple.com/documentation/scenekit/scnnode/1408046-clone – Xartec

関連する問題