function Update () { var meF : MeshFilter = GetComponent(MeshFilter); if(meF) mesh = meF.mesh; var vertices = mesh.vertices; var normals = mesh.normals; for (var i=0; i<vertices.length; i++) { vertices[i] += normals[i] * 2.0 * Time.deltaTime; } mesh.vertices = vertices; }
To prevent this disintegration from happening we need to find all vertices that share identical positions and find one average normal per group of identicals. First the result, then the code:
private var mesh : Mesh; private var vertices = new Vector3[0]; private var normals = new Vector3[0]; var finalNormals = new Vector3[0]; function Start () { var meF : MeshFilter = GetComponent(MeshFilter); mesh = meF.mesh; vertices = mesh.vertices; normals = mesh.normals; //Find identical vertices var vertexIDs = new int[vertices.length]; //this will hold an ID for each vertex, vertices at the same position will share the same ID! var counter : int = 0; for (var i = 0; i < vertices.length; i++) { for (var j = 0; j < vertices.length; j++) { if(vertexIDs[i] == 0) { counter++; vertexIDs[i] = counter; } if(i != j) { if(vertices[i] == vertices[j] && vertices[i] != 0) { vertexIDs[j] = vertexIDs[i]; } print(i + ", " + j + ":" + vertices[j] + " (" + vertexIDs[j] + ")"); } } } finalNormals = normals; //Calcualte average normals for(k = 1; k <= counter; k++) { //counter is the highest vertexID, now go through all the groups and collect normal data var curAvgNormal : Vector3 = Vector3.zero; for(l = 0; l < vertexIDs.length; l++) { if(vertexIDs[l] == k) { curAvgNormal += normals[l]; //Add up all the normals of the vertices with identical positions } } curAvgNormal.Normalize(); //Normalize the result for(m = 0; m < vertexIDs.length; m++) { if(vertexIDs[m] == k) finalNormals[m] = curAvgNormal; } } } function Update () { for (var i = 0; i < vertices.length; i++) { vertices[i] += finalNormals[i] * 2.0 * Time.deltaTime; } mesh.vertices = vertices; }
This code is horribly inefficient though and calculating the average normals will take forever. (Unity will hang and the little colorful wheel will spin until it’s done) So don’t try this on any object with more than 200 or so triangles unless you have a lot of time… (please add your optimization tips in the comments below :])
private var mesh : Mesh; private var vertices = new Vector3[0]; private var normals = new Vector3[0]; var finalNormals = new Vector3[0]; function Start () { var meF : MeshFilter = GetComponent(MeshFilter); mesh = meF.mesh; vertices = mesh.vertices; normals = mesh.normals; } function Update () { for (var i = 0; i < vertices.length; i++) { vertices[i] += finalNormals[i] * 2.0 * Time.deltaTime; } mesh.vertices = vertices; }
Okay, not bad. There’s still room for improvement though: It will look even more realistic (well, that is if you would classify “blowing up a wooden table” as “realistic”) if you also slowly scale up the gameObject with transform.localScale:
2 Comments
if you were planning on only running this on a desktop and not an iPhone, I'd recommend doing the actual manipulation of vertex positions within a vertex shader program.
I'd pass along with the position data its normal to move along and perform the "blow up" from there — as long as you submit your averaged normals rather than the mesh normals I don't see why this wouldn't work out for you
yeah, this is for an iPhone game… And to my surprise it even runs well!
plus I don't know enough about vertex shaders… :) Thanks for the tip though!