Created
September 14, 2016 13:44
-
-
Save rectalogic/47db6d228c85742233c353b6398b92fb to your computer and use it in GitHub Desktop.
Unity3D 5.x component to generate a mesh and control a vertex on the new Cloth component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
[RequireComponent(typeof(SkinnedMeshRenderer), typeof(Cloth))] | |
public class ClothMesh : MonoBehaviour { | |
public float width = 5; | |
public float height = 5; | |
public int xSize = 20; | |
public int ySize = 20; | |
public int controlVertex = 0; | |
private SkinnedMeshRenderer skinnedRenderer; | |
private Cloth cloth; | |
private Transform rootBone; | |
private Transform controlBone; | |
private int controlIndex; | |
private Mesh mesh; | |
void Awake() { | |
skinnedRenderer = GetComponent<SkinnedMeshRenderer>(); | |
cloth = GetComponent<Cloth>(); | |
rootBone = new GameObject("RootBone").transform; | |
rootBone.parent = transform; | |
rootBone.localRotation = Quaternion.identity; | |
rootBone.localPosition = Vector3.zero; | |
controlBone = new GameObject("ControlBone").transform; | |
controlBone.parent = transform; | |
controlBone.localRotation = Quaternion.identity; | |
controlBone.localPosition = Vector3.zero; | |
skinnedRenderer.bones = new Transform[] {rootBone, controlBone}; | |
mesh = CreateMesh(width, height, xSize, ySize); | |
skinnedRenderer.sharedMesh = mesh; | |
ControlVertex(controlVertex); | |
} | |
private IEnumerable<int> IndexNeighbors(int index) { | |
int yCount = ySize + 1; | |
int i = index % yCount; | |
int j = index / yCount; | |
for (int x = Mathf.Max(0, i - 1); x <= Mathf.Min(i + 1, xSize); x++) { | |
for (int y = Mathf.Max(0, j - 1); y <= Mathf.Min(j + 1, ySize); y++) { | |
yield return y * yCount + x; | |
} | |
} | |
} | |
private void ControlVertex(int index) { | |
ClothSkinningCoefficient[] coefficients = cloth.coefficients; | |
BoneWeight[] boneWeights = mesh.boneWeights; | |
// Unset previous control | |
foreach (int i in IndexNeighbors(controlIndex)) { | |
boneWeights[i].boneIndex0 = 0; | |
coefficients[i].maxDistance = Mathf.Infinity; | |
} | |
foreach (int i in IndexNeighbors(index)) { | |
boneWeights[i].boneIndex0 = 1; | |
coefficients[i].maxDistance = 0.3f; | |
} | |
coefficients[index].maxDistance = 0; | |
controlBone.localPosition = cloth.vertices[index]; | |
mesh.bindposes = new Matrix4x4[] {rootBone.worldToLocalMatrix * transform.localToWorldMatrix, controlBone.worldToLocalMatrix * transform.localToWorldMatrix}; | |
mesh.boneWeights = boneWeights; | |
cloth.coefficients = coefficients; | |
controlIndex = index; | |
} | |
private Mesh CreateMesh(float width, float height, int xSize, int ySize) { | |
Mesh mesh = new Mesh(); | |
mesh.name = name + "Mesh"; | |
Vector3[] vertices = new Vector3[(xSize + 1) * (ySize + 1)]; | |
Vector2[] uv = new Vector2[vertices.Length]; | |
float xStep = width / xSize; | |
float hWidth = width / 2.0f; | |
float yStep = height / ySize; | |
float hHeight = height / 2.0f; | |
for (int i = 0, y = 0; y <= ySize; y++) { | |
for (int x = 0; x <= xSize; x++, i++) { | |
vertices[i] = new Vector3((x * xStep) - hWidth, (y * yStep) - hHeight); | |
uv[i] = new Vector2(x / (float)xSize, y / (float)ySize); | |
} | |
} | |
int[] triangles = new int[xSize * ySize * 6]; | |
for (int ti = 0, vi = 0, y = 0; y < ySize; y++, vi++) { | |
for (int x = 0; x < xSize; x++, ti += 6, vi++) { | |
triangles[ti] = vi; | |
triangles[ti + 3] = triangles[ti + 2] = vi + 1; | |
triangles[ti + 4] = triangles[ti + 1] = vi + xSize + 1; | |
triangles[ti + 5] = vi + xSize + 2; | |
} | |
} | |
mesh.vertices = vertices; | |
mesh.uv = uv; | |
mesh.triangles = triangles; | |
mesh.RecalculateNormals(); | |
BoneWeight[] boneWeights = new BoneWeight[vertices.Length]; | |
for (int i = 0; i < boneWeights.Length; i++) { | |
boneWeights[i].weight0 = 1; | |
} | |
mesh.boneWeights = boneWeights; | |
return mesh; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment