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;
            }
        }
    }
Exemple #9
0
    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;
    }
Exemple #10
0
    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;
    }