Ejemplo n.º 1
0
	static Mesh ExtractSkinnedMeshAttachment (string name, SkinnedMeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List<Transform> boneList, Mesh mesh = null) {

		Skeleton skeleton = new Skeleton(skeletonData);
		skeleton.UpdateWorldTransform();

		float[] floatVerts = new float[attachment.UVs.Length];
		attachment.ComputeWorldVertices(skeleton.Slots[slotIndex], floatVerts);

		Vector2[] uvs = ExtractUV(attachment.UVs);
		Vector3[] verts = ExtractVerts(floatVerts);

		int[] triangles = attachment.Triangles;
		Color color = new Color(attachment.R, attachment.G, attachment.B, attachment.A);

		if (mesh == null)
			mesh = new Mesh();

		mesh.triangles = new int[0];

		mesh.vertices = verts;
		mesh.uv = uvs;
		mesh.triangles = triangles;
		Color[] colors = new Color[verts.Length];
		for (int i = 0; i < verts.Length; i++)
			colors[i] = color;

		mesh.colors = colors;
		mesh.name = name;
		mesh.RecalculateNormals();
		mesh.RecalculateBounds();

		//Handle weights and binding
		Dictionary<int, BoneWeightContainer> weightTable = new Dictionary<int, BoneWeightContainer>();
		System.Text.StringBuilder warningBuilder = new System.Text.StringBuilder();

		int[] bones = attachment.Bones;
		float[] weights = attachment.Weights;
		for (int w = 0, v = 0, b = 0, n = bones.Length; v < n; w += 2) {

			int nn = bones[v++] + v;
			for (; v < nn; v++, b += 3) {
				Transform boneTransform = boneList[bones[v]];
				int vIndex = w / 2;

				float weight = weights[b + 2];

				BoneWeightContainer container;
				if (weightTable.ContainsKey(vIndex))
					container = weightTable[vIndex];
				else {
					container = new BoneWeightContainer();
					weightTable.Add(vIndex, container);
				}


				container.Add(boneTransform, weight);
			}
		}

		BoneWeight[] boneWeights = new BoneWeight[weightTable.Count];

		for (int i = 0; i < weightTable.Count; i++) {
			BoneWeight bw = new BoneWeight();
			var container = weightTable[i];

			var pairs = container.pairs.OrderByDescending(pair => pair.weight).ToList();

			for (int b = 0; b < pairs.Count; b++) {
				if (b > 3) {
					if (warningBuilder.Length == 0)
						warningBuilder.Insert(0, "[SkinnedMeshAttachment " + name + "]\r\nUnity only supports 4 weight influences per vertex!  The 4 strongest influences will be used.\r\n");

					warningBuilder.AppendFormat("{0} ignored on vertex {1}!\r\n", pairs[b].bone.name, i);
					continue;
				}

				int boneIndex = boneList.IndexOf(pairs[b].bone);
				float weight = pairs[b].weight;

				switch (b) {
					case 0:
						bw.boneIndex0 = boneIndex;
						bw.weight0 = weight;
						break;
					case 1:
						bw.boneIndex1 = boneIndex;
						bw.weight1 = weight;
						break;
					case 2:
						bw.boneIndex2 = boneIndex;
						bw.weight2 = weight;
						break;
					case 3:
						bw.boneIndex3 = boneIndex;
						bw.weight3 = weight;
						break;
				}
			}

			boneWeights[i] = bw;
		}

		Matrix4x4[] bindPoses = new Matrix4x4[boneList.Count];
		for (int i = 0; i < boneList.Count; i++) {
			bindPoses[i] = boneList[i].worldToLocalMatrix;
		}

		mesh.boneWeights = boneWeights;
		mesh.bindposes = bindPoses;

		string warningString = warningBuilder.ToString();
		if (warningString.Length > 0)
			Debug.LogWarning(warningString);


		return mesh;
	}
