void BlurPass() { SkinTools t = target as SkinTools; SkinToolsData data = t.Data; data.UpdateResultInfo(); for (int v = 0; v < data.SourceGeometry.posVertsList.Count; v++) { data.SourceGeometry.posVertsList[v].BonesWeights = new float[data.ResultBones.Length]; } for (int i = 0; i < data.SourceGeometry.unityVertices.Count; i++) { int parent = data.SourceGeometry.unityVertices[i].PVertIdx; for (int b = 0; b < data.ResultBones.Length; b++) { data.SourceGeometry.posVertsList[parent].BonesWeights[b] = data.ResultBones[b].Weights[i]; } } for (int b = 0; b < data.ResultBones.Length; b++) { for (int i = 0; i < data.BlurIterations; i++) { for (int v = 0; v < data.SourceGeometry.posVertsList.Count; v++) { float lerpVal = (1f / data.SourceGeometry.posVertsList[v].AdjacentPV.Count) * data.BlurMultiplier; for (int a = 0; a < data.SourceGeometry.posVertsList[v].AdjacentPV.Count; a++) { int apv = data.SourceGeometry.posVertsList[v].AdjacentPV[a]; data.SourceGeometry.posVertsList[v].BonesWeights[b] = Mathf.Lerp(data.SourceGeometry.posVertsList[v].BonesWeights[b], data.SourceGeometry.posVertsList[apv].BonesWeights[b], lerpVal); } } } } Transform[] bones = data.resultSMR.bones; for (int v = 0; v < data.SourceGeometry.posVertsList.Count; v++) { data.SourceGeometry.posVertsList[v].ebw = new ExtBoneWeight(); for (int b = 0; b < data.ResultBones.Length; b++) { data.SourceGeometry.posVertsList[v].ebw.Add(bones[b], data.SourceGeometry.posVertsList[v].BonesWeights[b], 0); } } BoneWeight[] weights = data.ResultMesh.boneWeights; for (int i = 0; i < data.SourceGeometry.unityVertices.Count; i++) { int parent = data.SourceGeometry.unityVertices[i].PVertIdx; data.SourceGeometry.posVertsList[parent].ebw.FillIndeces(bones); weights[i] = data.SourceGeometry.posVertsList[parent].ebw.GetClampedBW(); } data.ResultMesh.boneWeights = weights; data.resultSMR.sharedMesh = data.ResultMesh; data.UpdateResultInfo(); data.ApplyResultVisual(); }
void GenerateSkinning() { SkinTools t = target as SkinTools; SkinToolsData data = t.Data; bool referenceExist = data.ReferenceSMR != null; Vector3[] rVertices = data.SourceGeometryMF.sharedMesh.vertices; Vector3[] rNormals = data.SourceGeometryMF.sharedMesh.normals; Vector3[] rWorldVertices = new Vector3[rVertices.Length]; Vector2[] rMapVertices = data.SourceGeometryMF.sharedMesh.uv; Matrix4x4 smLTW = data.SourceGeometryMF.transform.localToWorldMatrix; Matrix4x4 tWTL = t.transform.worldToLocalMatrix; for (int v = 0; v < rVertices.Length; v++) { rWorldVertices[v] = smLTW.MultiplyPoint3x4(rVertices[v]); rVertices[v] = tWTL.MultiplyPoint3x4(rWorldVertices[v]); rNormals[v] = smLTW.MultiplyVector(rNormals[v]); rNormals[v] = tWTL.MultiplyVector(rNormals[v]); } data.ResultMesh = Instantiate(data.SourceGeometryMF.sharedMesh) as Mesh; string[] splittedPath = data.OutputMeshPath.Split("/.".ToCharArray()); string meshName = splittedPath[splittedPath.Length - 2]; data.ResultMesh.name = meshName; data.ResultMesh.vertices = rVertices; data.ResultMesh.normals = rNormals; data.ResultMesh.RecalculateBounds(); data.resultSMR.localBounds = new Bounds(data.ResultMesh.bounds.center, data.ResultMesh.bounds.size * 2); SourceSMRCollider _collider = null; SourceSMRCollider _icollider = null; BoneWeight[] existingWeights = null; Transform[] sourceBones = null; int[] sourceSMRTris = null; Ray[] frays = null; bool[] excludedTriangles = null; if (referenceExist) { _collider = new SourceSMRCollider(data.ReferenceSMR, false); _icollider = new SourceSMRCollider(data.ReferenceSMR, true); existingWeights = data.ReferenceSMR.sharedMesh.boneWeights; sourceBones = data.ReferenceSMR.bones; sourceSMRTris = data.ReferenceSMR.sharedMesh.triangles; excludedTriangles = new bool[data.ReferenceSMR.sharedMesh.triangles.Length / 3]; if (data.ReferenceSMRGeometry != null && data.ReferenceSMRGeometry.IsValid) { excludedTriangles = data.ReferenceSMRGeometry.ExcludedTris; } if (data.BakingQuality == 0) { frays = new Ray[ResourceHolder.Rays362.Length]; for (int i = 0; i < frays.Length; i++) { frays[i] = new Ray(Vector3.zero, ResourceHolder.Rays362[i]); } } else if (data.BakingQuality == 1) { frays = new Ray[ResourceHolder.Rays642.Length]; for (int i = 0; i < frays.Length; i++) { frays[i] = new Ray(Vector3.zero, ResourceHolder.Rays642[i]); } } else if (data.BakingQuality == 2) { frays = new Ray[ResourceHolder.Rays1002.Length]; for (int i = 0; i < frays.Length; i++) { frays[i] = new Ray(Vector3.zero, ResourceHolder.Rays1002[i]); } } } ExtBoneWeight[] ebws = new ExtBoneWeight[rWorldVertices.Length]; List <Transform> newBonesList = new List <Transform>(); for (int b = 0; b < data.MapBones.Count; b++) { newBonesList.Add(data.MapBones[b].Tr); } EditorUtility.DisplayProgressBar("Bake", "Baking vertices", 0); int progressPercent = 0; for (int v = 0; v < rWorldVertices.Length; v++) { ebws[v] = new ExtBoneWeight( ); if (data.SourceGeometry.HasUV0) { Vector2 uv = rMapVertices[v]; for (int b = 0; b < data.MapBones.Count; b++) { float val = data.MapBones[b].Map.GetPixelBilinear(uv.x, uv.y).grayscale; ebws[v].AddMask(data.MapBones[b].Tr, val); } } if (referenceExist) { RaycastHit hit = GetNearestHit(frays, _collider._Collider, _icollider._Collider, rWorldVertices[v], excludedTriangles); BoneWeight bwA = existingWeights [sourceSMRTris[hit.triangleIndex * 3]]; BoneWeight bwB = existingWeights [sourceSMRTris[hit.triangleIndex * 3 + 1]]; BoneWeight bwC = existingWeights [sourceSMRTris[hit.triangleIndex * 3 + 2]]; for (int i = 0; i < 4; i++) { Transform nbA = sourceBones[bwA.GetBoneIdx(i)]; Transform nbB = sourceBones[bwB.GetBoneIdx(i)]; Transform nbC = sourceBones[bwC.GetBoneIdx(i)]; if (!data.ReferenceSMRBones[nbA].Excluded) { if (!newBonesList.Contains(nbA)) { newBonesList.Add(nbA); } ebws[v].Add(nbA, bwA.GetWeight(i) * hit.barycentricCoordinate.x, 0); } if (!data.ReferenceSMRBones[nbB].Excluded) { if (!newBonesList.Contains(nbB)) { newBonesList.Add(nbB); } ebws[v].Add(nbB, bwB.GetWeight(i) * hit.barycentricCoordinate.y, 0); } if (!data.ReferenceSMRBones[nbC].Excluded) { if (!newBonesList.Contains(nbC)) { newBonesList.Add(nbC); } ebws[v].Add(nbC, bwC.GetWeight(i) * hit.barycentricCoordinate.z, 0); } } } float progress = v / (float)rWorldVertices.Length; int percent = Mathf.FloorToInt(progress * 100); if (progressPercent != percent) { progressPercent = percent; string progressBarName = string.Format("Bake {0}", data.ResultMesh.name); string progressInfo = string.Format("baking vertices {0} of {1} with {2} quality ", v, rWorldVertices.Length, data.BakingQualityNames[data.BakingQuality]); EditorUtility.DisplayProgressBar(progressBarName, progressInfo, progress); } } EditorUtility.ClearProgressBar(); BoneWeight[] newweights = new BoneWeight[rWorldVertices.Length]; Transform[] newBonesArray = newBonesList.ToArray(); for (int w = 0; w < ebws.Length; w++) { ebws[w].FillIndeces(newBonesArray); newweights[w] = ebws[w].GetClampedBW(); } data.resultSMR.bones = newBonesArray; Matrix4x4[] bindBones = new Matrix4x4[newBonesArray.Length]; for (int b = 0; b < newBonesArray.Length; b++) { bindBones[b] = newBonesArray[b].worldToLocalMatrix * t.transform.localToWorldMatrix; } data.ResultMesh.bindposes = bindBones; data.ResultMesh.boneWeights = newweights; if (referenceExist) { _collider.Destroy(); _icollider.Destroy(); } AssetDatabase.DeleteAsset(data.OutputMeshPath); AssetDatabase.CreateAsset(data.ResultMesh, data.OutputMeshPath); AssetDatabase.SaveAssets(); data.ResultMesh = AssetDatabase.LoadAssetAtPath(data.OutputMeshPath, typeof(Mesh)) as Mesh; data.resultSMR.sharedMesh = data.ResultMesh; data.UpdateResultInfo(); data.ApplyResultVisual(); }