Пример #1
0
            public void ExecuteSoft(SoftSelection softSel, Quaternion modelRotOff)
            {
                softSel.Prepare();

                Vector3 modelPivotPos = m_Pivot.ModelPos;
                Mesh    m             = m_Mesh.mesh;

                //Vector3[] cachedVertsArray = softSel.CachedVertPos;
                //Vector3[] vertsArray = (Vector3[])cachedVertsArray.Clone();
                Vector3[] vertsArray = m.vertices;

                VLst softSelIdxLst = softSel.GetEffectVerts();

                for (int i = 0; i < softSelIdxLst.Count; ++i)
                {
                    int   vidx       = softSelIdxLst[i];
                    float percentage = softSel.GetPercentage(vidx);

                    Vector3    offVec          = vertsArray[vidx] - modelPivotPos;
                    Quaternion percModelRotoff = Quaternion.Slerp(Quaternion.identity,
                                                                  modelRotOff, percentage); // interpolated rotation

                    Vector3 transOff = percModelRotoff * offVec;
                    vertsArray[vidx] = transOff + modelPivotPos;
                }

                UndoMesh.SetVertices(m, vertsArray);
            }
Пример #2
0
            private Vector3[] m_CachedVertPos; //used in dragging handle, cache the starting position of verts

            #endregion "data"

            #region "public method"
            // public method

            public void Init(EditableMesh m, MeshSelection sel, Pivotor p)
            {
                m_Mesh      = m;
                m_Selection = sel;
                m_Pivot     = p;
                Dbg.Assert(m_Pivot != null, "SoftSelection.Init: pivotor is null");

                m_Range = 1f;

                m_Cont = new _Data[m.mesh.vertexCount];
                for (int i = 0; i < m_Cont.Length; ++i)
                {
                    m_Cont[i] = new _Data();
                }

                m_EffectVertIdxLst = new VLst();

                m_Mode        = Mode.Off;
                m_PrepareMode = PrepareMode.Always;

                // atten curve
                var res = (SoftSelectionRes)AssetDatabase.LoadAssetAtPath(SOFTSEL_ATTEN_CURVE_PATH, typeof(SoftSelectionRes));

                if (res == null)
                {
                    res = ScriptableObject.CreateInstance <SoftSelectionRes>();
                    AssetDatabase.CreateAsset(res, SOFTSEL_ATTEN_CURVE_PATH);
                    res = (SoftSelectionRes)AssetDatabase.LoadAssetAtPath(SOFTSEL_ATTEN_CURVE_PATH, typeof(SoftSelectionRes));
                    Dbg.Assert(res != null, "SoftSelection.Init: failed to create curve asset for SoftSelection");
                }
                m_Atten = res.attenCurve;

                MeshManipulator.evtHandleDraggingStateChanged += this._OnHandleDraggingStateChanged;
            }
Пример #3
0
            public void Prepare()
            {
                if (m_PrepareMode == PrepareMode.Stop)
                {
                    return;
                }
                else if (m_PrepareMode == PrepareMode.OnlyOnce)
                {
                    m_PrepareMode = PrepareMode.Stop;
                }

                m_CachedVertPos = m_Mesh.mesh.vertices; //cache as starting pos, useful when dynamically change range
                VLst selectedVerts = m_Selection.GetVertices();

                //1. set the initial effect percentage
                Reset();
                //1.1 set the seeds
                for (int i = 0; i < selectedVerts.Count; ++i)
                {
                    int vidx = selectedVerts[i];
                    m_Cont[vidx].AsSeed();
                }

                //2. calculate nearest distance for every vert,
                _CalcDist(selectedVerts);

                //3. calc the percentage
                _CalcPercentage();
            }
Пример #4
0
            public void ExecuteWorld(VLst vertIdxLst, Vector3 worldFrom, Vector3 worldTo)
            {
                Transform meshTr        = m_Mesh.transform;
                Vector3   localStartPos = meshTr.InverseTransformPoint(worldFrom);
                Vector3   localNewPos   = meshTr.InverseTransformPoint(worldTo);
                Vector3   localOff      = localNewPos - localStartPos;

                Execute(vertIdxLst, localOff);
            }
Пример #5
0
            public void ExecuteWorld(VLst vertIdxLst, Quaternion worldFrom, Quaternion worldTo)
            {
                Quaternion localFrom;
                Quaternion localTo;

                _CalcLocalRotations(ref worldFrom, ref worldTo, out localFrom, out localTo);

                Quaternion localOff = localTo * Quaternion.Inverse(localFrom);

                Execute(vertIdxLst, localOff);
            }
Пример #6
0
            /// <summary>
            /// move specified verts by offset
            /// </summary>
            /// <param name="vertIdxLst">the list containing index to all affected verts</param>
            /// <param name="modelSpaceOffset">the offset in model's local space</param>
            public void Execute(VLst vertIdxLst, Vector3 modelSpaceOffset)
            {
                Mesh m = m_Mesh.mesh;

                Vector3[] vertsArray = m.vertices;

                for (int i = 0; i < vertIdxLst.Count; ++i)
                {
                    int vidx = vertIdxLst[i];
                    vertsArray[vidx] += modelSpaceOffset;
                }

                UndoMesh.SetVertices(m, vertsArray);
            }
