Ejemplo n.º 1
0
    void DisplayDebug()
    {
        MegaWrap mod = (MegaWrap)target;

        if (mod.target)
        {
            if (mod.bindverts != null && mod.bindverts.Length > 0)
            {
                if (mod.targetIsSkin && !mod.sourceIsSkin)
                {
                    Color col = Color.black;
                    Handles.matrix = Matrix4x4.identity;

                    MegaBindVert bv = mod.bindverts[mod.vertindex];

                    for (int i = 0; i < bv.verts.Count; i++)
                    {
                        MegaBindInf bi = bv.verts[i];
                        float       w  = bv.verts[i].weight / bv.weight;

                        if (w > 0.5f)
                        {
                            col = Color.Lerp(Color.green, Color.red, (w - 0.5f) * 2.0f);
                        }
                        else
                        {
                            col = Color.Lerp(Color.blue, Color.green, w * 2.0f);
                        }
                        Handles.color = col;

                        Vector3 p = (mod.skinnedVerts[bv.verts[i].i0] + mod.skinnedVerts[bv.verts[i].i1] + mod.skinnedVerts[bv.verts[i].i2]) / 3.0f; //tm.MultiplyPoint(mod.vr[i].cpos);
                        Handles.DotCap(i, p, Quaternion.identity, mod.size);                                                                         //0.01f);

                        Vector3 p0 = mod.skinnedVerts[bi.i0];
                        Vector3 p1 = mod.skinnedVerts[bi.i1];
                        Vector3 p2 = mod.skinnedVerts[bi.i2];

                        Vector3 cp = mod.GetCoordMine(p0, p1, p2, bi.bary);
                        Handles.color = Color.gray;
                        Handles.DrawLine(p, cp);

                        Vector3 norm = mod.FaceNormal(p0, p1, p2);
                        Vector3 cp1  = cp + (((bi.dist * mod.shrink) + mod.gap) * norm.normalized);
                        Handles.color = Color.green;
                        Handles.DrawLine(cp, cp1);
                    }
                }
                else
                {
                    Color     col = Color.black;
                    Matrix4x4 tm  = mod.target.transform.localToWorldMatrix;
                    Handles.matrix = tm;                        //Matrix4x4.identity;

                    MegaBindVert bv = mod.bindverts[mod.vertindex];

                    for (int i = 0; i < bv.verts.Count; i++)
                    {
                        MegaBindInf bi = bv.verts[i];
                        float       w  = bv.verts[i].weight / bv.weight;

                        if (w > 0.5f)
                        {
                            col = Color.Lerp(Color.green, Color.red, (w - 0.5f) * 2.0f);
                        }
                        else
                        {
                            col = Color.Lerp(Color.blue, Color.green, w * 2.0f);
                        }
                        Handles.color = col;

                        Vector3 p = (mod.target.sverts[bv.verts[i].i0] + mod.target.sverts[bv.verts[i].i1] + mod.target.sverts[bv.verts[i].i2]) / 3.0f; //tm.MultiplyPoint(mod.vr[i].cpos);
                        Handles.DotCap(i, p, Quaternion.identity, mod.size);                                                                            //0.01f);

                        Vector3 p0 = mod.target.sverts[bi.i0];
                        Vector3 p1 = mod.target.sverts[bi.i1];
                        Vector3 p2 = mod.target.sverts[bi.i2];

                        Vector3 cp = mod.GetCoordMine(p0, p1, p2, bi.bary);
                        Handles.color = Color.gray;
                        Handles.DrawLine(p, cp);

                        Vector3 norm = mod.FaceNormal(p0, p1, p2);
                        Vector3 cp1  = cp + (((bi.dist * mod.shrink) + mod.gap) * norm.normalized);
                        Handles.color = Color.green;
                        Handles.DrawLine(cp, cp1);
                    }
                }

                // Show unmapped verts
                Handles.color = Color.yellow;
                for (int i = 0; i < mod.bindverts.Length; i++)
                {
                    if (mod.bindverts[i].weight == 0.0f)
                    {
                        Vector3 pv1 = mod.freeverts[i];
                        Handles.DotCap(0, pv1, Quaternion.identity, mod.size);                          //0.01f);
                    }
                }
            }

            if (mod.verts != null && mod.verts.Length > mod.vertindex)
            {
                Handles.color  = Color.red;
                Handles.matrix = mod.transform.localToWorldMatrix;
                Vector3 pv = mod.verts[mod.vertindex];
                Handles.DotCap(0, pv, Quaternion.identity, mod.size);                   //0.01f);
            }
        }
    }
Ejemplo n.º 2
0
    void DoUpdate()
    {
        if (source == null || WrapEnabled == false || target == null || source.bindverts == null)               //|| bindposes == null )
        {
            return;
        }

        if (targetIsSkin && source.neededVerts != null && source.neededVerts.Count > 0)
        {
            if (source.boneweights == null)
            {
                SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
                if (tmesh != null)
                {
                    if (!sourceIsSkin)
                    {
                        Mesh sm = tmesh.sharedMesh;
                        bindposes          = sm.bindposes;
                        source.boneweights = sm.boneWeights;
                    }
                }
            }

            for (int i = 0; i < source.neededVerts.Count; i++)
            {
                skinnedVerts[source.neededVerts[i]] = GetSkinPos(source, source.neededVerts[i]);
            }
        }

        Vector3 p = Vector3.zero;

        if (targetIsSkin && !sourceIsSkin)
        {
            for (int i = 0; i < source.bindverts.Length; i++)
            {
                if (source.bindverts[i].verts.Count > 0)
                {
                    p = Vector3.zero;

                    for (int j = 0; j < source.bindverts[i].verts.Count; j++)
                    {
                        MegaBindInf bi = source.bindverts[i].verts[j];

                        Vector3 p0 = skinnedVerts[bi.i0];
                        Vector3 p1 = skinnedVerts[bi.i1];
                        Vector3 p2 = skinnedVerts[bi.i2];

                        Vector3 cp   = GetCoordMine(p0, p1, p2, bi.bary);
                        Vector3 norm = FaceNormal(p0, p1, p2);
                        cp += ((bi.dist * shrink) + gap) * norm.normalized;
                        p  += cp * (bi.weight / source.bindverts[i].weight);
                    }

                    verts[i] = transform.InverseTransformPoint(p) + offset;
                }
            }
        }
        else
        {
            for (int i = 0; i < source.bindverts.Length; i++)
            {
                if (source.bindverts[i].verts.Count > 0)
                {
                    p = Vector3.zero;

                    for (int j = 0; j < source.bindverts[i].verts.Count; j++)
                    {
                        MegaBindInf bi = source.bindverts[i].verts[j];

                        Vector3 p0 = target.sverts[bi.i0];
                        Vector3 p1 = target.sverts[bi.i1];
                        Vector3 p2 = target.sverts[bi.i2];

                        Vector3 cp   = GetCoordMine(p0, p1, p2, bi.bary);
                        Vector3 norm = FaceNormal(p0, p1, p2);
                        cp += ((bi.dist * shrink) + gap) * norm.normalized;
                        p  += cp * (bi.weight / source.bindverts[i].weight);
                    }
                }
                else
                {
                    p = source.freeverts[i];                            //startverts[i];
                }
                p        = target.transform.TransformPoint(p);
                verts[i] = transform.InverseTransformPoint(p) + offset;
            }
        }

        mesh.vertices = verts;
        RecalcNormals();
        mesh.RecalculateBounds();
    }
