示例#1
0
        public static void SetFromBoneWeight(this EditableBoneWeight editableBoneWeight, BoneWeight boneWeight)
        {
            editableBoneWeight.Clamp(4, false);

            while (editableBoneWeight.Count < 4)
            {
                editableBoneWeight.AddChannel(0, 0f, false);
            }

            for (var i = 0; i < 4; ++i)
            {
                var weight = boneWeight.GetWeight(i);
                editableBoneWeight[i].boneIndex = boneWeight.GetBoneIndex(i);
                editableBoneWeight[i].weight    = weight;
                editableBoneWeight[i].enabled   = weight > 0f;
            }
        }
        protected void AssertBoneWeightContainsChannels(BoneWeight expected, BoneWeight actual)
        {
            var m_BoneWeightDataList = new List <BoneWeightData>();

            for (var i = 0; i < 4; ++i)
            {
                m_BoneWeightDataList.Add(new BoneWeightData()
                {
                    boneIndex = expected.GetBoneIndex(i),
                    weight    = expected.GetWeight(i)
                });
            }

            for (var i = 0; i < 4; ++i)
            {
                Assert.IsTrue(m_BoneWeightDataList.Contains(new BoneWeightData()
                {
                    boneIndex = actual.GetBoneIndex(i), weight = actual.GetWeight(i)
                }), "BoneWeight incorrect channel " + i + " with boneIndex " + actual.GetBoneIndex(i) + " and weight " + actual.GetWeight(i));
            }
        }
示例#3
0
        public void OnSceneGUI(SceneView sceneView)
        {
            if (skin != null && isPainting)
            {
                HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));

                if (mesh == null || recalculateMesh)
                {
                    mesh = new Mesh();
                    skin.BakeMesh(mesh);

                    mesh.normals     = skin.sharedMesh.normals;
                    mesh.bindposes   = skin.sharedMesh.bindposes;
                    mesh.bounds      = skin.sharedMesh.bounds;
                    mesh.uv          = skin.sharedMesh.uv;
                    mesh.uv2         = skin.sharedMesh.uv2;
                    mesh.boneWeights = skin.sharedMesh.boneWeights;
                    mesh.tangents    = skin.sharedMesh.tangents;

                    mesh.GetVertices(vertices);

                    for (int i = 0; i < mesh.vertexCount; i++)
                    {
                        vertices[i] = new Vector3(
                            vertices[i].x * skin.transform.lossyScale.x,
                            vertices[i].y * skin.transform.lossyScale.y,
                            vertices[i].z * skin.transform.lossyScale.z);
                    }

                    mesh.SetVertices(vertices);

                    recalculateMesh = false;
                }
                else
                {
                    mesh.boneWeights = skin.sharedMesh.boneWeights;
                }

                CalculateVertexColors(skin.bones, bones[boneIndex]);

                List <BoneWeight> weights = mesh.boneWeights.ToList();

                Event current = Event.current;

                Graphics.DrawMeshNow(mesh, skin.transform.localToWorldMatrix);

                for (int b = 0; b < bones.Length; b++)
                {
                    if (bones[b] == bones[boneIndex])
                    {
                        Handles.color = Color.yellow;
                    }
                    else
                    {
                        Handles.color = Color.gray;
                    }

                    Handles.DrawLine(bones[b].transform.position, bones[b].Head);
                }

                Handles.color = Color.red;

                mpos = HandleUtility.GUIPointToWorldRay(current.mousePosition).origin;

                mpos = new Vector3(mpos.x, mpos.y);

                Handles.DrawWireDisc(mpos, Vector3.forward, brushSize);

                if (isPainting)
                {
                    if (current.type == EventType.ScrollWheel && current.modifiers == EventModifiers.Control)
                    {
                        brushSize = Mathf.Clamp(brushSize + (float)System.Math.Round(current.delta.y / 30, 2), 0, float.MaxValue);

                        Repaint();

                        current.Use();
                    }
                    else if (current.type == EventType.MouseDown && current.button == 0)
                    {
                        isDrawing  = true;
                        wasDrawing = false;
                    }
                    else if (current.type == EventType.MouseUp && current.button == 0)
                    {
                        if (isDrawing)
                        {
                            wasDrawing      = true;
                            recalculateMesh = true;
                        }

                        isDrawing = false;
                    }
                    else if (current.type == EventType.MouseDrag && isDrawing && current.button == 0)
                    {
                        w = weight * ((mode == PaintingMode.Subtract) ? -1 : 1);

                        for (int i = 0; i < mesh.vertices.Length; i++)
                        {
                            v = mesh.vertices[i];

                            d = (v - skin.gameObject.transform.InverseTransformPoint(mpos)).magnitude;

                            if (d <= brushSize)
                            {
                                bw         = weights[i];
                                vw         = bw.GetWeight(boneIndex);
                                vw         = Mathf.Clamp(vw + (1 - d / brushSize) * w, 0, 1);
                                bw         = bw.SetWeight(boneIndex, vw);
                                weights[i] = bw.Clone();
                            }
                        }

                        skin.sharedMesh.boneWeights = weights.ToArray();
                    }
                }

                sceneView.Repaint();
            }
        }
    public void OnSceneGUI(SceneView sceneView)
    {
        if (skin != null && isPainting)
        {
            HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));

            Mesh m = skin.sharedMesh.Clone();
            m.colors = CalculateVertexColors(skin.bones, m, skin.bones[bone].GetComponent <Bone>());

            List <BoneWeight> weights = m.boneWeights.ToList();

            Event current = Event.current;

            Graphics.DrawMeshNow(m, skin.transform.position, skin.transform.rotation);

            Bone bn = skin.bones[bone].GetComponent <Bone>();

            foreach (Bone b in skin.GetComponentsInChildren <Bone>())
            {
                if (bn == b)
                {
                    Handles.color = Color.yellow;
                }
                else
                {
                    Handles.color = Color.gray;
                }
                Handles.DrawLine(b.transform.position, b.Head);
            }

            Handles.color = Color.red;
            Vector3 mpos = HandleUtility.GUIPointToWorldRay(current.mousePosition).origin;
            mpos = new Vector3(mpos.x, mpos.y);
            Handles.DrawWireDisc(mpos, Vector3.forward, brushSize);

            if (isPainting)
            {
                if (current.type == EventType.scrollWheel && current.modifiers == EventModifiers.Control)
                {
                    brushSize = Mathf.Clamp(brushSize + (float)System.Math.Round(current.delta.y / 30, 2), 0, float.MaxValue);
                    Repaint();
                    current.Use();
                }
                else if (current.type == EventType.mouseDown && current.button == 0)
                {
                    isDrawing = true;
                }
                else if (current.type == EventType.mouseUp && current.button == 0)
                {
                    isDrawing = false;
                }
                else if (current.type == EventType.mouseDrag && isDrawing && current.button == 0)
                {
                    float w = weight * ((mode == PaintingMode.Subtract) ? -1 : 1);

                    for (int i = 0; i < m.vertices.Length; i++)
                    {
                        Vector3 v = m.vertices[i];
                        float   d = (v - skin.gameObject.transform.InverseTransformPoint(mpos)).magnitude;

                        if (d <= brushSize)
                        {
                            BoneWeight bw = weights[i];
                            float      vw = bw.GetWeight(bn.index);
                            vw         = Mathf.Clamp(vw + (1 - d / brushSize) * w, 0, 1);
                            bw         = bw.SetWeight(bn.index, vw);
                            weights[i] = bw.Clone();
                        }
                    }

                    skin.sharedMesh.boneWeights = weights.ToArray();
                    EditorUtility.SetDirty(skin.gameObject);
                    if (PrefabUtility.GetPrefabType(skin.gameObject) != PrefabType.None)
                    {
                        AssetDatabase.SaveAssets();
                    }
                }
            }

            sceneView.Repaint();
        }
    }
        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();
        }
