爲了讓初學者有更加直觀的初步的瞭解,筆者提供了一個簡單的示意圖以下:
實際開發中,由設計人員提供對應的spine編輯器所導出的動畫素材,開發人員選用對應的spine運行庫對素材進行消費和上屏渲渲染,即是spine所作的事,相比gif、css幀動畫、apng具有更增強大的靈活性。css
簡單比較以下:web
類型\項 | 顏色 | 大小 | 兼容性 | 靈活性 | 成本 |
---|---|---|---|---|---|
GIF | 256色 | 小 | 優 | 差 | 低 |
CSS幀動畫 | 真彩 | 較大 | 優 | 通常 | 低 |
APNG | 真彩 | 小 | 部分瀏覽器兼容 | 差 | 低 |
spine2D動畫 | 真彩 | 大(動畫素材+運行庫引入) | 優 | 較優 | 高 |
GIF因爲其自己的色彩限制,通常不能知足設計的要求,所以目前大多采用CSS幀動畫和APNG的方式處理頁面動畫,小區域動畫採用apng,大區域動畫能夠考慮採用CSS幀動畫或JS動畫處理。而釐米秀這裏因爲業務自己複雜且形象裝扮多變,故不得不採用spine2D動畫的方案。json
註釋:canvas
1)、JSON文件/二進制文件:存儲骨架信息,見下文介紹。瀏覽器
2)、素材圖片:相似雪碧圖,也可單一素材,可導出一張或多張。架構
3)、與素材圖片對應的atlas文件:記錄素材圖片在雪碧圖上的位置信息特徵等。一個atlas文件可對應多個素材圖片。app
一、骨架Skeleton:指代的是數據的集合,包含構成此骨架的全部骨骼、插槽、附件及其餘信息。編輯器
二、骨骼bones:以官方示意圖爲例,一我的物自己由多個關節的骨骼組成。除了根骨骼之外,每一個骨骼都有對應的父骨骼,骨骼與骨骼之間的關係最終構形成相似樹的結構。函數
三、插槽slot:一個骨骼bone下可能有多個slot插槽,每一個slot插槽下能夠放置一個附件實例。插槽自己的存在有兩個重要的意義,一個是靈活的控制渲染順序,一個是分組同類附件。一個插槽能夠有多個附件,但一次只能看到一個。舉個簡單的栗子,圖中手槍所在的位置的插槽是"武器"插槽,而該插槽能夠放置不一樣的武器附件,例如"手槍"附件或"菜刀"附件。動畫
四、附件attachment:slot插槽內當前渲染的附件實例,即真實上屏渲染的實物素材。(可能須要對素材作旋轉、偏移、縮放甚至網格化mesh處理)。
五、皮膚skin:skin能夠看作是attachment的集合,或者能夠認爲是attachment的一個映射查詢表,一我的物能夠由多套skin,經過切換skin的方式去查詢不一樣的附件映射表,即可以變相的實現人物的全身換裝。
其餘相關概念:
關鍵幀:
在編輯器中,動畫是藉助關鍵幀完成的,從開始到結束的過渡動畫,由spine補間處理。
權重與網格:
權重用於將網格頂點綁定到一個或多個骨骼。變換骨骼時,頂點也會隨之變換。權重令網格可以隨着操縱骨骼而自動變形,從而讓本來複雜的網格變形動畫變得與骨骼動畫同樣簡單。
附件類型:
一、區域附件:普通的圖片展現附件。
二、點附件:空間中的一個點和旋轉,相比骨頭的優點能夠爲不一樣的皮膚設置更改位置和旋轉,例如不一樣的槍從不一樣的位置射擊。
三、網格附件:支持在圖片內設置多邊形,以後可操縱多邊形的頂點,以有效的方式讓圖片彎曲和變形。
四、邊界框附件:附加到骨骼上的多邊形,骨骼變化的時候也會隨之變形,可用於撞擊檢測,建立物理主體等。
五、剪裁附件:剪裁功能讓你能夠定義一個多邊形區域,與邊界框附件相似,它會屏蔽繪製順序中的其餘插槽。
六、路徑附件:用於設置路徑。
其中在業務中比較經常使用到的是區域附件和網格附件。
三種約束:
一、IK約束:反向動力學約束 子骨頭終點固定的場景。
二、變換約束:變換約束指的是將對骨骼的世界旋轉、移動縮放等複製到多個骨骼上。
三、路徑約束:使用路徑來調整骨骼變換,骨骼能夠沿着路徑,也能夠調整旋轉以指向路徑。
spine總體架構分層以下:
spine核心類以下:
讀懂上面這張官方所提供的類圖,將會對spine的總體架構設計有更加明確的瞭解和認識。
一、Loading模塊:是針對資源加載的處理,一個spine形象的骨架信息導出後,通常會導出爲json或者二進制文件的形式,因爲json形式純文本文件過大,因此官方提供了二進制文件導出的形式,而且輔以運行庫的代碼針對二進制文件進行解析。其次,Loading模塊中的atlasAttachmentLoader將會負責atlas文件的解析,因爲atlas文件自己是字符串的形式,內部包含雪碧圖中素材的位置信息,因此須要解析後與素材創建」關聯關係「。例如:Eyes-close素材在picture1.png圖片中的x,y位置 旋轉角度爲z,而構造出來的這種映射關係將用於被實例化attachment的時候消費。
二、Spine Texture Atlas模塊:一張素材圖映射一個atlasPage,一張素材圖中的某個區域塊映射一個atlasRegion,而region的詳細繪製信息本質上已經在上個模塊完成。
三、Rending模塊:由渲染層遍歷slot進行渲染,這裏不作詳解,渲染層並不是spine核心庫所負責的部分,上屏渲染能夠由canvas、webGL或者其餘第三方渲染庫渲染,例如pixijs。
四、SetupPoseData模塊:或者稱之爲SkeletonData模塊,數據源從這裏輸入進行處理,可是並非最終數據,能夠理解爲這裏對數據作了一層預處理,會將骨骼數據先處理爲boneData,插槽數據處理爲slotData,固然也有部分數據不須要被再次處理,在這裏,也會根據前面生成的atlasRegion去構造出對應的附件實例,存儲進skin中,skin本質上爲附件映射表。
其次,數據對象自己和實例對象是有差異的。
數據對象是無狀態的,可在任意數量的骨架實例間共用。有對應實例數據的數據對象類名稱以「Data」結尾,沒有對應實例數據的數據對象則沒有後綴,如附件、皮膚及動畫。
實例對象有許多屬性與數據對象相同。數據對象中的屬性表明裝配姿式,一般不會改動。實例對象中的相同屬性表示播放動畫時該實例的當前姿式。每一個實例對象保有一個其數據對象參考,用於將實例對象重置回裝配姿式。
例如,SkeletonData是數據對象,而Skeleton是實例對象。
五、Instance Data模塊:或者稱之爲Skeleton模塊,Skeleton實例自己是渲染層上屏渲染的真實直接數據源,渲染層將讀取Skeleton實例上的插槽信息,渲染對應的附件,在這裏,許多數據對象已經被處理成對應的實例對象,例如boneData已經被處理爲Bone實例,slotData已經被處理爲Slot實例;其次,如圖中所展現的,Skeleton實例中有兩個比較關鍵的方法,updateWorldTransform和setToSetUpPose。
updateWorldTransform爲更新世界變換,本質是觸發骨骼位置的計算,因爲骨骼位置可能發生旋轉偏移,其對應的子骨骼也會受到影響,所以須要更新世界變換從新計算全部骨骼的最新座標位置。
setToSetUpPose爲更新實例到當前初始狀態,通常才初始化時或重置人物狀態時調用,會將人物形象骨骼裝扮等切換爲初始最初的狀態。
六、Animation模塊:動畫模塊被單獨抽離,不只更方便維護和更新實例的狀態信息,總體架構邏輯也簡潔明瞭,由動畫state實例去觸發skeleton實例的更新,接下來skeleton實例調用updateWorldTransform更新世界變化,以後從新上屏渲染。
一個動畫實例中由多個timeline構成,這些timeline實例來自於不一樣的變種Timeline類,根本上都繼承與底層的TimeLine類,因爲一個動畫過程當中可能涉及多種變化,所以須要對不一樣的動畫進行劃分區別,處理旋轉的單獨一條timeline,處理縮放的單獨一條timeline,等等。而雖然不一樣類別動畫會抽離成不一樣的timeline,可是最終某個時間節點生效觸發,全部的timeline"做用"都是同時的。
一、Slot:存儲插槽的當前姿式。插槽爲{@link Skeleton#drawOrder}目的組織附件,並提供存儲附件狀態的位置。狀態不能存儲在附件自己中,由於附件是無狀態的,能夠跨多個骨架共享。
(deform屬性是針對mesh附件的處理信息。)
(經過setToSetUpPose設置初始動做)
(在slot實例裏能夠直接getAttachment和setAttachment)
二、SlotData:slot實例裏用的數據的數據格式,包含index、插槽名稱、附件名稱、boneData等。
三、BoneData:骨頭實例裏用的數據格式,包含index(骨頭也有index)、骨頭名稱、父骨頭數據、骨頭本地轉換數據、世界轉換的模式。
四、Bone:關鍵方法updateWorldTransformWith,更新骨骼的世界座標。包含其餘的一些方法,世界座標和本地座標的轉換,旋轉轉換等。
五、SkeletonData: Skeleton實例對應的數據格式。包含bones、slots、skins、events、animations、各類約束。提供了
因爲是數據對象,僅提供了一些findbone、findslot的方法。
六、Skeleton:根據data新建Bone和Slot。bone有index按順序創建關聯關係。調用setToSetupPose將bone和slot設置到初始位置。會遍歷調用bone和slot對應的方法。updateWorldTransform調用bone的updateWorldTransform更新骨骼位置。提供了一些Bone、slot、attachment的get、set方法。
有個update方法,更新time時間。
七、SkeletonBinary:用於讀取二進制的skeleton文件。
八、SkeletonBounds:收集每一個可見的BoundingBoxAttachment,並計算其多邊形的世界頂點。主要用於碰撞或者命中檢測。由渲染層調用。
九、SkeletonCilpping:主要針對ClippingAttachment的處理,由渲染層調用。
十、SkeletonJson:用於解析處理spine導出的skeleton json。須要對應傳入一個attachmentLoader讓其能構造對應的attachment實例,處理bone、slots、ik、skins、animation等數據。
處理bone和slot構造對應的實例data。
處理skins藉助loader生成對應附件實例。
處理 animations生成不一樣的timeline實例對象。
最終構造出對應的SkeletonData實例。
十一、Skin:一套皮膚下的全部attachment都在skin實例下,提供了操做skin和attachment的方法。這裏操做的方法至關於dictionary,不是改變人物裝扮的。
十二、attachment目錄:各類附件的處理處理方法,繼承於Attachment基類。實際由對應的AttachmentLoader調用對應的附件類方法。
AtlasAttachmentLoader實現了對應方法。
1三、Texture:定義了Texture抽象類,定義一些抽象方法須要被實現。
1四、TextureAtlas:針對atlas文本進行解析處理,實現TextureAtlasReader進行逐行讀取,texture
藉助外部傳入的textureLoader回調來獲取對應的紋理。
每塊小素材對應一個TextureAtlasPage,素材信息讀取解析後構造對應TextureAtlasRegion。
1五、AnimationStateData:存儲AnimationState動畫更改時要應用的混合(交叉淡入淡出)持續時間。
1六、AnimationState:隨着時間調用動畫,動畫入隊等待播放,容許多個動畫疊加。
分多個track存儲動畫、區分不一樣動畫的timeline,針對event事件的處理邏輯等。
1七、Animation:實現了各類timeline類,Animation負責調用apply方法觸發更新,其apply方法會調用各個timeline的apply方法更新。timeline類中實現找到對應關鍵幀 決定如何渲染。
1八、AssetManager:靜態資源管理,包括拉取文本資源、拉取二進制資源、加載紋理。調用TextureAtlas處理atlas文本等。
canvas:
一、AssetManager:沒有作啥,直接沿用core裏的AssetManager
二、canvasTexture:繼承Texture。
三、SkeletonRender:傳入skeleton數據,渲染畫布,
drawImage會遍歷drawOrder中的slot,逐個渲染region附件,藉助ctx.drawImage API來裁剪和渲染圖片。
drawTriangles會計算頂點,渲染調試模式的綠色線條。
threejs:
一、ThreeJsTexture:針對threesjs自己的texture作了一層包裹,處理了一下filter。
二、MeshBatcher:MeshBatcher繼承自Threejs自己的Mesh。調用SkeletonMeshMaterial獲取材質。
三、SkeletonMesh:SkeletonMeshMaterial繼承自ShaderMaterial,這裏包含了着色器代碼,頂點着色器和片元着色器。
SkeletonMesh繼承自Object3D類。
核心渲染函數updateGeometry,skeleton更新世界變化後,調用渲染函數,遍歷drawOrder。
RegionAttachment和MeshAttachment會進行渲染,渲染藉助MeshBatcher,紋理做爲素材傳入batchMaterial。
webgl:
一、GLTexture:獲取畫布,渲染對應的image到畫布上。
二、Camera:設置相機位置
三、WebGL:定義了ManagedWebGLRenderingContext,其實就是獲取webgl的context上下文。
四、Input:對元素作事件監聽,鼠標、touch事件。
五、Shader:自行實現的着色器,片元和頂點。
六、SkeletonRenderer:負責skeleton的上屏渲染,渲染函數須要藉助PolygonBatcher來上屏渲染,一樣的,只會對RegionAttachment和MeshAttachment會進行渲染。
七、PolygonBatcher:在這裏綁定着色器,設置混合模式,綁定一個Mesh實例對象,Mesh爲單獨封裝的mesh類,最終調用的是Mesh暴露的渲染方法。
八、Mesh:單獨封裝的Mesh類,容許設置指數和頂點,上屏渲染藉助context的drawElements和drawArrays方法。
九、SceneRenderer:最上層的調用類,實例化batcher、webgl上下文、shader,實例化SkeletonRenderer,暴露不一樣的渲染方法,包括drawSkeleton,drawSkeletonDebug、drawTexture、drawRegion等。
根據前面的介紹,咱們對基本概念有所瞭解,而且瞭解了spine的總體架構設計,針對核心模塊進行了介紹,同時對spine核心庫源碼以及渲染層源碼的關鍵邏輯進行解讀,能夠整理出spine渲染的總體流程圖以下:
看到這裏相信你對spine的總體架構設計,渲染流程都已經有了大體的瞭解,接下來在明確了底層內部的處理流程後,咱們的下一步工做是實現換裝和換動做API,具體如何實現,請聽下回分解!
謝謝觀看~~