Ejemplo n.º 2
0
		internal static Mesh ExtractWeightedMeshAttachment (string name, MeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List<Transform> boneList, Mesh mesh = null) {
			if (!attachment.IsWeighted())
				throw new System.ArgumentException("Mesh is not weighted.", "attachment");

			Skeleton skeleton = new Skeleton(skeletonData);
			skeleton.UpdateWorldTransform();

			float[] floatVerts = new float[attachment.WorldVerticesLength];
			attachment.ComputeWorldVertices(skeleton.Slots.Items[slotIndex], floatVerts);

			Vector2[] uvs = ExtractUV(attachment.UVs);
			Vector3[] verts = ExtractVerts(floatVerts);

			int[] triangles = attachment.Triangles;
			Color color = new Color(attachment.R, attachment.G, attachment.B, attachment.A);

			mesh = mesh ?? new Mesh();

			mesh.triangles = new int[0];

			mesh.vertices = verts;
			mesh.uv = uvs;
			mesh.triangles = triangles;
			Color[] colors = new Color[verts.Length];
			for (int i = 0; i < verts.Length; i++)
				colors[i] = color;

			mesh.colors = colors;
			mesh.name = name;
			mesh.RecalculateNormals();
			mesh.RecalculateBounds();

			// Handle weights and binding
			var weightTable = new Dictionary<int, BoneWeightContainer>();
			var warningBuilder = new System.Text.StringBuilder();

			int[] bones = attachment.Bones;
			float[] weights = attachment.Vertices;
			for (int w = 0, v = 0, b = 0, n = bones.Length; v < n; w += 2) {

				int nn = bones[v++] + v;
				for (; v < nn; v++, b += 3) {
					Transform boneTransform = boneList[bones[v]];
					int vIndex = w / 2;
					BoneWeightContainer container;
					if (weightTable.ContainsKey(vIndex))
						container = weightTable[vIndex];
					else {
						container = new BoneWeightContainer();
						weightTable.Add(vIndex, container);
					}

					float weight = weights[b + 2];
					container.Add(boneTransform, weight);
				}
			}

			BoneWeight[] boneWeights = new BoneWeight[weightTable.Count];

			for (int i = 0; i < weightTable.Count; i++) {
				BoneWeight bw = new BoneWeight();
				var container = weightTable[i];

				var pairs = container.pairs.OrderByDescending(pair => pair.weight).ToList();

				for (int b = 0; b < pairs.Count; b++) {
					if (b > 3) {
						if (warningBuilder.Length == 0)
							warningBuilder.Insert(0, "[Weighted Mesh: " + name + "]\r\nUnity only supports 4 weight influences per vertex!  The 4 strongest influences will be used.\r\n");

						warningBuilder.AppendFormat("{0} ignored on vertex {1}!\r\n", pairs[b].bone.name, i);
						continue;
					}

					int boneIndex = boneList.IndexOf(pairs[b].bone);
					float weight = pairs[b].weight;

					switch (b) {
					case 0:
						bw.boneIndex0 = boneIndex;
						bw.weight0 = weight;
						break;
					case 1:
						bw.boneIndex1 = boneIndex;
						bw.weight1 = weight;
						break;
					case 2:
						bw.boneIndex2 = boneIndex;
						bw.weight2 = weight;
						break;
					case 3:
						bw.boneIndex3 = boneIndex;
						bw.weight3 = weight;
						break;
					}
				}

				boneWeights[i] = bw;
			}

			Matrix4x4[] bindPoses = new Matrix4x4[boneList.Count];
			for (int i = 0; i < boneList.Count; i++) {
				bindPoses[i] = boneList[i].worldToLocalMatrix;
			}

			mesh.boneWeights = boneWeights;
			mesh.bindposes = bindPoses;

			string warningString = warningBuilder.ToString();
			if (warningString.Length > 0)
				Debug.LogWarning(warningString);


			return mesh;
		}