Ejemplo n.º 3
0
    public void Attach(MegaModifyObject modobj)
    {
        targetIsSkin = false;
        sourceIsSkin = false;

        if (mesh && startverts != null)
        {
            mesh.vertices = startverts;
        }

        if (modobj == null)
        {
            bindverts = null;
            return;
        }

        nomapcount = 0;

        if (mesh)
        {
            mesh.vertices = startverts;
        }

        MeshFilter mf      = GetComponent <MeshFilter>();
        Mesh       srcmesh = null;

        if (mf != null)
        {
            //skinned = false;
            srcmesh = mf.mesh;
        }
        else
        {
            SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));

            if (smesh != null)
            {
                //skinned = true;
                srcmesh      = smesh.sharedMesh;
                sourceIsSkin = true;
            }
        }

        if (srcmesh == null)
        {
            Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
            return;
        }

        if (mesh == null)
        {
            mesh = CloneMesh(srcmesh);                  //mf.mesh);
        }
        if (mf)
        {
            mf.mesh = mesh;
        }
        else
        {
            SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
            smesh.sharedMesh = mesh;
        }

        if (sourceIsSkin == false)
        {
            SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
            if (tmesh != null)
            {
                targetIsSkin = true;

                if (!sourceIsSkin)
                {
                    Mesh sm = tmesh.sharedMesh;
                    bindposes    = sm.bindposes;
                    boneweights  = sm.boneWeights;
                    bones        = tmesh.bones;
                    skinnedVerts = sm.vertices;                         //new Vector3[sm.vertexCount];
                }
            }
        }

        if (targetIsSkin)
        {
            if (boneweights == null || boneweights.Length == 0)
            {
                targetIsSkin = false;
            }
        }

        neededVerts.Clear();

        verts      = mesh.vertices;
        startverts = mesh.vertices;
        freeverts  = new Vector3[startverts.Length];
        Vector3[] baseverts = modobj.verts;     //basemesh.vertices;
        int[]     basefaces = modobj.tris;      //basemesh.triangles;

        bindverts = new MegaBindVert[verts.Length];

        // matrix to get vertex into local space of target
        Matrix4x4 tm = transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;

        List <MegaCloseFace> closefaces = new List <MegaCloseFace>();

        Vector3 p0 = Vector3.zero;
        Vector3 p1 = Vector3.zero;
        Vector3 p2 = Vector3.zero;

        for (int i = 0; i < verts.Length; i++)
        {
            MegaBindVert bv = new MegaBindVert();
            bindverts[i] = bv;

            Vector3 p = tm.MultiplyPoint(verts[i]);

            p            = transform.TransformPoint(verts[i]);
            p            = modobj.transform.InverseTransformPoint(p);
            freeverts[i] = p;

            closefaces.Clear();

            for (int t = 0; t < basefaces.Length; t += 3)
            {
                if (targetIsSkin && !sourceIsSkin)
                {
                    p0 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t]));
                    p1 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 1]));
                    p2 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 2]));
                }
                else
                {
                    p0 = baseverts[basefaces[t]];
                    p1 = baseverts[basefaces[t + 1]];
                    p2 = baseverts[basefaces[t + 2]];
                }

                float dist = GetDistance(p, p0, p1, p2);

                if (Mathf.Abs(dist) < maxdist)
                {
                    MegaCloseFace cf = new MegaCloseFace();
                    cf.dist = Mathf.Abs(dist);
                    cf.face = t;

                    bool inserted = false;
                    for (int k = 0; k < closefaces.Count; k++)
                    {
                        if (cf.dist < closefaces[k].dist)
                        {
                            closefaces.Insert(k, cf);
                            inserted = true;
                            break;
                        }
                    }

                    if (!inserted)
                    {
                        closefaces.Add(cf);
                    }
                }
            }

            float tweight = 0.0f;
            int   maxp    = maxpoints;
            if (maxp == 0)
            {
                maxp = closefaces.Count;
            }

            for (int j = 0; j < maxp; j++)
            {
                if (j < closefaces.Count)
                {
                    int t = closefaces[j].face;

                    if (targetIsSkin && !sourceIsSkin)
                    {
                        p0 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t]));
                        p1 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 1]));
                        p2 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 2]));
                    }
                    else
                    {
                        p0 = baseverts[basefaces[t]];
                        p1 = baseverts[basefaces[t + 1]];
                        p2 = baseverts[basefaces[t + 2]];
                    }

                    Vector3 normal = FaceNormal(p0, p1, p2);

                    float dist = closefaces[j].dist;                            //GetDistance(p, p0, p1, p2);

                    MegaBindInf bi = new MegaBindInf();
                    bi.dist   = GetPlaneDistance(p, p0, p1, p2);                        //dist;
                    bi.face   = t;
                    bi.i0     = basefaces[t];
                    bi.i1     = basefaces[t + 1];
                    bi.i2     = basefaces[t + 2];
                    bi.bary   = CalcBary(p, p0, p1, p2);
                    bi.weight = 1.0f / (1.0f + dist);
                    bi.area   = normal.magnitude * 0.5f;                        //CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]);	// Could calc once at start
                    tweight  += bi.weight;
                    bv.verts.Add(bi);
                }
            }

            if (maxpoints > 0 && maxpoints < bv.verts.Count)
            {
                bv.verts.RemoveRange(maxpoints, bv.verts.Count - maxpoints);
            }

            // Only want to calculate skin vertices we use
            if (!sourceIsSkin && targetIsSkin)
            {
                for (int fi = 0; fi < bv.verts.Count; fi++)
                {
                    if (!neededVerts.Contains(bv.verts[fi].i0))
                    {
                        neededVerts.Add(bv.verts[fi].i0);
                    }

                    if (!neededVerts.Contains(bv.verts[fi].i1))
                    {
                        neededVerts.Add(bv.verts[fi].i1);
                    }

                    if (!neededVerts.Contains(bv.verts[fi].i2))
                    {
                        neededVerts.Add(bv.verts[fi].i2);
                    }
                }
            }

            if (tweight == 0.0f)
            {
                nomapcount++;
            }

            bv.weight = tweight;
        }
    }