示例#6
0
    public static BoneWeight Lerp(BoneWeight a, BoneWeight b, float mix)
    {
        if (mix <= 0f)
        {
            return(a);
        }
        if (mix >= 1f)
        {
            return(b);
        }
        a.weight0 *= 1f - mix;
        a.weight1 *= 1f - mix;
        a.weight2 *= 1f - mix;
        a.weight3 *= 1f - mix;
        b.weight0 *= mix;
        b.weight1 *= mix;
        b.weight2 *= mix;
        b.weight3 *= mix;
        BoneWeight result = default(BoneWeight);
        int        num    = 0;
        int        num2   = 0;

        if (a.GetWeight(num) > b.GetWeight(num2))
        {
            result.weight0    = a.GetWeight(num);
            result.boneIndex0 = a.GetBoneIndex(num);
            num++;
        }
        else
        {
            result.weight0    = b.GetWeight(num2);
            result.boneIndex0 = b.GetBoneIndex(num2);
            num2++;
        }
        if (a.GetWeight(num) > b.GetWeight(num2))
        {
            result.weight1    = a.GetWeight(num);
            result.boneIndex1 = a.GetBoneIndex(num);
            num++;
        }
        else
        {
            result.weight1    = b.GetWeight(num2);
            result.boneIndex1 = b.GetBoneIndex(num2);
            num2++;
        }
        if (a.GetWeight(num) > b.GetWeight(num2))
        {
            result.weight2    = a.GetWeight(num);
            result.boneIndex2 = a.GetBoneIndex(num);
            num++;
        }
        else
        {
            result.weight2    = b.GetWeight(num2);
            result.boneIndex2 = b.GetBoneIndex(num2);
            num2++;
        }
        if (a.GetWeight(num) > b.GetWeight(num2))
        {
            result.weight3    = a.GetWeight(num);
            result.boneIndex3 = a.GetBoneIndex(num);
            num++;
        }
        else
        {
            result.weight3    = b.GetWeight(num2);
            result.boneIndex3 = b.GetBoneIndex(num2);
            num2++;
        }
        float num3 = result.weight0 + result.weight1 + result.weight2 + result.weight3;

        if (num3 != 0f)
        {
            result.weight0 /= num3;
            result.weight1 /= num3;
            result.weight2 /= num3;
            result.weight3 /= num3;
        }
        return(result);
    }