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