Ejemplo n.º 4
0
    void DoUpdate()
    {
        if (WrapEnabled == false || target == null || bindverts == null)                //|| bindposes == null )
        {
            return;
        }

        if (mesh == null)
        {
            SetMesh();
        }

        if (mesh == null)
        {
            return;
        }

        if (targetIsSkin && neededVerts != null && neededVerts.Count > 0)           //|| (targetIsSkin && boneweights == null) )
        {
            if (boneweights == null || tmesh == null)
            {
                tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
                if (tmesh != null)
                {
                    if (!sourceIsSkin)
                    {
                        Mesh sm = tmesh.sharedMesh;
                        bindposes   = sm.bindposes;
                        bones       = tmesh.bones;
                        boneweights = sm.boneWeights;
                    }
                }
            }

#if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
            if (tmesh == null)
            {
                tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
            }

            if (UseBakedMesh)
            {
                if (bakedmesh == null)
                {
                    bakedmesh = new Mesh();
                }

                tmesh.BakeMesh(bakedmesh);
                skinnedVerts = bakedmesh.vertices;
            }
            else
            {
                for (int i = 0; i < neededVerts.Count; i++)
                {
                    skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]);
                }
            }
#else
            for (int i = 0; i < neededVerts.Count; i++)
            {
                skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]);
            }
#endif
        }

        Matrix4x4 stm = Matrix4x4.identity;

        Vector3 p = Vector3.zero;
        if (targetIsSkin && !sourceIsSkin)
        {
#if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
            if (UseBakedMesh)
            {
                stm = transform.worldToLocalMatrix * target.transform.localToWorldMatrix;                       // * transform.worldToLocalMatrix;
            }
            else
            {
                stm = transform.worldToLocalMatrix;                     // * target.transform.localToWorldMatrix;	// * transform.worldToLocalMatrix;
            }
#else
            stm = transform.worldToLocalMatrix;                 // * target.transform.localToWorldMatrix;	// * transform.worldToLocalMatrix;
#endif

            for (int i = 0; i < bindverts.Length; i++)
            {
                if (bindverts[i].verts.Count > 0)
                {
                    p = Vector3.zero;
                    float oow = 1.0f / bindverts[i].weight;

                    int cnt = bindverts[i].verts.Count;

                    for (int j = 0; j < cnt; j++)
                    {
                        MegaBindInf bi = bindverts[i].verts[j];

                        Vector3 p0 = skinnedVerts[bi.i0];
                        Vector3 p1 = skinnedVerts[bi.i1];
                        Vector3 p2 = skinnedVerts[bi.i2];

                        Vector3 cp   = GetCoordMine(p0, p1, p2, bi.bary);
                        Vector3 norm = FaceNormal(p0, p1, p2);

                        float sq = 1.0f / Mathf.Sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);

                        float d = (bi.dist * shrink) + gap;

                        //cp += d * norm.x;
                        cp.x += d * norm.x * sq;
                        cp.y += d * norm.y * sq;
                        cp.z += d * norm.z * sq;

                        float bw = bi.weight * oow;

                        if (j == 0)
                        {
                            p.x = cp.x * bw;
                            p.y = cp.y * bw;
                            p.z = cp.z * bw;
                        }
                        else
                        {
                            p.x += cp.x * bw;
                            p.y += cp.y * bw;
                            p.z += cp.z * bw;
                        }
                        //cp += ((bi.dist * shrink) + gap) * norm.normalized;
                        //p += cp * (bi.weight / bindverts[i].weight);
                    }

                    Vector3 pp = stm.MultiplyPoint3x4(p);

                    verts[i].x = pp.x + offset.x;
                    verts[i].y = pp.y + offset.y;
                    verts[i].z = pp.z + offset.z;
                    //verts[i] = transform.InverseTransformPoint(p) + offset;
                }
            }
        }
        else
        {
            stm = transform.worldToLocalMatrix * target.transform.localToWorldMatrix;                   // * transform.worldToLocalMatrix;
            //Matrix4x4 tm = target.transform.localToWorldMatrix;

            for (int i = 0; i < bindverts.Length; i++)
            {
                if (bindverts[i].verts.Count > 0)
                {
                    p = Vector3.zero;
                    float oow = 1.0f / bindverts[i].weight;

                    for (int j = 0; j < bindverts[i].verts.Count; j++)
                    {
                        MegaBindInf bi = bindverts[i].verts[j];

                        Vector3 p0 = target.sverts[bi.i0];
                        Vector3 p1 = target.sverts[bi.i1];
                        Vector3 p2 = target.sverts[bi.i2];

                        Vector3 cp   = GetCoordMine(p0, p1, p2, bi.bary);
                        Vector3 norm = FaceNormal(p0, p1, p2);

                        float sq = 1.0f / Mathf.Sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);

                        float d = (bi.dist * shrink) + gap;

                        //cp += d * norm.x;
                        cp.x += d * norm.x * sq;
                        cp.y += d * norm.y * sq;
                        cp.z += d * norm.z * sq;

                        float bw = bi.weight * oow;

                        if (j == 0)
                        {
                            p.x = cp.x * bw;
                            p.y = cp.y * bw;
                            p.z = cp.z * bw;
                        }
                        else
                        {
                            p.x += cp.x * bw;
                            p.y += cp.y * bw;
                            p.z += cp.z * bw;
                        }

                        //cp += ((bi.dist * shrink) + gap) * norm.normalized;
                        //p += cp * (bi.weight / bindverts[i].weight);
                    }
                }
                else
                {
                    p = freeverts[i];                           //startverts[i];
                }
                Vector3 pp = stm.MultiplyPoint3x4(p);

                verts[i].x = pp.x + offset.x;
                verts[i].y = pp.y + offset.y;
                verts[i].z = pp.z + offset.z;

                //p = target.transform.TransformPoint(p);
                //verts[i] = transform.InverseTransformPoint(p) + offset;
            }
        }

        mesh.vertices = verts;
        RecalcNormals();
        mesh.RecalculateBounds();
    }
