void LoadTarget(MegaMorphTarget mt) { MegaMorph mr = (MegaMorph)target; string filename = EditorUtility.OpenFilePanel("Morph Target", lastpath, "obj"); if (filename == null || filename.Length < 1) { return; } lastpath = filename; List <MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, mr.importScale, mr.flipyz, mr.negx); if (targets != null && targets.Count > 0) { MegaTargetMesh tm = targets[0]; if (tm.verts.Count != mr.oPoints.Length) { EditorUtility.DisplayDialog("Target Vertex count mismatch!", "Target " + tm.name + " has wrong number of verts", "OK"); } else { mt.points = tm.verts.ToArray(); mt.name = tm.name; } } }
// Fbx could have been exported any which way so still need to do try all mappings to find correct public bool ParseMorph(BinaryReader br, string id) { MegaMorphOMatic mr = (MegaMorphOMatic)target; switch (id) { case "Max": mr.Max = br.ReadSingle(); break; case "Min": mr.Min = br.ReadSingle(); break; case "UseLim": mr.UseLimit = (br.ReadInt32() == 1); break; // This will only be changed points, but we need scale case "StartPoints": // Mapping MegaTargetMesh tm = new MegaTargetMesh(); tm.verts = MegaParse.ReadP3l(br); // make a vector if (!TryMapping1(tm, mr)) { EditorUtility.DisplayDialog("Mapping Failed!", "Mapping failed!", "OK"); EditorUtility.ClearProgressBar(); return(false); } break; case "Channel": mr.chanBank.Add(LoadChan(br)); break; case "Animation": LoadAnimation(mr, br); break; default: return(false); } return(true); }
bool DoMapping(MegaModifiers mod, MegaMorph morph, MegaTargetMesh tm, int[] mapping, float scale, bool flipyz, bool negx, bool negy) { int step = mod.verts.Length / 10; int count = 0; for (int i = 0; i < mod.verts.Length; i++) { count--; if (count < 0) { count = step; float a = (float)i / (float)mod.verts.Length; EditorUtility.DisplayProgressBar("Mapping", "Mapping vertex " + i, a); } mapping[i] = FindVert(mod.verts[i], tm.verts, morph.tolerance, scale, flipyz, negx, negy, i); if (mapping[i] == -1) { // Failed EditorUtility.ClearProgressBar(); return(false); } } EditorUtility.ClearProgressBar(); return(true); }
// remove mPoints from channel, just use target list, if targets.Count == 1 then use delta // first target goes into mPoints // guess we should update any targets who we have already, ie use name void LoadTargets(MegaMorphChan channel) { MegaMorph mr = (MegaMorph)target; string filename = EditorUtility.OpenFilePanel("Morph Targets", lastpath, "obj"); if (filename == null || filename.Length < 1) { return; } lastpath = filename; List <MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, mr.importScale, mr.flipyz, mr.negx); if (targets != null) { if (channel.mName == "Empty") { channel.mName = Path.GetFileNameWithoutExtension(filename); } // Now need to check that each target has correct num verts and face list matches for (int i = 0; i < targets.Count; i++) { MegaTargetMesh tm = targets[i]; if (tm.verts.Count != mr.oPoints.Length) { EditorUtility.DisplayDialog("Target Vertex count mismatch!", "Target " + tm.name + " has wrong number of verts", "OK"); } else { // See if we have a target with this name, if so update that MegaMorphTarget mt = channel.GetTarget(tm.name); if (mt == null) // add a new target { mt = new MegaMorphTarget(); mt.name = tm.name; channel.mTargetCache.Add(mt); } mt.points = tm.verts.ToArray(); //for ( int v = 0; v < mt.points.Length; v++ ) //{ //if ( mt.points[v] == mr.oPoints[v] ) //Debug.Log("Vert " + v + " isnt morphed"); //} } } channel.ResetPercent(); channel.Rebuild(mr); // rebuild delta for 1st channel } mr.BuildCompress(); }
// Remove morph and pass tolerance then can morph to Utils // TODO: report error if target vert counts dont match base mapping bool DoMapping(MegaModifiers mod, MegaMorphOMatic morph, MegaTargetMesh tm, float scale, bool flipyz, bool negx) { for ( int i = 0; i < mod.verts.Length; i++ ) { float a = (float)i / (float)mod.verts.Length; EditorUtility.DisplayProgressBar("Mapping", "Mapping vertex " + i, a); int map = MegaUtils.FindVert(mod.verts[i], tm.verts, morph.tolerance, scale, flipyz, negx, i); if ( map == -1 ) { // Failed EditorUtility.ClearProgressBar(); return false; } } EditorUtility.ClearProgressBar(); return true; }
// Remove morph and pass tolerance then can morph to Utils // TODO: report error if target vert counts dont match base mapping bool DoMapping(MegaModifiers mod, MegaMorphOMatic morph, MegaTargetMesh tm, float scale, bool flipyz, bool negx) { for (int i = 0; i < mod.verts.Length; i++) { float a = (float)i / (float)mod.verts.Length; EditorUtility.DisplayProgressBar("Mapping", "Mapping vertex " + i, a); int map = MegaUtils.FindVert(mod.verts[i], tm.verts, morph.tolerance, scale, flipyz, negx, i); if (map == -1) { // Failed EditorUtility.ClearProgressBar(); return(false); } } EditorUtility.ClearProgressBar(); return(true); }
// Fbx could have been exported any which way so still need to do try all mappings to find correct public bool ParseMorph(BinaryReader br, string id) { MegaMorph mr = (MegaMorph)target; //Debug.Log("ParseMorph " + id); switch (id) { case "Max": mr.Max = br.ReadSingle(); break; case "Min": mr.Min = br.ReadSingle(); break; case "UseLim": mr.UseLimit = (br.ReadInt32() == 1); break; case "StartPoints": // Mapping MegaTargetMesh tm = new MegaTargetMesh(); tm.verts = MegaParse.ReadP3l(br); // make a vector //Debug.Log("num " + tm.verts.Count); if (!TryMapping1(tm, mr)) { EditorUtility.DisplayDialog("Mapping Failed!", "Mapping failed! Please check the Morph page on the MegaFiers website for reasons for this", "OK"); EditorUtility.ClearProgressBar(); return(false); } //Debug.Log("StartPoints " + tm.verts.Count); break; case "Channel": mr.chanBank.Add(LoadChan(br)); break; case "Animation": LoadAnimation(mr, br); break; default: return(false); } return(true); }
void LoadBase(MegaMorph morph) { string filename = EditorUtility.OpenFilePanel("Morph Base", lastpath, "obj"); if (filename == null || filename.Length < 1) { return; } lastpath = filename; List <MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, 1.0f, false, false); //morph.importScale, morph.flipyz, morph.negx); // only use first if (targets != null && targets.Count > 0) { if (!TryMapping(targets, morph)) { // No match found EditorUtility.DisplayDialog("Mapping Failed!", "Mapping of " + Path.GetFileNameWithoutExtension(filename) + " failed!", "OK"); EditorUtility.ClearProgressBar(); return; } } }
public static List<MegaTargetMesh> LoadTargets(string path, float scale, bool flipzy, bool negx) { List<MegaTargetMesh> targets = new List<MegaTargetMesh>(); MegaTargetMesh current = null; StreamReader stream = File.OpenText(path); string entireText = stream.ReadToEnd(); stream.Close(); entireText = entireText.Replace("\n", "\r\n"); List<Vector3> verts = new List<Vector3>(); using ( StringReader reader = new StringReader(entireText) ) { string currentText = reader.ReadLine(); char[] splitIdentifier = { ' ' }; string[] brokenString; string name = ""; Vector3 p = Vector3.zero; while ( currentText != null ) { if ( !currentText.StartsWith("v ") && !currentText.StartsWith("g ") && !currentText.StartsWith("f ") ) { currentText = reader.ReadLine(); if ( currentText != null ) currentText = currentText.Replace(" ", " "); } else { currentText = currentText.Trim(); brokenString = currentText.Split(splitIdentifier, 50); switch ( brokenString[0] ) { case "f": if ( verts.Count > 0 ) { current = new MegaTargetMesh(); current.name = name; current.verts = new List<Vector3>(verts); current.faces = new List<int>(); targets.Add(current); verts.Clear(); } break; case "g": name = brokenString[1]; break; case "v": p.x = System.Convert.ToSingle(brokenString[1]) * scale; if ( negx ) { p.x = -p.x; } if ( flipzy ) { p.y = System.Convert.ToSingle(brokenString[3]) * scale; p.z = System.Convert.ToSingle(brokenString[2]) * scale; } else { p.y = System.Convert.ToSingle(brokenString[2]) * scale; p.z = System.Convert.ToSingle(brokenString[3]) * scale; } verts.Add(p); break; } currentText = reader.ReadLine(); if ( currentText != null ) currentText = currentText.Replace(" ", " "); } } } return targets; }
bool TryMapping1(MegaTargetMesh tm, MegaMorph morph) { MegaModifiers mod = morph.GetComponent<MegaModifiers>(); if ( mod == null ) { EditorUtility.DisplayDialog("Missing ModifyObject!", "No ModifyObject script found on the object", "OK"); return false; } int[] mapping = new int[mod.verts.Length]; //for ( int i = 0; i < 8; i++ ) //{ //Debug.Log("target vert " + tm.verts[i].ToString("0.000")); //} //for ( int i = 0; i < 8; i++ ) //{ //Debug.Log("base vert " + mod.verts[i].ToString("0.000")); //} // Get extents for mod verts and for imported meshes, if not the same then scale Vector3 min1,max1; Vector3 min2,max2; Vector3 ex1 = Extents(mod.verts, out min1, out max1); Vector3 ex2 = Extents(tm.verts, out min2, out max2); // need min max on all axis so we can produce an offset to add float d1 = ex1.x; float d2 = ex2.x; float scl = d1 / d2; //d2 / d1; bool flipyz = false; bool negx = false; //Debug.Log("scale " + scl.ToString("0.0000")); //Vector3 offset = (min2 * scl) - min1; //Debug.Log("offset " + offset.ToString("0.0000")); //for ( int i = 0; i < 8; i++ ) //{ //Vector3 p = tm.verts[i]; //p = (p * scl) + offset; //Debug.Log("adj vert " + p.ToString("0.000")); //} // So try to match first vert using autoscale and no flip bool mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx); if ( !mapped ) { flipyz = true; mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx); if ( !mapped ) //DoMapping(mod, morph, tm, mapping, scl, flipyz, negx) ) { flipyz = false; negx = true; mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx); if ( !mapped ) { flipyz = true; mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx); } } } if ( mapped ) { morph.importScale = scl; morph.flipyz = flipyz; morph.negx = negx; morph.mapping = mapping; // if mapping was ok set opoints morph.oPoints = tm.verts.ToArray(); for ( int i = 0; i < morph.oPoints.Length; i++ ) { Vector3 p = morph.oPoints[i]; if ( negx ) p.x = -p.x; if ( flipyz ) { float z = p.z; p.z = p.y; p.y = z; } morph.oPoints[i] = p * morph.importScale; } return true; } return false; }
// We should know the mapping // remove morph pass tolerance instead bool TryMapping1(MegaTargetMesh tm, MegaMorphOMatic morph) { MegaModifiers mod = morph.GetComponent <MegaModifiers>(); if (mod == null) { EditorUtility.DisplayDialog("Missing ModifyObject!", "No ModifyObject script found on the object", "OK"); return(false); } // Get extents for mod verts and for imported meshes, if not the same then scale Vector3 min1, max1; Vector3 min2, max2; Vector3 ex1 = MegaUtils.Extents(mod.verts, out min1, out max1); Vector3 ex2 = MegaUtils.Extents(tm.verts, out min2, out max2); // need min max on all axis so we can produce an offset to add float d1 = ex1.x; float d2 = ex2.x; float scl = d1 / d2; //d2 / d1; bool flipyz = false; bool negx = false; // So try to match first vert using autoscale and no flip bool mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if (!mapped) { flipyz = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if (!mapped) //DoMapping(mod, morph, tm, mapping, scl, flipyz, negx) ) { flipyz = false; negx = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if (!mapped) { flipyz = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); } } } if (mapped) { morph.importScale = scl; morph.flipyz = flipyz; morph.negx = negx; // if mapping was ok set opoints morph.oPoints = tm.verts.ToArray(); for (int i = 0; i < morph.oPoints.Length; i++) { Vector3 p = morph.oPoints[i]; if (negx) { p.x = -p.x; } if (flipyz) { float z = p.z; p.z = p.y; p.y = z; } morph.oPoints[i] = p * morph.importScale; } morph.mapping = new MegaMomVertMap[morph.oPoints.Length]; for (int i = 0; i < morph.oPoints.Length; i++) { //int[] indices = morph.FindVerts(morph.oPoints[i], mod); int[] indices = FindVerts(morph.oPoints[i], mod); morph.mapping[i] = new MegaMomVertMap(); morph.mapping[i].indices = indices; //morph.FindVerts(morph.oPoints[i], mod); } return(true); } return(false); }
// Fbx could have been exported any which way so still need to do try all mappings to find correct public bool ParseMorph(BinaryReader br, string id) { MegaMorph mr = (MegaMorph)target; //Debug.Log("ParseMorph " + id); switch ( id ) { case "Max": mr.Max = br.ReadSingle(); Debug.Log("Max " + mr.Max); break; case "Min": mr.Min = br.ReadSingle(); Debug.Log("Min " + mr.Min); break; case "UseLim": mr.UseLimit = (br.ReadInt32() == 1); Debug.Log("UseLim " + mr.UseLimit); break; case "StartPoints": // Mapping MegaTargetMesh tm = new MegaTargetMesh(); tm.verts = MegaParse.ReadP3l(br); // make a vector //Debug.Log("num " + tm.verts.Count); if ( !TryMapping1(tm, mr) ) { EditorUtility.DisplayDialog("Mapping Failed!", "Mapping failed! Please check the Morph page on the MegaFiers website for reasons for this", "OK"); EditorUtility.ClearProgressBar(); return false; } //Debug.Log("StartPoints " + tm.verts.Count); break; case "Channel": MegaMorphChan chan = LoadChan(br); if ( chan != null ) mr.chanBank.Add(chan); break; case "Animation": LoadAnimation(mr, br); break; default: return false; } return true; }
bool TryMapping(List <MegaTargetMesh> targets, MegaMorph morph) { MegaModifiers mod = morph.GetComponent <MegaModifiers>(); if (mod == null) { //Debug.Log("No modifyobject found"); EditorUtility.DisplayDialog("Missing ModifyObject!", "No ModifyObject script found on the object", "OK"); return(false); } int[] mapping = new int[mod.verts.Length]; for (int i = 0; i < 18; i++) { Debug.Log("v[" + i + "] " + mod.verts[i].ToString("0.00000")); } for (int i = 0; i < 18; i++) { Debug.Log("t[" + i + "] " + targets[0].verts[i].ToString("0.00000")); } for (int t = 0; t < targets.Count; t++) { MegaTargetMesh tm = targets[t]; // Get extents for mod verts and for imported meshes, if not the same then scale Vector3 min1, max1; Vector3 min2, max2; Vector3 ex1 = Extents(mod.verts, out min1, out max1); Vector3 ex2 = Extents(tm.verts, out min2, out max2); Debug.Log("min1 " + min1.ToString("0.000")); Debug.Log("max1 " + max1.ToString("0.000")); Debug.Log("min2 " + min2.ToString("0.000")); Debug.Log("max2 " + max2.ToString("0.000")); // need min max on all axis so we can produce an offset to add float d1 = ex1.x; float d2 = ex2.x; float scl = d1 / d2; //d2 / d1; bool flipyz = false; bool negx = false; //Vector3 offset = (min2 * scl) - min1; //Debug.Log("offset " + offset.ToString("0.0000")); Debug.Log("scl " + scl); // So try to match first vert using autoscale and no flip bool mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx); if (!mapped) { flipyz = true; mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx); if (!mapped) //DoMapping(mod, morph, tm, mapping, scl, flipyz, negx) ) { flipyz = false; negx = true; mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx); if (!mapped) { flipyz = true; mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx); } } } if (mapped) { morph.importScale = scl; morph.flipyz = flipyz; morph.negx = negx; morph.mapping = mapping; // if mapping was ok set opoints morph.oPoints = tm.verts.ToArray(); for (int i = 0; i < morph.oPoints.Length; i++) { Vector3 p = morph.oPoints[i]; if (negx) { p.x = -p.x; } if (flipyz) { float z = p.z; p.z = p.y; p.y = z; } morph.oPoints[i] = p * morph.importScale; } return(true); } } return(false); }
static public List <MegaTargetMesh> LoadTargets(string path, float scale, bool flipzy, bool negx) { List <MegaTargetMesh> targets = new List <MegaTargetMesh>(); MegaTargetMesh current = null; StreamReader stream = File.OpenText(path); string entireText = stream.ReadToEnd(); stream.Close(); entireText = entireText.Replace("\n", "\r\n"); List <Vector3> verts = new List <Vector3>(); using (StringReader reader = new StringReader(entireText)) { string currentText = reader.ReadLine(); char[] splitIdentifier = { ' ' }; string[] brokenString; string name = ""; Vector3 p = Vector3.zero; while (currentText != null) { if (!currentText.StartsWith("v ") && !currentText.StartsWith("g ") && !currentText.StartsWith("f ")) { currentText = reader.ReadLine(); if (currentText != null) { currentText = currentText.Replace(" ", " "); } } else { currentText = currentText.Trim(); brokenString = currentText.Split(splitIdentifier, 50); switch (brokenString[0]) { case "f": if (verts.Count > 0) { current = new MegaTargetMesh(); current.name = name; current.verts = new List <Vector3>(verts); current.faces = new List <int>(); targets.Add(current); verts.Clear(); } break; case "g": name = brokenString[1]; break; case "v": p.x = System.Convert.ToSingle(brokenString[1]) * scale; if (negx) { p.x = -p.x; } if (flipzy) { p.y = System.Convert.ToSingle(brokenString[3]) * scale; p.z = System.Convert.ToSingle(brokenString[2]) * scale; } else { p.y = System.Convert.ToSingle(brokenString[2]) * scale; p.z = System.Convert.ToSingle(brokenString[3]) * scale; } verts.Add(p); break; } currentText = reader.ReadLine(); if (currentText != null) { currentText = currentText.Replace(" ", " "); } } } } return(targets); }
// Fbx could have been exported any which way so still need to do try all mappings to find correct public bool ParseMorph(BinaryReader br, string id) { MegaMorphOMatic mr = (MegaMorphOMatic)target; switch ( id ) { case "Max": mr.Max = br.ReadSingle(); break; case "Min": mr.Min = br.ReadSingle(); break; case "UseLim": mr.UseLimit = (br.ReadInt32() == 1); break; // This will only be changed points, but we need scale case "StartPoints": // Mapping MegaTargetMesh tm = new MegaTargetMesh(); tm.verts = MegaParse.ReadP3l(br); // make a vector if ( !TryMapping1(tm, mr) ) { EditorUtility.DisplayDialog("Mapping Failed!", "Mapping failed!", "OK"); EditorUtility.ClearProgressBar(); return false; } break; case "Channel": mr.chanBank.Add(LoadChan(br)); break; case "Animation": LoadAnimation(mr, br); break; default: return false; } return true; }
// We should know the mapping // remove morph pass tolerance instead bool TryMapping1(MegaTargetMesh tm, MegaMorphOMatic morph) { MegaModifiers mod = morph.GetComponent<MegaModifiers>(); if ( mod == null ) { EditorUtility.DisplayDialog("Missing ModifyObject!", "No ModifyObject script found on the object", "OK"); return false; } // Get extents for mod verts and for imported meshes, if not the same then scale Vector3 min1,max1; Vector3 min2,max2; Vector3 ex1 = MegaUtils.Extents(mod.verts, out min1, out max1); Vector3 ex2 = MegaUtils.Extents(tm.verts, out min2, out max2); // need min max on all axis so we can produce an offset to add float d1 = ex1.x; float d2 = ex2.x; float scl = d1 / d2; //d2 / d1; bool flipyz = false; bool negx = false; // So try to match first vert using autoscale and no flip bool mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if ( !mapped ) { flipyz = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if ( !mapped ) //DoMapping(mod, morph, tm, mapping, scl, flipyz, negx) ) { flipyz = false; negx = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); if ( !mapped ) { flipyz = true; mapped = DoMapping(mod, morph, tm, scl, flipyz, negx); } } } if ( mapped ) { morph.importScale = scl; morph.flipyz = flipyz; morph.negx = negx; // if mapping was ok set opoints morph.oPoints = tm.verts.ToArray(); for ( int i = 0; i < morph.oPoints.Length; i++ ) { Vector3 p = morph.oPoints[i]; if ( negx ) p.x = -p.x; if ( flipyz ) { float z = p.z; p.z = p.y; p.y = z; } morph.oPoints[i] = p * morph.importScale; } morph.mapping = new MegaMomVertMap[morph.oPoints.Length]; for ( int i = 0; i < morph.oPoints.Length; i++ ) { //int[] indices = morph.FindVerts(morph.oPoints[i], mod); int[] indices = FindVerts(morph.oPoints[i], mod); morph.mapping[i] = new MegaMomVertMap(); morph.mapping[i].indices = indices; //morph.FindVerts(morph.oPoints[i], mod); } return true; } return false; }
bool DoMapping(MegaModifiers mod, MegaMorph morph, MegaTargetMesh tm, int[] mapping, float scale, bool flipyz, bool negx, bool negy) { int step = mod.verts.Length / 10; int count = 0; for ( int i = 0; i < mod.verts.Length; i++ ) { count--; if ( count < 0 ) { count = step; float a = (float)i / (float)mod.verts.Length; EditorUtility.DisplayProgressBar("Mapping", "Mapping vertex " + i, a); } mapping[i] = FindVert(mod.verts[i], tm.verts, morph.tolerance, scale, flipyz, negx, negy, i); if ( mapping[i] == -1 ) { // Failed EditorUtility.ClearProgressBar(); return false; } } EditorUtility.ClearProgressBar(); return true; }