Beispiel #1
0
        /// <summary>
        /// Parses each child of <code>node</code> as an instruction, adds them to the specified instruction list. Calls are resolved to production lists
        /// using the specified multimap.
        /// </summary>
        private static void ParseInstructionsFromXml(XmlNode node, List <TreeCrayonInstruction> instructions, MultiMap <string, ProductionNodePair> map)
        {
            foreach (XmlNode child in node.ChildNodes)
            {
                switch (child.Name)
                {
                case "Call":
                    String            name        = XmlUtil.GetString(child, "ref");
                    List <Production> productions = GetProductionsByRef(name, map);
                    instructions.Add(new Call(productions, XmlUtil.GetInt(child, "delta", -1)));
                    break;

                case "Child":
                    Child ch = new Child();
                    ParseInstructionsFromXml(child, ch.Instructions, map);
                    instructions.Add(ch);
                    break;

                case "Maybe":
                    Maybe maybe = new Maybe(XmlUtil.GetFloat(child, "chance", 0.50f));
                    ParseInstructionsFromXml(child, maybe.Instructions, map);
                    instructions.Add(maybe);
                    break;

                case "Forward":
                    instructions.Add(new Forward(XmlUtil.GetFloat(child, "distance"), XmlUtil.GetFloat(child, "variation", 0.0f), XmlUtil.GetFloat(child, "radius", 0.86f)));
                    break;

                case "Backward":
                    instructions.Add(new Backward(XmlUtil.GetFloat(child, "distance"), XmlUtil.GetFloat(child, "variation", 0.0f)));
                    break;

                case "Pitch":
                    instructions.Add(new Pitch(XmlUtil.GetFloat(child, "angle"), XmlUtil.GetFloat(child, "variation", 0.0f)));
                    break;

                case "Scale":
                    instructions.Add(new Scale(XmlUtil.GetFloat(child, "scale"), XmlUtil.GetFloat(child, "variation", 0.0f)));
                    break;

                case "ScaleRadius":
                    instructions.Add(new ScaleRadius(XmlUtil.GetFloat(child, "scale"), XmlUtil.GetFloat(child, "variation", 0.0f)));
                    break;

                case "Twist":
                    instructions.Add(new Twist(XmlUtil.GetFloat(child, "angle", 0), XmlUtil.GetFloat(child, "variation", 360.0f)));
                    break;

                case "Level":
                    instructions.Add(new Level(XmlUtil.GetInt(child, "delta", -1)));
                    break;

                case "Leaf":
                    instructions.Add(ParseLeafFromXml(child));
                    break;

                case "Bone":
                    instructions.Add(new Bone(XmlUtil.GetInt(child, "delta", -1)));
                    break;

                case "RequireLevel":
                    String       type  = XmlUtil.GetStringOrNull(child, "type");
                    CompareType  ctype = type == "less" ? CompareType.Less : CompareType.Greater;
                    RequireLevel req   = new RequireLevel(XmlUtil.GetInt(child, "level"), ctype);
                    ParseInstructionsFromXml(child, req.Instructions, map);
                    instructions.Add(req);
                    break;

                case "Align":
                    instructions.Add(new Align());
                    break;
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates a tree generator from a specified XML document.
        /// </summary>
        /// <param name="document">The XML document to parse.</param>
        /// <returns>A new tree generator.</returns>
        /// <exception cref="ArgumentException">If the XML document is not a valid tree specification.</exception>
        public static TreeGenerator CreateFromXml(XmlDocument document)
        {
            TreeGenerator generator  = new TreeGenerator();
            string        rootName   = null;
            int           levels     = -1;
            int           boneLevels = 3;
            MultiMap <string, ProductionNodePair> productions = new MultiMap <string, ProductionNodePair>();

            XmlNode root = document.SelectSingleNode("Tree");

            foreach (XmlNode child in root.ChildNodes)
            {
                switch (child.Name)
                {
                case "Root":
                    rootName = XmlUtil.GetString(child, "ref");
                    break;

                case "Levels":
                    levels = XmlUtil.GetInt(child, "value");
                    break;

                case "BoneLevels":
                    boneLevels = XmlUtil.GetInt(child, "value");
                    break;

                case "LeafAxis":
                    generator.LeafAxis = XmlUtil.GetVector3(child, "value");
                    generator.LeafAxis.Value.Normalize();
                    break;

                case "Production":
                    string name = XmlUtil.GetString(child, "id");
                    productions.Add(name, new ProductionNodePair(new Production(), child));
                    break;

                case "ConstrainUnderground":
                    generator.Constraints.Constaints.Add(new ConstrainUndergroundBranches(XmlUtil.GetFloat(child, "lowerBound", 256.0f)));
                    break;

                case "TextureHeight":
                    generator.TextureHeight          = XmlUtil.GetFloat(child, "height");
                    generator.TextureHeightVariation = XmlUtil.GetFloat(child, "variation", 0.0f);
                    break;
                }
            }

            if (rootName == null)
            {
                throw new ArgumentException("Root name must be specified.");
            }

            // Now we have a map of names -> productions, so we can start parsing the the productions
            foreach (ProductionNodePair pn in productions.Values)
            {
                ParseInstructionsFromXml(pn.Node, pn.Production.Instructions, productions);
            }

            generator.Root       = productions[rootName][0].Production;
            generator.MaxLevel   = levels;
            generator.BoneLevels = boneLevels;

            return(generator);
        }