Пример #7
0
            public void ExecuteWorldSoft(SoftSelection softSel, Vector3 worldFrom, Vector3 worldTo, Vector3 worldPivotPos)
            {
                //Dbg.Log("ScaleVerts.ExecuteWorldSoft: from: {0}, to: {1}, revert: {2}", worldFrom.ToString("F3"), worldTo.ToString("F3"), bRevert);
                Vector3 worldScaleDelta = V3Ext.DivideComp(worldTo, worldFrom); //when I say "world", it's not bound to be global orientation

                Matrix4x4 mat, matI;

                _GetMatrices(out mat, out matI);

                //Vector3 localPivotPos = m_Pivot.ModelPos; //this will accumulate errors
                Vector3 localPivotPos = m_Tr.InverseTransformPoint(worldPivotPos);

                softSel.Prepare();

                // apply change to verts
                Mesh m = m_Mesh.mesh;

                Vector3[] cachedVertsArray = softSel.CachedVertPos;
                Vector3[] vertsArray       = (Vector3[])cachedVertsArray.Clone();
                VLst      softSelIdxLst    = softSel.GetEffectVerts();

                //Vector3[] curVertArray = MeshCache.Instance.vertices;
                //Dbg.Log("modelPivotPos = {0}, {1}", localPivotPos.ToString("F3"), Misc.ListToString(softSelIdxLst, idx => { return curVertArray[idx].ToString("F3"); } ));

                // apply scaling
                for (int i = 0; i < softSelIdxLst.Count; ++i)
                {
                    int     vidx = softSelIdxLst[i];
                    Vector3 off  = vertsArray[vidx] - localPivotPos;

                    // calc scale mat
                    Vector3 percScale;
                    float   percentage = softSel.GetPercentage(vidx);
                    percScale = Vector3.Lerp(Vector3.one, worldScaleDelta, percentage);

                    Matrix4x4 matScalePerc = Matrix4x4.Scale(percScale);
                    Matrix4x4 combinedMat  = (mat * matScalePerc * matI);
                    Vector3   newOff       = combinedMat.MultiplyPoint(off);

                    vertsArray[vidx] = localPivotPos + newOff;

                    //Dbg.Log("newOff={0}, off={1}, verts={2}, mat=\n{3}", newOff.ToString("F6"), off.ToString("F6"), vertsArray[vidx].ToString("F6"), combinedMat.ToString("F8"));
                }

                // apply to mesh
                UndoMesh.SetVertices(m, vertsArray);

                //Dbg.Log("=======================");
            }
Пример #8
0
            /// <summary>
            /// rotate selected verts by rotation
            /// </summary>
            /// <param name="vertIdxLst">the list containing index to all affected verts</param>
            /// <param name="modelPivotPos">the position of pivot in local space</param>
            /// <param name="modelRotOff">the rotation in model's local space</param>
            public void Execute(VLst vertIdxLst, Quaternion modelRotOff)
            {
                Vector3 modelPivotPos = m_Pivot.ModelPos;
                Mesh    m             = m_Mesh.mesh;

                Vector3[] vertsArray = m.vertices;

                for (int i = 0; i < vertIdxLst.Count; ++i)
                {
                    int     vidx     = vertIdxLst[i];
                    Vector3 offVec   = vertsArray[vidx] - modelPivotPos;
                    Vector3 transOff = modelRotOff * offVec;
                    vertsArray[vidx] = transOff + modelPivotPos;
                }

                UndoMesh.SetVertices(m, vertsArray);
            }
Пример #9
0
            /// <summary>
            /// calculate for each vert, the minimum distance to a seed vert
            /// </summary>
            private void _CalcDist(VLst selectedVerts)
            {
                Transform meshTr = m_Mesh.transform;

                Mesh m = m_Mesh.mesh;

                Vector3[] oriVerts = m.vertices; //original verts pos

                // generate the transformed verts
                Vector3[] verts = new Vector3[oriVerts.Length]; //the verts transformed by matrix
                for (int i = 0; i < m.vertexCount; ++i)
                {
                    verts[i] = meshTr.TransformPoint(oriVerts[i]);
                }

                // calc distances
                int found = 0;

                for (int i = 0; i < m_Cont.Length; ++i)
                {
                    _Data lhs = m_Cont[i];
                    if (lhs.percentage == 1f)
                    {
                        continue;
                    }

                    Vector3 lhsPos = verts[i];

                    for (int j = 0; j < selectedVerts.Count; ++j)
                    {
                        int     seedVertIdx = selectedVerts[j];
                        Vector3 seedPos     = verts[seedVertIdx];

                        float d = Vector3.Distance(seedPos, lhsPos);

                        lhs.dist = Mathf.Min(lhs.dist, d);
                    }

                    if (lhs.dist < m_Range)
                    {
                        ++found;
                    }
                }

                //Dbg.Log("SoftSelection._CalcDist: found {0}", found);
            }
