Ejemplo n.º 1
0
            /// <summary>
            /// for specified shape,
            /// 1. apply mesh changes based on weight
            /// 2. ensure animWeight == cmpWeight
            /// </summary>
            private void _ApplyWeightChange(int shapeIdx, float newWeight)
            {
                float curWeight = m_CmpWeights[shapeIdx];

                _SetAnimWeight(shapeIdx, newWeight);
                if (Mathf.Approximately(curWeight, newWeight))
                {
                    return;
                }

                Mesh m = m_Mesh.mesh;

                ShapeKeyMorphSO tarMorph = m_Deforms[shapeIdx];

                tarMorph.LerpDiff(_GetBasisShapeKey(), curWeight, newWeight, m_OutData);

                if (m_UseMeshCache)
                {
                    m_OutData.ApplyToMeshAsSubtract(m, m_MeshCache);
                }
                else
                {
                    m_OutData.ApplyToMeshAsSubtract(m);
                }

                m_CmpWeights[shapeIdx] = newWeight;

                _MarkNeedFix();
            }
Ejemplo n.º 2
0
            /// <summary>
            /// used to init real data
            /// </summary>
            public static ShapeKeyDataDiff New(ShapeKeyMorphSO basis, float weight, bool isFullData)
            {
                var d = new ShapeKeyDataDiff();

                d.weight     = weight;
                d.basisSO    = basis;
                d.isFullData = isFullData;

                d.vertices = new List <Vector3>();
                d.normals  = new List <Vector3>();
                d.tangents = new List <Vector4>();
                d.indV     = new List <int>();
                d.indN     = new List <int>();
                d.indT     = new List <int>();
                if (!isFullData)
                {
                    d.UpdateDiffDataWithCurrentMesh();
                }
                else
                {
                    d.SetFullData();
                }

                return(d);
            }
