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; } }
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; } }
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(); }
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 }
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; } }