Ejemplo n.º 5
0
    void Attach(MegaModifyObject modobj)
    {
        MegaWrap mod = (MegaWrap)target;

        mod.targetIsSkin = false;
        mod.sourceIsSkin = false;

        if (mod.mesh && mod.startverts != null)
        {
            mod.mesh.vertices = mod.startverts;
        }

        if (modobj == null)
        {
            mod.bindverts = null;
            return;
        }

        mod.nomapcount = 0;

        if (mod.mesh)
        {
            mod.mesh.vertices = mod.startverts;
        }

        MeshFilter mf      = mod.GetComponent <MeshFilter>();
        Mesh       srcmesh = null;

        if (mf != null)
        {
            //skinned = false;
            srcmesh = mf.sharedMesh;
        }
        else
        {
            SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));

            if (smesh != null)
            {
                //skinned = true;
                srcmesh          = smesh.sharedMesh;
                mod.sourceIsSkin = true;
            }
        }

        if (srcmesh == null)
        {
            Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
            return;
        }

        if (mod.mesh == null)
        {
            mod.mesh = mod.CloneMesh(srcmesh);                  //mf.mesh);
        }
        if (mf)
        {
            mf.mesh = mod.mesh;
        }
        else
        {
            SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));
            smesh.sharedMesh = mod.mesh;
        }

        if (mod.sourceIsSkin == false)
        {
            SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
            if (tmesh != null)
            {
                mod.targetIsSkin = true;

                if (!mod.sourceIsSkin)
                {
                    Mesh sm = tmesh.sharedMesh;
                    mod.bindposes    = sm.bindposes;
                    mod.boneweights  = sm.boneWeights;
                    mod.bones        = tmesh.bones;
                    mod.skinnedVerts = sm.vertices;                     //new Vector3[sm.vertexCount];
                }
            }
        }

        if (mod.targetIsSkin)
        {
            if (mod.boneweights == null || mod.boneweights.Length == 0)
            {
                mod.targetIsSkin = false;
            }
        }

        mod.neededVerts.Clear();

        mod.verts      = mod.mesh.vertices;
        mod.startverts = mod.mesh.vertices;
        mod.freeverts  = new Vector3[mod.startverts.Length];
        Vector3[] baseverts = modobj.verts;     //basemesh.vertices;
        int[]     basefaces = modobj.tris;      //basemesh.triangles;

        mod.bindverts = new MegaBindVert[mod.verts.Length];

        // matrix to get vertex into local space of target
        Matrix4x4 tm = mod.transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;

        List <MegaCloseFace> closefaces = new List <MegaCloseFace>();

        Vector3 p0 = Vector3.zero;
        Vector3 p1 = Vector3.zero;
        Vector3 p2 = Vector3.zero;

        Vector3[] tverts = new Vector3[mod.target.sverts.Length];

        for (int i = 0; i < tverts.Length; i++)
        {
            if (mod.targetIsSkin && !mod.sourceIsSkin)
            {
                tverts[i] = modobj.transform.InverseTransformPoint(mod.GetSkinPos(i));
            }
            else
            {
                tverts[i] = baseverts[i];
            }
        }

        EditorUtility.ClearProgressBar();

        float unit = 0.0f;

        mod.target.mesh.RecalculateBounds();
        MegaVoxel.Voxelize(tverts, basefaces, mod.target.mesh.bounds, 16, out unit);

        //Vector3 min = mod.target.mesh.bounds.min;

        for (int i = 0; i < mod.verts.Length; i++)
        {
            MegaBindVert bv = new MegaBindVert();
            mod.bindverts[i] = bv;

            Vector3 p = tm.MultiplyPoint(mod.verts[i]);

            p = mod.transform.TransformPoint(mod.verts[i]);
            p = modobj.transform.InverseTransformPoint(p);
            mod.freeverts[i] = p;

            closefaces.Clear();

            int gx = 0;
            int gy = 0;
            int gz = 0;

            MegaVoxel.GetGridIndex(p, out gx, out gy, out gz, unit);

            for (int x = gx - 1; x <= gx + 1; x++)
            {
                if (x >= 0 && x < MegaVoxel.width)
                {
                    for (int y = gy - 1; y <= gy + 1; y++)
                    {
                        if (y >= 0 && y < MegaVoxel.height)
                        {
                            for (int z = gz - 1; z <= gz + 1; z++)
                            {
                                if (z >= 0 && z < MegaVoxel.depth)
                                {
                                    List <MegaTriangle> tris = MegaVoxel.volume[x, y, z].tris;

                                    for (int t = 0; t < tris.Count; t++)
                                    {
                                        float dist = mod.GetDistance(p, tris[t].a, tris[t].b, tris[t].c);

                                        if (Mathf.Abs(dist) < mod.maxdist)
                                        {
                                            MegaCloseFace cf = new MegaCloseFace();
                                            cf.dist = Mathf.Abs(dist);
                                            cf.face = tris[t].t;

                                            bool inserted = false;
                                            for (int k = 0; k < closefaces.Count; k++)
                                            {
                                                if (cf.dist < closefaces[k].dist)
                                                {
                                                    closefaces.Insert(k, cf);
                                                    inserted = true;
                                                    break;
                                                }
                                            }

                                            if (!inserted)
                                            {
                                                closefaces.Add(cf);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            float tweight = 0.0f;
            int   maxp    = mod.maxpoints;
            if (maxp == 0)
            {
                maxp = closefaces.Count;
            }
            for (int j = 0; j < maxp; j++)
            {
                if (j < closefaces.Count)
                {
                    int t = closefaces[j].face;

                    p0 = tverts[basefaces[t]];
                    p1 = tverts[basefaces[t + 1]];
                    p2 = tverts[basefaces[t + 2]];

                    Vector3 normal = mod.FaceNormal(p0, p1, p2);

                    float dist = closefaces[j].dist;                            //GetDistance(p, p0, p1, p2);

                    MegaBindInf bi = new MegaBindInf();
                    bi.dist   = mod.GetPlaneDistance(p, p0, p1, p2);                    //dist;
                    bi.face   = t;
                    bi.i0     = basefaces[t];
                    bi.i1     = basefaces[t + 1];
                    bi.i2     = basefaces[t + 2];
                    bi.bary   = mod.CalcBary(p, p0, p1, p2);
                    bi.weight = 1.0f / (1.0f + dist);
                    bi.area   = normal.magnitude * 0.5f;                        //CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]);	// Could calc once at start
                    tweight  += bi.weight;
                    bv.verts.Add(bi);
                }
            }

            if (mod.maxpoints > 0 && mod.maxpoints < bv.verts.Count)
            {
                bv.verts.RemoveRange(mod.maxpoints, bv.verts.Count - mod.maxpoints);
            }

            // Only want to calculate skin vertices we use
            if (!mod.sourceIsSkin && mod.targetIsSkin)
            {
                for (int fi = 0; fi < bv.verts.Count; fi++)
                {
                    if (!mod.neededVerts.Contains(bv.verts[fi].i0))
                    {
                        mod.neededVerts.Add(bv.verts[fi].i0);
                    }

                    if (!mod.neededVerts.Contains(bv.verts[fi].i1))
                    {
                        mod.neededVerts.Add(bv.verts[fi].i1);
                    }

                    if (!mod.neededVerts.Contains(bv.verts[fi].i2))
                    {
                        mod.neededVerts.Add(bv.verts[fi].i2);
                    }
                }
            }

            if (tweight == 0.0f)
            {
                mod.nomapcount++;
                break;
            }

            bv.weight = tweight;
        }
    }
Ejemplo n.º 6
0
	public void Attach(MegaModifyObject modobj)
	{
		if ( mesh && startverts != null )
			mesh.vertices = startverts;

		if ( modobj == null )
		{
			bindverts = null;
			return;
		}

		nomapcount = 0;

		if ( mesh )
			mesh.vertices = startverts;

		MeshFilter mf = GetComponent<MeshFilter>();
		Mesh srcmesh = null;

		if ( mf != null )
		{
			skinned = false;
			srcmesh = mf.mesh;
		}
		else
		{
			SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));

			if ( smesh != null )
			{
				skinned = true;
				srcmesh = smesh.sharedMesh;
			}
		}

		if ( mesh == null )
			mesh = CloneMesh(srcmesh);	//mf.mesh);

		if ( mf )
			mf.mesh = mesh;
		else
		{
			SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
			smesh.sharedMesh = mesh;
		}

		//Mesh basemesh = MegaUtils.GetMesh(go);

		verts = mesh.vertices;
		startverts = mesh.vertices;
		freeverts = new Vector3[startverts.Length];
		Vector3[] baseverts = modobj.verts;	//basemesh.vertices;
		int[] basefaces = modobj.tris;	//basemesh.triangles;

		bindverts = new MegaBindVert[verts.Length];

		// matrix to get vertex into local space of target
		Matrix4x4 tm = transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;


		List<MegaCloseFace> closefaces = new List<MegaCloseFace>();

		for ( int i = 0; i < verts.Length; i++ )
		{
			//Debug.Log("i " + i + " " + verts[i]);
			MegaBindVert bv = new MegaBindVert();
			bindverts[i] = bv;

			Vector3 p = tm.MultiplyPoint(verts[i]);
			//Debug.Log("p " + p);

			p = transform.TransformPoint(verts[i]);
			p = modobj.transform.InverseTransformPoint(p);
			freeverts[i] = p;
			//Debug.Log("p " + p);

			closefaces.Clear();



			for ( int t = 0; t < basefaces.Length; t += 3 )
			{
				Vector3 p0 = baseverts[basefaces[t]];
				Vector3 p1 = baseverts[basefaces[t + 1]];
				Vector3 p2 = baseverts[basefaces[t + 2]];

				//Vector3 normal = FaceNormal(p0, p1, p2);

				float dist = GetDistance(p, p0, p1, p2);

				if ( Mathf.Abs(dist) < maxdist )
				{
					MegaCloseFace cf = new MegaCloseFace();
					cf.dist = Mathf.Abs(dist);
					cf.face = t;

					bool inserted = false;
					for ( int k = 0; k < closefaces.Count; k++ )
					{
						if ( cf.dist < closefaces[k].dist )
						{
							closefaces.Insert(k, cf);
							inserted = true;
							break;
						}
					}

					if ( !inserted )
					{
						closefaces.Add(cf);
					}
				}
			}


			float tweight = 0.0f;
			int maxp = maxpoints;
			if ( maxp == 0 )
			{
				maxp = closefaces.Count;
			}

			for ( int j = 0; j < maxp; j++ )
			{
				int t = closefaces[j].face;

				Vector3 p0 = baseverts[basefaces[t]];
				Vector3 p1 = baseverts[basefaces[t + 1]];
				Vector3 p2 = baseverts[basefaces[t + 2]];
				//Debug.Log("Face " + p0 + " " + p1 + " " + p2);

				Vector3 normal = FaceNormal(p0, p1, p2);

				//float dot = Vector3.Dot(normal, p - p0);
#if true
				//Debug.Log("Dot " + dot);
				//if ( dot > 0.0f )
				{
					float dist = closefaces[j].dist;	//GetDistance(p, p0, p1, p2);

					//Debug.Log("Dist " + dist);
					//if ( dist >= 0.0f && dist < maxdist )
					//if ( Mathf.Abs(dist) < maxdist )
					{
						MegaBindInf bi = new MegaBindInf();
						bi.dist = GetPlaneDistance(p, p0, p1, p2);	//dist;
						bi.face = t;
						bi.i0 = basefaces[t];
						bi.i1 = basefaces[t + 1];
						bi.i2 = basefaces[t + 2];
						bi.bary = CalcBary(p, p0, p1, p2);
						//Debug.Log("Bary " + bi.bary);
						bi.weight = 1.0f / (1.0f + dist);
						bi.area = normal.magnitude * 0.5f;	//CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]);	// Could calc once at start
						//Debug.Log("Weight " + bi.weight + " area " + bi.area);
						tweight += bi.weight;
						bv.verts.Add(bi);

						//if ( maxpoints > 0 && bv.verts.Count >= maxpoints )
						//	break;
					}
				}
#endif
			}

			if ( maxpoints > 0 )
			{
				bv.verts.RemoveRange(maxpoints, bv.verts.Count - maxpoints);
			}


			if ( tweight == 0.0f )
			{
				nomapcount++;
			}

			//Debug.Log("TWeight " + tweight);
			bv.weight = tweight;
		}
		// for each vert, find faces that are close enough and thatvert is above
		// find closest point on that face
		// calc bary coord and find distance from plane of face
		// calc area of face for weighting
		// keep track of all faces in range for combined weight
	}
Ejemplo n.º 7
0
	public void AttachOld(MegaModifyObject modobj)
	{
		if ( mesh && startverts != null )
			mesh.vertices = startverts;

		if ( modobj == null )
		{
			bindverts = null;
			return;
		}

		nomapcount = 0;

		if ( mesh )
			mesh.vertices = startverts;

		MeshFilter mf = GetComponent<MeshFilter>();

		if ( mesh == null )
			mesh = CloneMesh(mf.mesh);

		mf.mesh = mesh;

		//Mesh basemesh = MegaUtils.GetMesh(go);

		verts = mesh.vertices;
		startverts = mesh.vertices;
		freeverts = new Vector3[startverts.Length];
		Vector3[] baseverts = modobj.verts;	//basemesh.vertices;
		int[] basefaces = modobj.tris;	//basemesh.triangles;

		bindverts = new MegaBindVert[verts.Length];

		// matrix to get vertex into local space of target
		Matrix4x4 tm = transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;

		for ( int i = 0; i < verts.Length; i++ )
		{
			//Debug.Log("i " + i + " " + verts[i]);
			MegaBindVert bv = new MegaBindVert();
			bindverts[i] = bv;

			Vector3 p = tm.MultiplyPoint(verts[i]);
			//Debug.Log("p " + p);

			p = transform.TransformPoint(verts[i]);
			p = modobj.transform.InverseTransformPoint(p);
			freeverts[i] = p;
			//Debug.Log("p " + p);

			float tweight = 0.0f;
			for ( int t = 0; t < basefaces.Length; t += 3 )
			{
				Vector3 p0 = baseverts[basefaces[t]];
				Vector3 p1 = baseverts[basefaces[t + 1]];
				Vector3 p2 = baseverts[basefaces[t + 2]];
				//Debug.Log("Face " + p0 + " " + p1 + " " + p2);

				Vector3 normal = FaceNormal(p0, p1, p2);

				//float dot = Vector3.Dot(normal, p - p0);
#if true
				//Debug.Log("Dot " + dot);
				//if ( dot > 0.0f )
				{
					float dist = GetDistance(p, p0, p1, p2);

					//Debug.Log("Dist " + dist);
					//if ( dist >= 0.0f && dist < maxdist )
					if ( Mathf.Abs(dist) < maxdist )
					{
						MegaBindInf bi = new MegaBindInf();
						bi.dist = GetPlaneDistance(p, p0, p1, p2);	//dist;
						bi.face = t;
						bi.i0 = basefaces[t];
						bi.i1 = basefaces[t + 1];
						bi.i2 = basefaces[t + 2];
						bi.bary = CalcBary(p, p0, p1, p2);
						//Debug.Log("Bary " + bi.bary);
						bi.weight = 1.0f / (1.0f + dist);
						bi.area = normal.magnitude * 0.5f;	//CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]);	// Could calc once at start
						//Debug.Log("Weight " + bi.weight + " area " + bi.area);
						tweight += bi.weight;
						bv.verts.Add(bi);

						if ( maxpoints > 0 && bv.verts.Count >= maxpoints )
							break;
					}
				}
#endif
			}



			if ( tweight == 0.0f )
			{
				nomapcount++;
			}

			//Debug.Log("TWeight " + tweight);
			bv.weight = tweight;
		}
		// for each vert, find faces that are close enough and thatvert is above
		// find closest point on that face
		// calc bary coord and find distance from plane of face
		// calc area of face for weighting
		// keep track of all faces in range for combined weight
	}
Ejemplo n.º 8
0
    void Attach(MegaModifyObject modobj)
    {
        MegaWrap mod = (MegaWrap)target;

        mod.targetIsSkin = false;
        mod.sourceIsSkin = false;

        if (mod.mesh && mod.startverts != null)
        {
            mod.mesh.vertices = mod.startverts;
        }

        if (modobj == null)
        {
            mod.bindverts = null;
            return;
        }

        mod.nomapcount = 0;

        if (mod.mesh)
        {
            mod.mesh.vertices = mod.startverts;
        }

        MeshFilter mf      = mod.GetComponent <MeshFilter>();
        Mesh       srcmesh = null;

        if (mf != null)
        {
            //skinned = false;
            srcmesh = mf.sharedMesh;
        }
        else
        {
            SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));

            if (smesh != null)
            {
                //skinned = true;
                srcmesh          = smesh.sharedMesh;
                mod.sourceIsSkin = true;
            }
        }

        if (srcmesh == null)
        {
            Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
            return;
        }

        if (mod.mesh == null)
        {
            mod.mesh = mod.CloneMesh(srcmesh);                  //mf.mesh);
        }
        if (mf)
        {
            mf.mesh = mod.mesh;
        }
        else
        {
            SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));
            smesh.sharedMesh = mod.mesh;
        }

        if (mod.sourceIsSkin == false)
        {
            SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
            if (tmesh != null)
            {
                mod.targetIsSkin = true;

                if (!mod.sourceIsSkin)
                {
                    Mesh sm = tmesh.sharedMesh;
                    mod.bindposes    = sm.bindposes;
                    mod.boneweights  = sm.boneWeights;
                    mod.bones        = tmesh.bones;
                    mod.skinnedVerts = sm.vertices;                     //new Vector3[sm.vertexCount];
                }
            }
        }

        if (mod.targetIsSkin)
        {
            if (mod.boneweights == null || mod.boneweights.Length == 0)
            {
                mod.targetIsSkin = false;
            }
        }

        mod.neededVerts.Clear();

        mod.verts      = mod.mesh.vertices;
        mod.startverts = mod.mesh.vertices;
        mod.freeverts  = new Vector3[mod.startverts.Length];
        Vector3[] baseverts = modobj.verts;     //basemesh.vertices;
        int[]     basefaces = modobj.tris;      //basemesh.triangles;

        mod.bindverts = new MegaBindVert[mod.verts.Length];

        // matrix to get vertex into local space of target
        Matrix4x4 tm = mod.transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;

        List <MegaCloseFace> closefaces = new List <MegaCloseFace>();

        Vector3 p0 = Vector3.zero;
        Vector3 p1 = Vector3.zero;
        Vector3 p2 = Vector3.zero;

        Vector3[] tverts = new Vector3[mod.target.sverts.Length];

        int tcount = 10;

        for (int i = 0; i < tverts.Length; i++)
        {
            tcount--;
            if (tcount < 0)
            {
                tcount = 10;
                EditorUtility.DisplayProgressBar("Calc vertex positions", "Vertex " + i + " of " + tverts.Length, (float)i / (float)tverts.Length);
            }

            if (mod.targetIsSkin && !mod.sourceIsSkin)
            {
                tverts[i] = modobj.transform.InverseTransformPoint(mod.GetSkinPos(i));
            }
            else
            {
                tverts[i] = baseverts[i];
            }
        }

        EditorUtility.ClearProgressBar();

        for (int i = 0; i < mod.verts.Length; i++)
        {
            if (EditorUtility.DisplayCancelableProgressBar("Wrap Mapping", "Mapping Vertex " + i + " of " + mod.verts.Length, (float)i / (float)mod.verts.Length))
            {
                mod.bindverts = null;
                break;
            }

            MegaBindVert bv = new MegaBindVert();
            mod.bindverts[i] = bv;

            Vector3 p = tm.MultiplyPoint(mod.verts[i]);

            p = mod.transform.TransformPoint(mod.verts[i]);
            p = modobj.transform.InverseTransformPoint(p);
            mod.freeverts[i] = p;

            closefaces.Clear();

            for (int t = 0; t < basefaces.Length; t += 3)
            {
                p0 = tverts[basefaces[t]];
                p1 = tverts[basefaces[t + 1]];
                p2 = tverts[basefaces[t + 2]];

                //if ( mod.targetIsSkin && !mod.sourceIsSkin )
                //{
                //p0 = modobj.transform.InverseTransformPoint(mod.GetSkinPos(basefaces[t]));
                //p1 = modobj.transform.InverseTransformPoint(mod.GetSkinPos(basefaces[t + 1]));
                //p2 = modobj.transform.InverseTransformPoint(mod.GetSkinPos(basefaces[t + 2]));
                //}
                //else
                //{
                //p0 = baseverts[basefaces[t]];
                //	p1 = baseverts[basefaces[t + 1]];
                //p2 = baseverts[basefaces[t + 2]];
                //}

                float dist = mod.GetDistance(p, p0, p1, p2);

                if (Mathf.Abs(dist) < mod.maxdist)
                {
                    MegaCloseFace cf = new MegaCloseFace();
                    cf.dist = Mathf.Abs(dist);
                    cf.face = t;

                    bool inserted = false;
                    for (int k = 0; k < closefaces.Count; k++)
                    {
                        if (cf.dist < closefaces[k].dist)
                        {
                            closefaces.Insert(k, cf);
                            inserted = true;
                            break;
                        }
                    }

                    if (!inserted)
                    {
                        closefaces.Add(cf);
                    }
                }
            }

            float tweight = 0.0f;
            int   maxp    = mod.maxpoints;
            if (maxp == 0)
            {
                maxp = closefaces.Count;
            }

            for (int j = 0; j < maxp; j++)
            {
                if (j < closefaces.Count)
                {
                    int t = closefaces[j].face;

                    p0 = tverts[basefaces[t]];
                    p1 = tverts[basefaces[t + 1]];
                    p2 = tverts[basefaces[t + 2]];

                    //if ( mod.targetIsSkin && !mod.sourceIsSkin )
                    //{
                    //p0 = modobj.transform.InverseTransformPoint(mod.GetSkinPos(basefaces[t]));
                    //p1 = modobj.transform.InverseTransformPoint(mod.GetSkinPos(basefaces[t + 1]));
                    //p2 = modobj.transform.InverseTransformPoint(mod.GetSkinPos(basefaces[t + 2]));
                    //}
                    //else
                    //{
                    //p0 = baseverts[basefaces[t]];
                    //p1 = baseverts[basefaces[t + 1]];
                    //p2 = baseverts[basefaces[t + 2]];
                    //}

                    Vector3 normal = mod.FaceNormal(p0, p1, p2);

                    float dist = closefaces[j].dist;                            //GetDistance(p, p0, p1, p2);

                    MegaBindInf bi = new MegaBindInf();
                    bi.dist   = mod.GetPlaneDistance(p, p0, p1, p2);                    //dist;
                    bi.face   = t;
                    bi.i0     = basefaces[t];
                    bi.i1     = basefaces[t + 1];
                    bi.i2     = basefaces[t + 2];
                    bi.bary   = mod.CalcBary(p, p0, p1, p2);
                    bi.weight = 1.0f / (1.0f + dist);
                    bi.area   = normal.magnitude * 0.5f;                        //CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]);	// Could calc once at start
                    tweight  += bi.weight;
                    bv.verts.Add(bi);
                }
            }

            if (mod.maxpoints > 0 && mod.maxpoints < bv.verts.Count)
            {
                bv.verts.RemoveRange(mod.maxpoints, bv.verts.Count - mod.maxpoints);
            }

            // Only want to calculate skin vertices we use
            if (!mod.sourceIsSkin && mod.targetIsSkin)
            {
                for (int fi = 0; fi < bv.verts.Count; fi++)
                {
                    if (!mod.neededVerts.Contains(bv.verts[fi].i0))
                    {
                        mod.neededVerts.Add(bv.verts[fi].i0);
                    }

                    if (!mod.neededVerts.Contains(bv.verts[fi].i1))
                    {
                        mod.neededVerts.Add(bv.verts[fi].i1);
                    }

                    if (!mod.neededVerts.Contains(bv.verts[fi].i2))
                    {
                        mod.neededVerts.Add(bv.verts[fi].i2);
                    }
                }
            }

            if (tweight == 0.0f)
            {
                mod.nomapcount++;
                break;
            }

            bv.weight = tweight;
        }

        EditorUtility.ClearProgressBar();
    }
Ejemplo n.º 9
0
    public void Attach(MegaModifyObject modobj)
    {
        targetIsSkin = false;
        sourceIsSkin = false;

        if ( mesh && startverts != null )
            mesh.vertices = startverts;

        if ( modobj == null )
        {
            bindverts = null;
            return;
        }

        nomapcount = 0;

        if ( mesh )
            mesh.vertices = startverts;

        MeshFilter mf = GetComponent<MeshFilter>();
        Mesh srcmesh = null;

        if ( mf != null )
        {
            //skinned = false;
            srcmesh = mf.mesh;
        }
        else
        {
            SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));

            if ( smesh != null )
            {
                //skinned = true;
                srcmesh = smesh.sharedMesh;
                sourceIsSkin = true;
            }
        }

        if ( mesh == null )
            mesh = CloneMesh(srcmesh);	//mf.mesh);

        if ( mf )
            mf.mesh = mesh;
        else
        {
            SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
            smesh.sharedMesh = mesh;
        }

        if ( sourceIsSkin == false )
        {
            SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
            if ( tmesh != null )
            {
                targetIsSkin = true;

                if ( !sourceIsSkin )
                {
                    Mesh sm = tmesh.sharedMesh;
                    bindposes = sm.bindposes;
                    boneweights = sm.boneWeights;
                    bones = tmesh.bones;
                    skinnedVerts = sm.vertices;	//new Vector3[sm.vertexCount];
                }
            }
        }

        neededVerts.Clear();

        verts = mesh.vertices;
        startverts = mesh.vertices;
        freeverts = new Vector3[startverts.Length];
        Vector3[] baseverts = modobj.verts;	//basemesh.vertices;
        int[] basefaces = modobj.tris;	//basemesh.triangles;

        bindverts = new MegaBindVert[verts.Length];

        // matrix to get vertex into local space of target
        Matrix4x4 tm = transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;

        List<MegaCloseFace> closefaces = new List<MegaCloseFace>();

        Vector3 p0 = Vector3.zero;
        Vector3 p1 = Vector3.zero;
        Vector3 p2 = Vector3.zero;

        for ( int i = 0; i < verts.Length; i++ )
        {
            MegaBindVert bv = new MegaBindVert();
            bindverts[i] = bv;

            Vector3 p = tm.MultiplyPoint(verts[i]);

            p = transform.TransformPoint(verts[i]);
            p = modobj.transform.InverseTransformPoint(p);
            freeverts[i] = p;

            closefaces.Clear();

            for ( int t = 0; t < basefaces.Length; t += 3 )
            {
                if ( targetIsSkin && !sourceIsSkin )
                {
                    p0 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t]));
                    p1 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 1]));
                    p2 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 2]));
                }
                else
                {
                    p0 = baseverts[basefaces[t]];
                    p1 = baseverts[basefaces[t + 1]];
                    p2 = baseverts[basefaces[t + 2]];
                }

                float dist = GetDistance(p, p0, p1, p2);

                if ( Mathf.Abs(dist) < maxdist )
                {
                    MegaCloseFace cf = new MegaCloseFace();
                    cf.dist = Mathf.Abs(dist);
                    cf.face = t;

                    bool inserted = false;
                    for ( int k = 0; k < closefaces.Count; k++ )
                    {
                        if ( cf.dist < closefaces[k].dist )
                        {
                            closefaces.Insert(k, cf);
                            inserted = true;
                            break;
                        }
                    }

                    if ( !inserted )
                        closefaces.Add(cf);
                }
            }

            float tweight = 0.0f;
            int maxp = maxpoints;
            if ( maxp == 0 )
                maxp = closefaces.Count;

            for ( int j = 0; j < maxp; j++ )
            {
                if ( j < closefaces.Count )
                {
                    int t = closefaces[j].face;

                    if ( targetIsSkin && !sourceIsSkin )
                    {
                        p0 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t]));
                        p1 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 1]));
                        p2 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 2]));
                    }
                    else
                    {
                        p0 = baseverts[basefaces[t]];
                        p1 = baseverts[basefaces[t + 1]];
                        p2 = baseverts[basefaces[t + 2]];
                    }

                    Vector3 normal = FaceNormal(p0, p1, p2);

                    float dist = closefaces[j].dist;	//GetDistance(p, p0, p1, p2);

                    MegaBindInf bi = new MegaBindInf();
                    bi.dist = GetPlaneDistance(p, p0, p1, p2);	//dist;
                    bi.face = t;
                    bi.i0 = basefaces[t];
                    bi.i1 = basefaces[t + 1];
                    bi.i2 = basefaces[t + 2];
                    bi.bary = CalcBary(p, p0, p1, p2);
                    bi.weight = 1.0f / (1.0f + dist);
                    bi.area = normal.magnitude * 0.5f;	//CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]);	// Could calc once at start
                    tweight += bi.weight;
                    bv.verts.Add(bi);
                }
            }

            if ( maxpoints > 0 && maxpoints < bv.verts.Count )
                bv.verts.RemoveRange(maxpoints, bv.verts.Count - maxpoints);

            // Only want to calculate skin vertices we use
            if ( !sourceIsSkin && targetIsSkin )
            {
                for ( int fi = 0; fi < bv.verts.Count; fi++ )
                {
                    if ( !neededVerts.Contains(bv.verts[fi].i0) )
                        neededVerts.Add(bv.verts[fi].i0);

                    if ( !neededVerts.Contains(bv.verts[fi].i1) )
                        neededVerts.Add(bv.verts[fi].i1);

                    if ( !neededVerts.Contains(bv.verts[fi].i2) )
                        neededVerts.Add(bv.verts[fi].i2);
                }
            }

            if ( tweight == 0.0f )
                nomapcount++;

            bv.weight = tweight;
        }
    }