2014-12-03 29 views
0

我有一個對象,在初始化期間創建一個幾何。如何在SCNNode上爲自定義屬性設置動畫效果?

class Helix { 
    var width: GLfloat  // x 
    var height: GLfloat  // y 
    var depth: GLfloat  // z 
    var radius: GLfloat 
    var pitchInherent: GLfloat 
    var pitchCurrent: GLfloat 
    /* Other SceneKit related properties used later */ 
    init(width: Float, height: Float, depth: Float) { 
     /* Geometry logic */ 
     geometry = SCNGeometry(sources: [vertexSource], elements: [element]) 
    } 
    func getNode() -> SCNNode { 
     return SCNNode(geometry: geometry) 
    } 
} 

然後在我的視圖控制器中,我將它添加到節點樹中。

let scene = SCNScene() 
let helix = Helix(width: 30, height: 30, depth: 30) 
let helixNode = helix.getNode() 
scene.rootNode.addChildNode(helixNode) 

我想動畫pitchCurrent屬性。在定製CALayer對象的世界中,我用來指定那些我想動畫的屬性爲dynamic,併爲相應的key分配了一個偵聽器。我應該如何在這方面做到這一點?

+0

我的恐懼是我可能必須重做每個幀的整個頂點數組... – 2014-12-03 21:16:04

回答

2

每幀重建一個頂點數組並不是那麼糟糕。但是,將每個幀重新上傳到GPU中可能不會導致性能提升,從而提升您的一天。

相反,我建議使用shader modifiers來在GPU的頂點階段自定義您的幾何圖形。 (請務必點擊頁面頂部的「更多」鏈接進行全面討論。)您甚至可以將此與您自定義的Helix類相結合,以便從Swift中更改寬度/半徑/間距/等參數,實現SCNShadable的SceneKit對象會自動使用KVO讓您將GLSL制服視爲類屬性。

要做到這一點,你首先需要重構,使Helix子類SCNGeometrySCNNode,然後,像在CALayer情況下,作爲dynamic聲明你的屬性。

然後,創建一個GLSL片段,做幾何定製:

// declare uniforms whose names match your class' dynamic properties 
uniform float width; 
uniform float height; 
// etc 

// do your geometry math 
_geometry.position = /* Geometry logic */ 

最後,分配該片段到shaderModifiers爲您的節點,使用SCNShaderModifierEntryPointGeometry切入點:

let shader = "all that GLSL stuff above" // or better, load it from a file 
geometry.shaderModifiers = [ SCNShaderModifierEntryPointGeometry: shader ] 

在這點,您應該能夠創建自定義Helix節點/幾何體的實例,並使用SceneKit的任何動畫技巧來爲其width,height等屬性設置動畫。

+0

這肯定會打開一個全新的領域,我需要弄清楚。我需要一段時間才能做到這一點,所以暫時,謝謝!如果需要,我會回覆更多細節:) – 2014-12-03 21:57:11

+2

請注意,您的自定義屬性不一定必須是「動態」。只是'SCNNode'和'SCNGeometry'是兼容鍵值編碼的容器類(就像'CALayer'一樣),並允許你使用KVC作爲任意鍵。 – mnuages 2014-12-04 11:02:41

相關問題