//This script needs to be placed on the object whose immediate child is the mesh void Start() { Mesh mesh = MeshGetters.getMesh(this.gameObject); //So my suspicion is that the vertex welding doesn't work on skinned mesh renderers because we're not associating the modified vertices with the appropriate bone anymore. GeometryFunctions.weldVertices(mesh); perturbMesh(); }
Vector3[] newVertices() { Mesh mesh = MeshGetters.getMesh(this.gameObject); int[] triangles = mesh.triangles; Vector3[] triangleA = new Vector3[3];//Lets not allocate new vector3s so much Vector3[] triangleB = new Vector3[3]; bool verticesUpdatedSuccessfully; Vector3[] newVertices; do { newVertices = mesh.vertices; verticesUpdatedSuccessfully = true; //Modify the vertices for (int i = 0; i < newVertices.Length; i++) { wiggleVector3(ref newVertices[i]); } //Check the triangles for collisions for (int i = 0; i < triangles.Length; i += 3) { triangleA[0] = newVertices[triangles[i]]; triangleA[1] = newVertices[triangles[i + 1]]; triangleA[2] = newVertices[triangles[i + 2]]; for (int j = i + 3; j < triangles.Length; j += 3) { triangleB[0] = newVertices[triangles[j]]; triangleB[1] = newVertices[triangles[j + 1]]; triangleB[2] = newVertices[triangles[j + 2]]; if (!GeometryFunctions.triangleNonintersectCheck(triangleA, triangleB)) { verticesUpdatedSuccessfully = false; break; } } } } while (!verticesUpdatedSuccessfully); if (this.saveModel) { MeshSerializer.serializeMesh(mesh, this.name); } return(newVertices); }
// Start is called before the first frame update void Start() { //Get the mesh and the material from the this.mesh = MeshGetters.getTriMesh(1f, 2f); this.grassRenderMaterial = Resources.Load <Material>("Materials/Grass"); grassTransforms = new List <Matrix4x4[]>(); float grassDensity = 0.3f;//1 blade of grass per area unit int[] triangles = MeshGetters.getMeshTriangles(this.gameObject); Vector3[] vertices = MeshGetters.getMeshVertices(this.gameObject); Vector3[] curVertices = new Vector3[3]; int gtbi = 0; Matrix4x4[] grassTransformBuffer = new Matrix4x4[1023]; //Iterate through our triangles array three at a time (one triangle) for (int i = 0; i < triangles.Length; i += 3) { //Convert to vertices curVertices[0] = Vector3.Scale(vertices[triangles[i]], transform.localScale) + transform.position; curVertices[1] = Vector3.Scale(vertices[triangles[i + 1]], transform.localScale) + transform.position; curVertices[2] = Vector3.Scale(vertices[triangles[i + 2]], transform.localScale) + transform.position; float area = GeometryFunctions.getTriangleArea(curVertices); int numBlades = (int)(area * grassDensity); Vector3[] grassLocs = GeometryFunctions.getNLocationsOnTriangle(curVertices, numBlades); for (int j = 0; j < grassLocs.Length; j++) { if (gtbi == 1023) { gtbi = 0; Matrix4x4[] gtBufferCopy = (Matrix4x4[])grassTransformBuffer.Clone(); grassTransforms.Add(gtBufferCopy); } Quaternion rotationQuat = Quaternion.FromToRotation(transform.up, GeometryFunctions.getTriangleNormal(curVertices)); grassTransformBuffer[gtbi] = Matrix4x4.TRS(grassLocs[j], rotationQuat, new Vector3(1, 1, 1)); gtbi++; } } //Get them leftovers grassTransforms.Add(grassTransformBuffer);//this should be truncated and then added to the dynamic list based on the current j //will deal with it later }
void perturbMesh() { Mesh mesh = MeshGetters.getMesh(this.gameObject); //Change the model vertices Vector3[] nv = newVertices(); Vector2[] nuv = mesh.uv; int[] nt = mesh.triangles; mesh.vertices = nv; mesh.uv = nuv; mesh.triangles = nt; mesh.Optimize(); if (this.gameObject.GetComponent <MeshCollider>()) { //UPDATE THE MESH COLLIDER. This code gets used in UseSerializedMesh. Should it be its own thing? DestroyImmediate(this.gameObject.GetComponent <MeshCollider>()); var collider = this.gameObject.AddComponent <MeshCollider>(); collider.sharedMesh = mesh; } }