Ejemplo n.º 3
0
            /// <summary>
            /// called only by MeshManipulator
            /// </summary>
            public void InitWhenCreatedByEditor()
            {
                Dbg.Assert(m_Deforms.Count == 0, "MorphProc.InitWhenCreatedByEditor: m_Deforms not empty!?");

                ShapeKeyMorphSO newShape = ShapeKeyMorphSO.NewAsBasis(m_Mesh.mesh);

                SetMorphAt(BASIS_MORPH_IDX, newShape);

                m_CmpWeights[BASIS_MORPH_IDX] = FULL_WEIGHT;
                _SetAnimWeight(BASIS_MORPH_IDX, FULL_WEIGHT);

                m_OutData = ShapeKeyDataDiff.TempVarNew(m_Deforms[BASIS_MORPH_IDX]);
            }
            public override void OnInspectorGUI()
            {
                serializedObject.Update();

                ShapeKeyMorphSO morph = (ShapeKeyMorphSO)serializedObject.targetObject;
                Mesh            m     = (Mesh)m_propMesh.objectReferenceValue;

                EditorGUILayout.BeginHorizontal();
                {
                    GUILayout.Label("Morph Name:");
                    GUILayout.Space(20f);

                    string morphName = m_propName.stringValue;
                    if (EUtil.StringField("MorphName", ref morphName))
                    {
                        m_propName.stringValue = morphName;
                        _ChangeAssetNameIfNeeded();
                    }
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.ObjectField(new GUIContent("Working Mesh", "The mesh on which this morph is applied"),
                                            m, typeof(Mesh), true);

                EditorGUILayout.HelpBox(
                    string.Format("vertex: {0},  {1},  {2}", m.vertexCount,
                                  morph.HasNormals ? "normals" : "NO normals",
                                  morph.HasTangents ? "tangents" : "NO tangents"),
                    MessageType.Info);

                // show each shapeKeyData
                for (int i = 0; i < morph.ShapeKeyCnt; ++i)
                {
                    _DrawShapeKeyData(morph, i);
                }

                // add new shapeKeyData button
                GUILayout.BeginHorizontal();
                {
                    GUILayout.Space(30f);
                    if (GUILayout.Button("Add New Shape Key"))
                    {
                        Undo.RecordObject(morph, "ShapeKeyMorphSO inspector");
                        morph.AddNewShapeKeyByMeshCurrentData();
                    }
                    GUILayout.Space(30f);
                }
                GUILayout.EndHorizontal();

                serializedObject.ApplyModifiedProperties();
            }
Ejemplo n.º 5
0
            /// <summary>
            /// add a new deform using current mesh status
            /// </summary>
            public void AddCurrentMeshAsNewShapeKeyMorph()
            {
                if (m_Deforms.Count >= MAX_SHAPEKEY_CNT)
                {
                    return;
                }

                int             newIdx   = m_Deforms.Count;
                ShapeKeyMorphSO newShape = ShapeKeyMorphSO.NewAsNonBasis(m_Deforms[BASIS_MORPH_IDX]);

                SetMorphAt(newIdx, newShape);

                m_CmpWeights[newIdx] = FULL_WEIGHT;
                _SetAnimWeight(newIdx, FULL_WEIGHT);
            }
Ejemplo n.º 6
0
            public static ShapeKeyData New(float weight, ShapeKeyMorphSO basisSO)
            {
                ShapeKeyData d = new ShapeKeyData();

                //int vcnt = m.vertexCount;

                d.basisSO = basisSO;

                Mesh m = basisSO.GetMesh();

                d.vertices = m.vertices;
                d.normals  = m.normals;
                d.tangents = m.tangents;

                d.weight = weight;

                return(d);
            }
Ejemplo n.º 7
0
            // public method

            /// <summary>
            /// used to init temp var
            /// </summary>
            public static ShapeKeyDataDiff TempVarNew(ShapeKeyMorphSO basis)
            {
                var d = new ShapeKeyDataDiff();

                d.weight     = 0;
                d.basisSO    = basis;
                d.isFullData = false;

                d.vertices = new List <Vector3>();
                d.normals  = new List <Vector3>();
                d.tangents = new List <Vector4>();

                d.indV = new List <int>();
                d.indN = new List <int>();
                d.indT = new List <int>();

                return(d);
            }
Ejemplo n.º 8
0
            public void SetMorphAt(int idx, ShapeKeyMorphSO shape)
            {
                Dbg.Assert(m_Deforms != null, "SetMorphAt: m_Deforms == null");

                if (idx < m_Deforms.Count)
                {
                    m_Deforms[idx] = shape;
                }
                else if (idx == m_Deforms.Count)
                {
                    m_Deforms.Add(shape);
                }
                else if (idx >= MAX_SHAPEKEY_CNT)
                {
                    Dbg.LogErr("MorphProc.SetMorphAt: current only support up to 10 shape keys");
                }
                else
                {
                    Dbg.LogErr("MorphProc.SetMorphAt: idx beyond range: {0}, {1}", idx, m_Deforms.Count);
                }
            }
Ejemplo n.º 9
0
            public static ShapeKeyMorphSO NewAsBasis(Mesh m)
            {
                ShapeKeyMorphSO deform = ScriptableObject.CreateInstance <ShapeKeyMorphSO>();

                deform.name   = "Deform" + deform.GetInstanceID();
                deform.m_Mesh = m;
                deform.m_Keys = new List <ShapeKeyDataDiff>();

                deform.m_BasisSO = deform;

                var data = ShapeKeyDataDiff.New(deform, MorphProc.FULL_WEIGHT, true);

                deform.m_Keys.Add(data);

                deform._PrepareTmpVar();

                deform.m_hasNormals  = data.normals.Count > 0;
                deform.m_hasTangents = data.tangents.Count > 0;

                return(deform);
            }
            // public method

            #endregion "public method"

            #region "private method"
            // private method

            private void _DrawShapeKeyData(ShapeKeyMorphSO morph, int keyIdx)
            {
                ShapeKeyDataDiff keyData = morph.GetShapeKeyDataDiff(keyIdx);

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("Weight:", GUILayout.Width(50f));

                    float newWeight = keyData.weight;
                    if (EUtil.FloatField("weight" + keyIdx, ref newWeight)) //only true when use enter to confirm
                    {
                        morph.SetShapeKeyWeight(keyIdx, newWeight);         //this will ensure all keys are sorted
                    }

                    if (EUtil.Button(EditorRes.texSample, "Sample current mesh status as shape key", EditorRes.styleBtnMorphProc, GUILayout.Width(20f)))
                    {
                        morph.SetMeshCurrentDataToShapeKey(keyIdx);
                    }
                    if (EUtil.Button(EditorRes.texApplyToMesh, "Apply this shape key to mesh", EditorRes.styleBtnMorphProc, GUILayout.Width(20f)))
                    {
                        Undo.RecordObject(m_MorphProc, "MorphProc Inspector");
                        m_MorphProc.ResetToBasisShape();
                        m_MorphProc.ApplyOnlyMorphAt(m_MorphIdx, keyData.weight);
                    }
                    if (EUtil.Button(EditorRes.texDelete, "Delete this shape key from this morph", EditorRes.styleBtnMorphProc, GUILayout.Width(20f)))
                    {
                        if (morph.ShapeKeyCnt == 1)
                        {
                            EditorUtility.DisplayDialog("Only one shape key", "Cannot delete shape key when there's no others", "Got it");
                        }
                        else
                        {
                            morph.DelShapeKeyDataDiff(keyIdx);
                        }
                    }
                }
                EditorGUILayout.EndHorizontal();
            }
