public void UpdateSkinnedMesh() { if (weights != null && weights.Length > 0) { int len = vertices.Length; int boneLen = bones.Length; if (m_weightVertices == null) { m_weightVertices = new Vector3[len]; } if (m_BoneMatrices == null || m_BoneMatrices.Length != boneLen) { m_BoneMatrices = new Matrix4x4[boneLen]; } for (int j = 0; j < boneLen; ++j) { m_BoneMatrices[j] = bones[j].localToWorldMatrix * bindposes[j]; } Matrix4x4 vertexMatrix = new Matrix4x4(); Matrix4x4 worldMat = transform.worldToLocalMatrix; for (int i = 0; i < len; ++i) { Vector3 v = vertices[i]; //local vertex Armature.BoneWeightClass bw = weights[i]; Matrix4x4 bm0 = m_BoneMatrices[bw.boneIndex0]; Matrix4x4 bm1 = m_BoneMatrices[bw.boneIndex1]; Matrix4x4 bm2 = m_BoneMatrices[bw.boneIndex2]; Matrix4x4 bm3 = m_BoneMatrices[bw.boneIndex3]; Matrix4x4 bm4 = m_BoneMatrices[bw.boneIndex4]; for (int n = 0; n < 16; ++n) { vertexMatrix[n] = bm0[n] * bw.weight0 + bm1[n] * bw.weight1 + bm2[n] * bw.weight2 + bm3[n] * bw.weight3 + bm4[n] * bw.weight4; } vertexMatrix = worldMat * vertexMatrix; v = vertexMatrix.MultiplyPoint3x4(v); v.z = 0f; m_weightVertices[i] = v; } m_mesh.vertices = m_weightVertices; } else { m_mesh.vertices = vertices; } }
public void UpdateEdges() { if (m_collder != null && edges != null && edges.Length > 0) { int len = edges.Length; if (m_collider_points == null) { m_collider_points = new Vector2[len]; } Matrix4x4 worldMat = transform.worldToLocalMatrix; Matrix4x4 vertexMatrix = new Matrix4x4(); for (int i = 0; i < len; ++i) { int vIndex = edges[i]; Vector3 v = vertices[vIndex]; //local vertex if (weights != null && weights.Length > 0) { Armature.BoneWeightClass bw = weights[vIndex]; Matrix4x4 bm0 = m_BoneMatrices[bw.boneIndex0]; Matrix4x4 bm1 = m_BoneMatrices[bw.boneIndex1]; Matrix4x4 bm2 = m_BoneMatrices[bw.boneIndex2]; Matrix4x4 bm3 = m_BoneMatrices[bw.boneIndex3]; Matrix4x4 bm4 = m_BoneMatrices[bw.boneIndex4]; for (int n = 0; n < 16; ++n) { vertexMatrix[n] = bm0[n] * bw.weight0 + bm1[n] * bw.weight1 + bm2[n] * bw.weight2 + bm3[n] * bw.weight3 + bm4[n] * bw.weight4; } vertexMatrix = worldMat * vertexMatrix; v = vertexMatrix.MultiplyPoint3x4(v); v.z = 0f; } m_collider_points[i] = (Vector2)v; } m_collder.points = m_collider_points; } }
static void ShowSpriteMesh(TextureFrame frame, SpineData.SkinAttachment attachmentData, Transform slot, Transform skinParent, SpineArmatureEditor armatureEditor) { GameObject go = new GameObject(attachmentData.name); SpriteMesh sm = go.AddComponent <SpriteMesh>(); sm.transform.parent = skinParent; Vector3 localPos = Vector3.zero; localPos.x = attachmentData.x; localPos.y = attachmentData.y; go.transform.localPosition = localPos; Vector3 localSc = Vector3.one; localSc.x = attachmentData.scaleX; localSc.y = attachmentData.scaleY; go.transform.localScale = localSc; go.transform.localRotation = Quaternion.Euler(0, 0, attachmentData.rotation); Transform[] bones = SetMeshVertex <SpriteMesh>(sm, attachmentData, armatureEditor); sm.uvs = attachmentData.uvs; sm.triangles = attachmentData.triangles; sm.colors = new Color[sm.vertices.Length]; for (int i = 0; i < sm.colors.Length; ++i) { sm.colors[i] = Color.white; } if (armatureEditor.genMeshCollider && attachmentData.edges != null) { sm.edges = attachmentData.edges; } if (attachmentData.weights != null && attachmentData.weights.Count > 0) { sm.CreateMesh(); if (armatureEditor.ffdKV.ContainsKey(attachmentData.textureName)) { //Vertex controller sm.vertControlTrans = new Transform[sm.vertices.Length]; for (int i = 0; i < sm.vertices.Length; ++i) { GameObject gov = new GameObject(go.name + "_v" + i); gov.transform.parent = go.transform; gov.transform.localPosition = sm.vertices[i]; gov.transform.localScale = Vector3.zero; sm.vertControlTrans[i] = gov.transform; gov.SetActive(false); } } } else { sm.CreateMesh(); //Vertex controller sm.vertControlTrans = new Transform[sm.vertices.Length]; for (int i = 0; i < sm.vertices.Length; ++i) { GameObject gov = new GameObject(go.name + "_v" + i); gov.transform.parent = go.transform; gov.transform.localPosition = sm.vertices[i]; gov.transform.localScale = Vector3.zero; sm.vertControlTrans[i] = gov.transform; gov.SetActive(false); } } if (attachmentData.weights != null && attachmentData.weights.Count > 0) { List <Armature.BoneWeightClass> boneWeights = new List <Armature.BoneWeightClass>(); for (int i = 0; i < attachmentData.weights.Count; ++i) { int boneCount = (int)attachmentData.weights[i]; //骨骼数量 List <KeyValuePair <int, float> > boneWeightList = new List <KeyValuePair <int, float> >(); for (int j = 0; j < boneCount * 2; j += 2) { int boneIdx = (int)attachmentData.weights[i + j + 1]; float weight = attachmentData.weights[i + j + 2]; boneWeightList.Add(new KeyValuePair <int, float>(boneIdx, weight)); } //sort boneWeightList,desc boneWeightList.Sort(delegate(KeyValuePair <int, float> x, KeyValuePair <int, float> y) { if (x.Value == y.Value) { return(0); } return(x.Value < y.Value? 1: -1); }); Armature.BoneWeightClass bw = new Armature.BoneWeightClass(); for (int j = 0; j < boneWeightList.Count; ++j) { if (j == 0) { bw.boneIndex0 = GlobalBoneIndexToLocalBoneIndex(armatureEditor, boneWeightList[j].Key, bones); bw.weight0 = boneWeightList[j].Value; } else if (j == 1) { bw.boneIndex1 = GlobalBoneIndexToLocalBoneIndex(armatureEditor, boneWeightList[j].Key, bones); bw.weight1 = boneWeightList[j].Value; } else if (j == 2) { bw.boneIndex2 = GlobalBoneIndexToLocalBoneIndex(armatureEditor, boneWeightList[j].Key, bones); bw.weight2 = boneWeightList[j].Value; } else if (j == 3) { bw.boneIndex3 = GlobalBoneIndexToLocalBoneIndex(armatureEditor, boneWeightList[j].Key, bones); bw.weight3 = boneWeightList[j].Value; } else if (j == 4) { bw.boneIndex4 = GlobalBoneIndexToLocalBoneIndex(armatureEditor, boneWeightList[j].Key, bones); bw.weight4 = boneWeightList[j].Value; break; } } boneWeights.Add(bw); i += boneCount * 2; } Matrix4x4[] matrixArray = new Matrix4x4[bones.Length]; for (int i = 0; i < matrixArray.Length; ++i) { Transform bone = bones[i]; matrixArray[i] = bone.worldToLocalMatrix * armatureEditor.armature.localToWorldMatrix; matrixArray[i] *= Matrix4x4.TRS(slot.localPosition, slot.localRotation, slot.localScale); } sm.bones = bones; sm.bindposes = matrixArray; sm.weights = boneWeights.ToArray(); } sm.color = attachmentData.color; sm.UpdateMesh(); sm.UpdateVertexColor(); sm.frame = frame; }
void OnSceneGUI() { if (Application.isPlaying || !sm.isEdit) { return; } Tools.current = Tool.None; Vector3[] vs = (sm.weightVertices == null || sm.weightVertices.Length == 0) ? sm.vertices : sm.weightVertices; if (vs != null) { if (sm.weights != null && sm.weights.Length > 0) { if (m_BoneMatrices == null || m_BoneMatrices.Length != sm.bones.Length) { m_BoneMatrices = new Matrix4x4[sm.bones.Length]; } for (int j = 0; j < sm.bones.Length; ++j) { m_BoneMatrices[j] = sm.bones[j].localToWorldMatrix * sm.bindposes[j]; } } Matrix4x4 vertexMatrix = new Matrix4x4(); for (int i = 0; i < vs.Length; ++i) { Vector3 v = vs[i]; Vector3 prevWorldPos = sm.transform.TransformPoint(v); Vector3 worldPos = Handles.DoPositionHandle(prevWorldPos, Quaternion.identity); Handles.Label(worldPos, " v" + i); worldPos.z = 0; Vector3 localPos = sm.transform.InverseTransformPoint(worldPos); localPos.z = 0; if ((localPos - v).magnitude > 0.005f) { if (m_BoneMatrices != null && i < sm.weights.Length) { Armature.BoneWeightClass bw = sm.weights[i]; Matrix4x4 bm0 = m_BoneMatrices[bw.boneIndex0]; Matrix4x4 bm1 = m_BoneMatrices[bw.boneIndex1]; Matrix4x4 bm2 = m_BoneMatrices[bw.boneIndex2]; Matrix4x4 bm3 = m_BoneMatrices[bw.boneIndex3]; Matrix4x4 bm4 = m_BoneMatrices[bw.boneIndex4]; for (int n = 0; n < 16; ++n) { vertexMatrix[n] = bm0[n] * bw.weight0 + bm1[n] * bw.weight1 + bm2[n] * bw.weight2 + bm3[n] * bw.weight3 + bm4[n] * bw.weight4; } vertexMatrix = sm.transform.worldToLocalMatrix * vertexMatrix; localPos = vertexMatrix.inverse.MultiplyPoint3x4(localPos); localPos.z = 0f; } sm.vertices[i] = localPos; if (sm.vertControlTrans != null && i < sm.vertControlTrans.Length) { sm.vertControlTrans[i].localPosition = sm.vertices[i]; } EditorUtility.SetDirty(sm); } } SceneView.RepaintAll(); } }