\r
return totalrot;\r
}\r
- \r
+\r
}\r
\r
+ public class VisualParamEx\r
+ {\r
+ \r
+ static public Dictionary<int,VisualParamEx> allParams = new Dictionary<int,VisualParamEx>();\r
+ static public Dictionary<int, VisualParamEx> deformParams = new Dictionary<int, VisualParamEx>();\r
+ static public Dictionary<int, VisualParamEx> morphParams = new Dictionary<int, VisualParamEx>();\r
+ static public Dictionary<int, VisualParamEx> drivenParams = new Dictionary<int, VisualParamEx>();\r
+ static public SortedList tweakable_params = new SortedList();\r
+ \r
+ public Dictionary<string, Vector3> BoneDeforms = null;\r
+ public Dictionary<string, VolumeDeform> VolumeDeforms = null;\r
+ public List<driven> childparams = null;\r
+ \r
+ public string morphmesh = null;\r
+ \r
+ enum GroupType\r
+ {\r
+ VISUAL_PARAM_GROUP_TWEAKABLE = 0,\r
+ VISUAL_PARAM_GROUP_ANIMATABLE,\r
+ VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT,\r
+ }\r
+ \r
+ public struct VolumeDeform\r
+ {\r
+ public string name;\r
+ public Vector3 scale;\r
+ public Vector3 pos;\r
+ }\r
+ \r
+ public enum EparamSex\r
+ {\r
+ SEX_BOTH = 0,\r
+ SEX_FEMALE = 1,\r
+ SEX_MALE = 2\r
+ }\r
+ \r
+ public enum ParamType\r
+ {\r
+ TYPE_BONEDEFORM,\r
+ TYPE_MORPH,\r
+ TYPE_DRIVER,\r
+ TYPE_COLOR,\r
+ TYPE_LAYER\r
+ }\r
+ \r
+ public struct driven\r
+ {\r
+ public int id;\r
+ public float max1;\r
+ public float max2;\r
+ public float min1;\r
+ public float min2;\r
+ public bool hasMinMax;\r
+ }\r
+ \r
+ public string meshname;\r
+ \r
+ /// <summary>Index of this visual param</summary>\r
+ public int ParamID;\r
+ /// <summary>Internal name</summary>\r
+ public string Name;\r
+ /// <summary>Group ID this parameter belongs to</summary>\r
+ public int Group;\r
+ /// <summary>Name of the wearable this parameter belongs to</summary>\r
+ public string Wearable;\r
+ /// <summary>Displayable label of this characteristic</summary>\r
+ public string Label;\r
+ /// <summary>Displayable label for the minimum value of this characteristic</summary>\r
+ public string LabelMin;\r
+ /// <summary>Displayable label for the maximum value of this characteristic</summary>\r
+ public string LabelMax;\r
+ /// <summary>Default value</summary>\r
+ public float DefaultValue;\r
+ /// <summary>Minimum value</summary>\r
+ public float MinValue;\r
+ /// <summary>Maximum value</summary>\r
+ public float MaxValue;\r
+ /// <summary>Is this param used for creation of bump layer?</summary>\r
+ public bool IsBumpAttribute;\r
+ /// <summary>Alpha blending/bump info</summary>\r
+ public VisualAlphaParam? AlphaParams;\r
+ /// <summary>Color information</summary>\r
+ public VisualColorParam? ColorParams;\r
+ /// <summary>Array of param IDs that are drivers for this parameter</summary>\r
+ public int[] Drivers;\r
+ /// <summary>The Avatar Sex that this parameter applies to</summary>\r
+ public EparamSex sex;\r
+ \r
+ public ParamType pType;\r
+ \r
+ public static int count = 0;\r
+ \r
+ /// <summary>\r
+ /// Set all the values through the constructor\r
+ /// </summary>\r
+ /// <param name="paramID">Index of this visual param</param>\r
+ /// <param name="name">Internal name</param>\r
+ /// <param name="group"></param>\r
+ /// <param name="wearable"></param>\r
+ /// <param name="label">Displayable label of this characteristic</param>\r
+ /// <param name="labelMin">Displayable label for the minimum value of this characteristic</param>\r
+ /// <param name="labelMax">Displayable label for the maximum value of this characteristic</param>\r
+ /// <param name="def">Default value</param>\r
+ /// <param name="min">Minimum value</param>\r
+ /// <param name="max">Maximum value</param>\r
+ /// <param name="isBumpAttribute">Is this param used for creation of bump layer?</param>\r
+ /// <param name="drivers">Array of param IDs that are drivers for this parameter</param>\r
+ /// <param name="alpha">Alpha blending/bump info</param>\r
+ /// <param name="colorParams">Color information</param>\r
+ public VisualParamEx(int paramID, string name, int group, string wearable, string label, string labelMin, string labelMax, float def, float min, float max, bool isBumpAttribute, int[] drivers, VisualAlphaParam? alpha, VisualColorParam? colorParams)\r
+ {\r
+ ParamID = paramID;\r
+ Name = name;\r
+ Group = group;\r
+ Wearable = wearable;\r
+ Label = label;\r
+ LabelMin = labelMin;\r
+ LabelMax = labelMax;\r
+ DefaultValue = def;\r
+ MaxValue = max;\r
+ MinValue = min;\r
+ IsBumpAttribute = isBumpAttribute;\r
+ Drivers = drivers;\r
+ AlphaParams = alpha;\r
+ ColorParams = colorParams;\r
+ sex = EparamSex.SEX_BOTH;\r
+ }\r
+ \r
+ public VisualParamEx(XmlNode node, ParamType pt)\r
+ {\r
+ pType = pt;\r
+ \r
+ ParamID = Int32.Parse(node.Attributes.GetNamedItem("id").Value);\r
+ Name = node.Attributes.GetNamedItem("name").Value;\r
+ Group = Int32.Parse(node.Attributes.GetNamedItem("group").Value);\r
+ \r
+ //These dont exist for facal expresion morphs\r
+ if(node.Attributes.GetNamedItem("wearable")!=null)\r
+ Wearable = node.Attributes.GetNamedItem("wearable").Value;\r
+ \r
+ MinValue = float.Parse(node.Attributes.GetNamedItem("value_min").Value);\r
+ MaxValue = float.Parse(node.Attributes.GetNamedItem("value_max").Value);\r
+ \r
+ // These do not exists for driven parameters\r
+ if (node.Attributes.GetNamedItem("label_min") != null)\r
+ {\r
+ LabelMin = node.Attributes.GetNamedItem("label_min").Value;\r
+ }\r
+ \r
+ if (node.Attributes.GetNamedItem("label_max") != null)\r
+ {\r
+ LabelMax = node.Attributes.GetNamedItem("label_max").Value;\r
+ }\r
+ \r
+ XmlNode sexnode = node.Attributes.GetNamedItem("sex");\r
+ \r
+ if (sexnode != null)\r
+ {\r
+ if (sexnode.Value == "male")\r
+ {\r
+ sex = EparamSex.SEX_MALE;\r
+ }\r
+ else\r
+ {\r
+ sex = EparamSex.SEX_FEMALE;\r
+ }\r
+ \r
+ }\r
+ \r
+ Group = int.Parse(node.Attributes.GetNamedItem("group").Value);\r
+ \r
+ if (Group == (int)GroupType.VISUAL_PARAM_GROUP_TWEAKABLE)\r
+ {\r
+ if(!tweakable_params.ContainsKey(ParamID)) //stupid duplicate shared params\r
+ {\r
+ tweakable_params.Add(this.ParamID, this);\r
+ }\r
+ Logger.Log(String.Format("Adding tweakable paramater ID {0} {1}", count, this.Name),Helpers.LogLevel.Info);\r
+ count++;\r
+ }\r
+ \r
+ //TODO other paramaters but these arew concerned with editing the GUI display so not too fussed at the moment\r
+ \r
+ try\r
+ {\r
+ allParams.Add(ParamID, this);\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ Logger.Log("Duplicate VisualParam in allParams id " + ParamID.ToString(), Helpers.LogLevel.Info);\r
+ }\r
+ \r
+ if (pt == ParamType.TYPE_BONEDEFORM)\r
+ {\r
+ // If we are in the skeleton section then we also have bone deforms to parse\r
+ BoneDeforms = new Dictionary<string, Vector3>();\r
+ if(node.HasChildNodes && node.ChildNodes[0].HasChildNodes)\r
+ {\r
+ ParseBoneDeforms(node.ChildNodes[0].ChildNodes); \r
+ }\r
+ deformParams.Add(ParamID,this);\r
+ }\r
+ \r
+ if (pt == ParamType.TYPE_MORPH)\r
+ {\r
+ VolumeDeforms = new Dictionary<string, VolumeDeform>();\r
+ if (node.HasChildNodes && node.ChildNodes[0].HasChildNodes)\r
+ {\r
+ ParseVolumeDeforms(node.ChildNodes[0].ChildNodes);\r
+ }\r
+ \r
+ try\r
+ {\r
+ morphParams.Add(ParamID, this);\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ Logger.Log("Duplicate VisualParam in morphParams id " + ParamID.ToString(), Helpers.LogLevel.Info);\r
+ }\r
+ \r
+ }\r
+ \r
+ if (pt == ParamType.TYPE_DRIVER)\r
+ {\r
+ childparams = new List<driven>();\r
+ if (node.HasChildNodes && node.ChildNodes[0].HasChildNodes) //LAZY\r
+ {\r
+ ParseDrivers(node.ChildNodes[0].ChildNodes);\r
+ }\r
+ \r
+ drivenParams.Add(ParamID, this);\r
+ \r
+ }\r
+ \r
+ if (pt == ParamType.TYPE_COLOR)\r
+ {\r
+ if (node.HasChildNodes)\r
+ {\r
+ foreach (XmlNode colorchild in node.ChildNodes)\r
+ {\r
+ if (colorchild.Name == "param_color")\r
+ {\r
+ //TODO extract <value color="50, 25, 5, 255" />\r
+ }\r
+ }\r
+ \r
+ }\r
+ }\r
+ \r
+ }\r
+ \r
+ void ParseBoneDeforms(XmlNodeList deforms)\r
+ {\r
+ foreach (XmlNode node in deforms)\r
+ {\r
+ if (node.Name == "bone")\r
+ {\r
+ string name = node.Attributes.GetNamedItem("name").Value;\r
+ Vector3 scale = XmlParseVector(node.Attributes.GetNamedItem("scale").Value);\r
+ BoneDeforms.Add(name, scale);\r
+ }\r
+ }\r
+ }\r
+ \r
+ void ParseVolumeDeforms(XmlNodeList deforms)\r
+ {\r
+ foreach (XmlNode node in deforms)\r
+ {\r
+ if (node.Name == "volume_morph")\r
+ {\r
+ VolumeDeform vd = new VolumeDeform();\r
+ vd.name = node.Attributes.GetNamedItem("name").Value;\r
+ vd.name = vd.name.ToLower();\r
+ \r
+ if (node.Attributes.GetNamedItem("scale") != null)\r
+ {\r
+ vd.scale = XmlParseVector(node.Attributes.GetNamedItem("scale").Value);\r
+ }\r
+ else\r
+ {\r
+ vd.scale = new Vector3(0, 0, 0);\r
+ }\r
+ \r
+ if (node.Attributes.GetNamedItem("pos") != null)\r
+ {\r
+ vd.pos = XmlParseVector(node.Attributes.GetNamedItem("pos").Value);\r
+ }\r
+ else\r
+ {\r
+ vd.pos = new Vector3(0f, 0f, 0f);\r
+ }\r
+ \r
+ VolumeDeforms.Add(vd.name, vd);\r
+ }\r
+ }\r
+ }\r
+ \r
+ void ParseDrivers(XmlNodeList drivennodes)\r
+ {\r
+ foreach (XmlNode node in drivennodes)\r
+ {\r
+ if (node.Name == "driven")\r
+ {\r
+ driven d = new driven();\r
+ \r
+ d.id = Int32.Parse(node.Attributes.GetNamedItem("id").Value);\r
+ XmlNode param = node.Attributes.GetNamedItem("max1");\r
+ if (param != null)\r
+ {\r
+ d.max1 = float.Parse(param.Value);\r
+ d.max2 = float.Parse(node.Attributes.GetNamedItem("max2").Value);\r
+ d.min1 = float.Parse(node.Attributes.GetNamedItem("min1").Value);\r
+ d.max2 = float.Parse(node.Attributes.GetNamedItem("min2").Value);\r
+ d.hasMinMax = true;\r
+ }\r
+ else\r
+ {\r
+ d.hasMinMax = false;\r
+ }\r
+ \r
+ childparams.Add(d); \r
+ \r
+ }\r
+ }\r
+ }\r
+ \r
+ public static Vector3 XmlParseVector(string data)\r
+ {\r
+ string[] posparts = data.Split(' ');\r
+ return new Vector3(float.Parse(posparts[0]), float.Parse(posparts[1]), float.Parse(posparts[2]));\r
+ }\r
+ \r
+ public static Quaternion XmlParseRotation(string data)\r
+ {\r
+ string[] rotparts = data.Split(' ');\r
+ return Quaternion.CreateFromEulers((float)(float.Parse(rotparts[0]) * Math.PI / 180f), (float)(float.Parse(rotparts[1]) * Math.PI / 180f), (float)(float.Parse(rotparts[2]) * Math.PI / 180f));\r
+ }\r
+ }\r
}\r