Ejemplo n.º 11
0
            public void Copy(ShapeKeyData rhs)
            {
                Dbg.Assert(this.vertices.Length == rhs.vertices.Length, "ShapeKeyData.Copy: vertices cnt: {0}!={1}", vertices.Length, rhs.vertices.Length);
                Dbg.Assert(this.normals.Length == rhs.normals.Length, "ShapeKeyData.Copy: normals cnt: {0}!={1}", normals.Length, rhs.normals.Length);
                Dbg.Assert(this.tangents.Length == rhs.tangents.Length, "ShapeKeyData.Copy: tangents cnt: {0}!={1}", tangents.Length, rhs.tangents.Length);

                for (int i = 0; i < vertices.Length; ++i)
                {
                    this.vertices[i] = rhs.vertices[i];
                }
                for (int i = 0; i < normals.Length; ++i)
                {
                    this.normals[i] = rhs.normals[i];
                }
                for (int i = 0; i < tangents.Length; ++i)
                {
                    this.tangents[i] = rhs.tangents[i];
                }

                this.weight = rhs.weight;

                this.basisSO = rhs.basisSO;
            }
Ejemplo n.º 12
0
            // public method

            #endregion "public method"

            #region "private method"

            private void _DrawDeformEntry(MorphProc proc, int deformIdx, bool isBasis = true)
            {
                ShapeKeyMorphSO deform = (ShapeKeyMorphSO)m_propDeforms.GetArrayElementAtIndex(deformIdx).objectReferenceValue;

                EditorGUILayout.BeginHorizontal();
                {
                    float newWeight = 0f;

                    // weight
                    if (isBasis)
                    {
                        EUtil.PushGUIEnable(false);
                    }

                    EditorGUI.BeginChangeCheck();
                    newWeight = EditorGUILayout.FloatField(deform.name, m_propAnimWeights[deformIdx].floatValue);
                    if (EditorGUI.EndChangeCheck())
                    {
                        m_propAnimWeights[deformIdx].floatValue = Mathf.Clamp(newWeight, 0, 100f);
                    }

                    if (isBasis)
                    {
                        EUtil.PopGUIEnable();
                    }

                    // after weight
                    if (isBasis)
                    { //the basis
                        GUILayout.Space(20f);
                        if (EUtil.Button("R", "Reset as Basis", Color.green, GUILayout.Width(42f)))
                        {
                            Undo.RecordObject(proc, "MorphProc Inspector");
                            proc.ResetToBasisShape();
                        }
                    }
                    else
                    {
                        if (GUILayout.Button(new GUIContent(m_texDetail, "Edit details of this deform"), m_styleBtn, GUILayout.Width(20f)))
                        {
                            var e = (BaseMorphSOEditor)Editor.CreateEditor(deform);
                            e.m_MorphProcEditor = this;
                            e.m_MorphProc       = proc;
                            e.m_MorphIdx        = deformIdx;
                            EditorEditorWindow.OpenWindowWithEditor(e);
                        }

                        if (GUILayout.Button(new GUIContent(m_texApply, "Apply only this deform 100%"), m_styleBtn, GUILayout.Width(20f)))
                        {
                            Undo.RecordObject(proc, "MorphProc Inspector");
                            proc.ApplyOnlyMorphAt(deformIdx);
                        }

                        if (GUILayout.Button(new GUIContent(m_texDelete, "Delete this deform"), m_styleBtn, GUILayout.Width(20f)))
                        {
                            if (EditorUtility.DisplayDialog("To be or not to be", "Are you sure to delete this Morph?", "Go Ahead", "No No No"))
                            {
                                Undo.RecordObject(proc, "MorphProc Inspector");
                                proc.RemoveShapeKeyMorphAt(deformIdx);
                            }
                        }
                    }
                }
                EditorGUILayout.EndHorizontal();
            }