private static void ProcessNodes(XmlNode node, Dictionary <int, PPAnimNodeInfo> animNodeInfos, PPSectionInfo parentSection)
    {
        XmlNodeList sections = node.SelectNodes("section");

        for (int i = 0; i < sections.Count; i++)
        {
            XmlNode       sectionNode = sections[i];
            PPSectionInfo sectionInfo = new PPSectionInfo();
            sectionInfo.Index = sectionInfo.Id = int.Parse(sectionNode.Attributes["id"].Value);
            sectionInfo.Name  = sectionNode.Attributes["name"] != null ? sectionNode.Attributes["name"].Value : "section_" + sectionInfo.Index;
            sectionInfo.Type  = NodeType.Section;

            XmlNode editorNode = sectionNode.SelectSingleNode("editor");
            editorNode.GetPosInfo(out sectionInfo.EditorPos)
            .GetAngleInfo(out sectionInfo.EditorAngle);

            //for versatile
            PBVersatileInterface.LoadFromXml(sectionNode, sectionInfo.VersatileInfo);

            animNodeInfos.Add(sectionInfo.Index, sectionInfo);
            parentSection.AddSubNode(sectionInfo);

            ProcessNodes(sectionNode, animNodeInfos, sectionInfo);
        }

        XmlNodeList blocks = node.SelectNodes("block");

        for (int i = 0; i < blocks.Count; i++)
        {
            XmlNode     blockNode  = blocks[i];
            PPBlockInfo blockInfo  = new PPBlockInfo();
            XmlNode     editorNode = blockNode.SelectSingleNode("editor");
            editorNode.GetPosInfo(out blockInfo.EditorPos)
            .GetAngleInfo(out blockInfo.EditorAngle);

            blockInfo.Prefab = blockNode.Attributes["type"].Value;
            blockInfo.Thumb  = blockNode.Attributes["thumb"] != null ? blockNode.Attributes["thumb"].Value : blockInfo.Prefab;
            blockInfo.Detail = blockNode.Attributes["partDetail"] != null ? blockNode.Attributes["partDetail"].Value : "";
            blockInfo.Count  = blockNode.Attributes["count"] != null?int.Parse(blockNode.Attributes["count"].Value) : 1;

            blockInfo.Hide  = blockNode.Attributes["hide"] != null && blockNode.Attributes["hide"].Value.Equals("1");
            blockInfo.Type  = NodeType.Block;
            blockInfo.Index = blockInfo.Id = int.Parse(blockNode.Attributes["id"].Value);

            //for textures
            blockInfo.ParseTextures(blockNode.SelectNodes("texture"));

            //for versatile blocks
            PBVersatileInterface.LoadFromXml(blockNode, blockInfo.VersatileInfo);

            animNodeInfos.Add(blockInfo.Index, blockInfo);
            parentSection.AddSubNode(blockInfo);
        }
    }