/* * Reads a DAZ Studio PZ2 file with a pose in it and produces * a Vixen Pose object for this avatar's skeleton. * @param posename file name containing pose */ public Pose ReadPose(System.String name) { Hashtable poseinfo = new Hashtable(); int level = 0; int numbones = 0; int offset = -1; try { /* * Parse the DAZ Studio pose file and extract the rotations * for each bone into a hash table */ using (StreamReader posefile = new StreamReader("pose/" + name + ".pz2")) { System.String line; System.String bonename = ""; char[] space = new char[] { ' ' }; float xrot = 0; float yrot = 0; float zrot = 0; while ((line = posefile.ReadLine().Trim()) != null) { string[] words = line.Split(space); string opcode; if (line == "") { continue; } if (line.EndsWith("{")) // open bracket increases nesting leve4l { ++level; continue; } if (line.EndsWith("}")) // close bracket decreases nesting level { --level; if (level == 0) { break; } continue; } if (words.Length == 0) // nothing parsed? { continue; } opcode = words[0]; if (words.Length < 1) // has an argument? { continue; } if (opcode == "actor") // found a new bone? { bonename = words[1]; // save the bone name xrot = 0; yrot = 0; zrot = 0; ++numbones; } else if (opcode == "rotateX") // X rotation coming up? { offset = 0; } else if (opcode == "rotateY") // Y rotation coming up? { offset = 1; } else if (opcode == "rotateZ") // Z rotation coming up? { offset = 2; } else if (opcode == "k") // is it a key? { float time = float.Parse(words[1]); // parse the time float angle = float.Parse(words[2]); // parse the rotation angle in degrees Quat q; angle *= (float)Math.PI / 180; switch (offset) { case 0: xrot = angle; break; case 1: yrot = angle; break; case 2: zrot = angle; if ((xrot == 0) && (yrot == 0) && (zrot == 0)) { break; } q = new Quat(Model.XAXIS, xrot); if (yrot != 0) { q *= new Quat(Model.YAXIS, yrot); } if (zrot != 0) { q *= new Quat(Model.ZAXIS, yrot); } q.Normalize(); offset = -1; if (q.IsEmpty()) { break; } if (bonename.Length > 0) // save rotation for the bone { poseinfo[bonename] = q; SharedWorld.Trace(bonename + " " + q.x + " " + q.y + " " + q.z + " " + q.w + "\n"); } break; } } } } if (numbones != BodyPoser.NumBones) { Canvas3D.LogError(System.String.Format("Pose with {0} bones does not match skeleton with {1} bones", numbones, BodyPoser.NumBones)); } /* * Convert hash table with rotations into a Pose. */ Pose pose = new Pose(BodyPoser); foreach (DictionaryEntry entry in poseinfo) { System.String key = entry.Key.ToString(); System.String bonename = key; Quat q = entry.Value as Quat; int boneindex; boneindex = BodyPoser.GetBoneIndex(bonename); if (boneindex >= 0) { pose.SetLocalRotation(boneindex, q); SharedWorld.Trace(bonename + " " + q.x + " " + q.y + " " + q.z + " " + q.w + "\n"); } else { Canvas3D.LogError("Cannot find bone " + bonename + " in skeleton "); } } return(pose); } catch (Exception ex) { Canvas3D.LogError(ex.Message + " Cannot read pose file " + name); return(null); } }
/* * Reads a DAZ Studio DSF file with a pose in it and produces * a Vixen Pose object for this avatar's skeleton. * @param posename name of pose */ public Pose ReadPose(System.String posename) { System.String filename = "pose/" + posename + "pose.dsf"; Hashtable poseinfo = new Hashtable(); try { /* * Parse the DAZ Studio pose file and extract the rotations * for each bone into a hash table */ using (StreamReader posefile = new StreamReader(filename)) { System.String line; Regex pattern = new Regex("([a-zA-Z0-9]+)" + Regex.Escape(":?") + "rotation/([xyz])"); while ((line = posefile.ReadLine()) != null) { Match match = pattern.Match(line); System.String name; System.String axis; if (!match.Success) { continue; } name = match.Groups[1].ToString(); axis = match.Groups[2].ToString(); line = posefile.ReadLine(); int p = line.IndexOf("[ 0, "); if (p > 0) { System.String s = line.Substring(p + 5); float angle; Quat rot; Quat q = null; s = s.Substring(0, s.IndexOf("]")); angle = float.Parse(s); if (angle == 0) { continue; } angle *= (float)Math.PI / 180.0f; if (axis == "x") { q = new Quat(Model.XAXIS, angle); } else if (axis == "y") { q = new Quat(Model.YAXIS, angle); } else if (axis == "z") { q = new Quat(Model.ZAXIS, angle); } if (q == null) { continue; } if (poseinfo.Contains(name)) { rot = poseinfo[name] as Quat; rot.Mul(rot, q); } else { poseinfo.Add(name, q); } } } } /* * Convert hash table with rotations into a Pose. * Map DAZ bone names into Vixen bone names. */ Pose pose = new Pose(BodyPoser); foreach (DictionaryEntry entry in poseinfo) { System.String key = entry.Key.ToString(); System.String bonename = key; Quat q = entry.Value as Quat; int boneindex; if (key == "abdomen") { bonename = "Torso"; } else if (key == "rHand") { bonename = "RightWrist"; } else if (key == "lHand") { bonename = "LeftWrist"; } else if (key == "rShldr") { bonename = "RightShoulder"; } else if (key == "lShldr") { bonename = "LeftShoulder"; } else if (key == "rForeArm") { bonename = "RightElbow"; } else if (key == "lForeArm") { bonename = "LeftElbow"; } else if (key == "rShin") { bonename = "RightKnee"; } else if (key == "lShin") { bonename = "LeftShin"; } else if (key == "rThigh") { bonename = "RightHip"; } else if (key == "lThigh") { bonename = "LeftHip"; } else if (key == "lFoot") { bonename = "LeftAnkle"; } else if (key == "rFoot") { bonename = "RightAnkle"; } boneindex = BodyPoser.GetBoneIndex(bonename); if (boneindex >= 0) { pose.SetLocalRotation(boneindex, q); SharedWorld.Trace(bonename + " " + q.x + " " + q.y + " " + q.z + " " + q.w + "\n"); } } return(pose); } catch (Exception ex) { Canvas3D.LogError(ex.Message + " Cannot read pose file " + filename); return(null); } }
/* * Reads a DAZ Studio PZ2 file with a pose in it and produces * a Vixen Pose object for this avatar's skeleton. * @param posename file name containing pose */ public Pose ReadPose(System.String name) { ArrayList bones = new ArrayList(); ArrayList positions = new ArrayList(); int level = 0; int numbones = 0; Int32 numframes = 0; bool parsing_motion = false; System.String bonename = ""; Pose bindpose = BodyPoser.BindPose; Pose pose = new Pose(BodyPoser); float x, y, z; pose.Copy(bindpose); try { /* * Parse the DAZ Studio pose file and extract the rotations * for each bone into a hash table */ using (StreamReader posefile = new StreamReader("pose/" + name + ".bvh")) { System.String line; char[] space = new char[] { ' ' }; while ((line = posefile.ReadLine().Trim()) != null) { string[] words = line.Split(space); string opcode; if (line == "") { continue; } /* * Parsing motion for each frame. * Each line in the file contains the root joint position and rotations for all joints. */ if (parsing_motion) { int nbones = 0; if (words[0].StartsWith("Frame")) { continue; } x = float.Parse(words[0]); // root bone position y = float.Parse(words[1]); z = float.Parse(words[2]); pose.SetPosition(new Vec3(x, y, z)); for (int i = 3; i < words.Length; i += 3) { bonename = bones[nbones] as System.String; int boneindex = BodyPoser.GetBoneIndex(bonename); ++nbones; if (boneindex >= 0) { Quat q, b; z = float.Parse(words[i]); // Z, Y, X rotation angles y = float.Parse(words[i + 1]); x = float.Parse(words[i + 2]); if ((x == 0) && (y == 0) && (z == 0)) { continue; } if (true) { q = new Quat(Model.ZAXIS, z * (float)Math.PI / 180); q *= new Quat(Model.YAXIS, x * (float)Math.PI / 180); q *= new Quat(Model.XAXIS, y * (float)Math.PI / 180); } else { q = new Quat(Model.ZAXIS, y * (float)Math.PI / 180); q *= new Quat(Model.YAXIS, x * (float)Math.PI / 180); q *= new Quat(Model.XAXIS, z * (float)Math.PI / 180); } q.Normalize(); b = pose.GetLocalRotation(boneindex); q *= b; pose.SetLocalRotation(boneindex, q); SharedWorld.Trace(bonename + " " + q.x + " " + q.y + " " + q.z + " " + q.w + "\n"); } else { Canvas3D.LogError("Cannot find bone " + bonename + " in skeleton "); } } break; } /* * Parsing skeleton definition with joint names and positions. */ else { if (words.Length < 1) // has an argument? { continue; } opcode = words[0]; if ((opcode == "ROOT") || // found root bone? (opcode == "JOINT")) // found any bone? { bonename = words[1]; // save the bone name ++numbones; } else if (opcode == "OFFSET") // bone position { float xpos = float.Parse(words[1]); float ypos = float.Parse(words[2]); float zpos = float.Parse(words[3]); if (bonename.Length > 0) // save position for the bone { bones.Add(bonename); positions.Add(new Vec3(xpos, ypos, zpos)); SharedWorld.Trace(bonename + " " + xpos + " " + ypos + " " + zpos + "\n"); } bonename = ""; continue; } else if (opcode == "MOTION") { parsing_motion = true; if (numbones != BodyPoser.NumBones) { Canvas3D.LogError(System.String.Format("Pose with {0} bones does not match skeleton with {1} bones", numbones, BodyPoser.NumBones)); } } } } } return(pose); } catch (Exception ex) { Canvas3D.LogError(ex.Message + " Cannot read pose file " + name); return(null); } }