Пример #10
0
        private void _UpdatePivotRot()
        {
            VLst vlst = m_Selection.GetVertices();

            // rotation
            switch (m_Orient)
            {
            case Orientation.Global:
            {
                m_WorldRot = Quaternion.identity;
            }
            break;

            case Orientation.Normal:
            {
                List <Vector3> nLst = MeshUtil.GetVertNormal(m_EditMesh.mesh, vlst);
                if (nLst == null)
                {         //no normal
                    m_WorldRot = m_MeshTr.rotation;
                }
                else
                {         //has normal
                    Vector3 total          = nLst.Aggregate((sum, cur) => { return(sum + cur); });
                    Vector3 newModelNormal = total.normalized;
                    newModelNormal = newModelNormal == Vector3.zero ? (Vector3.forward) : (newModelNormal);
                    Vector3 newWorldNormal = m_MeshTr.TransformDirection(newModelNormal);
                    m_WorldRot = Quaternion.LookRotation(newWorldNormal);
                }
            }
            break;

            case Orientation.Local:
            {
                m_WorldRot = m_EditMesh.transform.rotation;
            }
            break;

            default:
                Dbg.LogErr("Pivotor._UpdatePivot: unexpected orientation: {0}", m_Orient);
                break;
            }
        }
Пример #11
0
            /// <summary>
            /// move specified verts by offset
            /// the base shape is cached in softSel
            /// </summary>
            public void ExecuteSoft(SoftSelection softSel, Vector3 modelSpaceOffset)
            {
                softSel.Prepare(); // will do calculation IF NEEDED

                Mesh m = m_Mesh.mesh;

                Vector3[] cachedVertsArray = softSel.CachedVertPos;
                Vector3[] vertsArray       = (Vector3[])cachedVertsArray.Clone();

                VLst softSelIdxLst = softSel.GetEffectVerts();

                for (int i = 0; i < softSelIdxLst.Count; ++i)
                {
                    int   vidx       = softSelIdxLst[i];
                    float percentage = softSel.GetPercentage(vidx);
                    vertsArray[vidx] += modelSpaceOffset * percentage;
                }

                UndoMesh.SetVertices(m, vertsArray);
            }
Пример #12
0
        private void _UpdatePivotPos_Midian()
        {
            // position
            VLst vlst = m_Selection.GetVertices();

            {
                List <Vector3> posLst        = MeshUtil.GetVertPos(m_EditMesh.mesh, vlst);
                Vector3        total         = Vector3.zero;
                Vector3        modelPivotPos = Vector3.zero;
                if (posLst.Count > 0)
                {
                    total         = posLst.Aggregate((sum, cur) => { return(sum + cur); });
                    modelPivotPos = total / posLst.Count;
                }
                else
                {
                    modelPivotPos = Vector3.zero;
                }
                m_WorldPos = m_MeshTr.TransformPoint(modelPivotPos);

                //Dbg.Log("m_WorldPos = {0}", m_WorldPos);
            }
        }
Пример #13
0
            /// <summary>
            /// scale specified verts based on pivot (parameter in world space)
            /// a affine transformation(?)
            /// </summary>
            /// <param name="vertIdxLst">the list containing index to all affected verts</param>
            /// <param name="worldScaleDelta">the scale info in world space</param>
            public void ExecuteWorld(VLst vertIdxLst, Vector3 worldFrom, Vector3 worldTo, Vector3 worldPivotPos)
            {
                Vector3   worldScaleDelta = V3Ext.DivideComp(worldTo, worldFrom); //when I say "world", it's not bound to be global orientation
                Matrix4x4 combinedMat     = _CalcCombinedMat(ref worldScaleDelta);

                //Vector3 localPivotPos = m_Pivot.ModelPos; //this will accumulate errors
                Vector3 localPivotPos = m_Tr.InverseTransformPoint(worldPivotPos);

                // apply change to verts
                Mesh m = m_Mesh.mesh;

                Vector3[] vertsArray = m.vertices;
                for (int i = 0; i < vertIdxLst.Count; ++i)
                {
                    int     vidx   = vertIdxLst[i];
                    Vector3 off    = vertsArray[vidx] - localPivotPos;
                    Vector3 newOff = combinedMat.MultiplyPoint(off);
                    vertsArray[vidx] = localPivotPos + newOff;
                    //Dbg.Log("newOff={0}, off={1}, verts={2}, mat=\n{3}", newOff.ToString("F6"), off.ToString("F6"), vertsArray[vidx].ToString("F6"), combinedMat.ToString("F8"));
                }

                // apply to mesh
                UndoMesh.SetVertices(m, vertsArray);
            }