Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // SliceMesh function makes a single slice - call it twice with reversed plane to make both slices
- // Neither SliceMesh nor Shatter destroys the original object - call destroy as well if you want that
- var ReplacementPrefab : GameObject;
- var ChunkPrefab : GameObject;
- var MyBreakForce : float;
- var SliceSurfaceMaterial : Material;
- var Chaos : float = 1.0f;
- var AttachToGround : boolean = true;
- var GroundJoinMultiplier : float = 2.0f;
- private var thisMeshfilter : MeshFilter;
- private var thisMaterials : Material[];
- function VertexSplit ( outv : Vector3[], outi : int, a : Vector3, b : Vector3, slice : Plane, c : Vector2, d : Vector2, outuv : Vector2[]) {
- var ray : Ray;
- ray.origin=a;
- ray.direction=b-a;
- var origdist : float = Vector3.Distance(b,a);
- var dist : float;
- slice.Raycast(ray,dist);
- outuv[outi] = c + (d-c)*dist/origdist;
- outv[outi] = a + ray.direction*dist;
- }
- private var AntiClockwiseAngles : float[];
- private var slicesurfacematerialindex : int;
- function AntiClockwise ( i1 : int, i2 : int) : int {
- return (AntiClockwiseAngles[i1]<AntiClockwiseAngles[i2])?-1:1;
- }
- public function SliceMesh ( mesh : Mesh, slice : Plane ) : Mesh {
- var i : int;
- var j :int;
- var vertices : Vector3[] = mesh.vertices;
- var uv : Vector2[] = mesh.uv;
- var newmesh=new Mesh();
- var submeshes : int=Mathf.Max(mesh.subMeshCount,slicesurfacematerialindex+1);
- var triangles = MultiDim.JaggedInt(submeshes);
- var vertexinslice : boolean[] = new boolean[vertices.Length];
- var vertexconvert : int[] = new int[vertices.Length];
- var sliceda : boolean = false;
- var slicedb : boolean = false;
- var vertexmove=0;
- for (i=0; i<mesh.subMeshCount; i++) {
- triangles[i]=mesh.GetTriangles(i);
- }
- if (i<submeshes) {
- triangles[i]=new int[0];
- }
- for (i=0; i<vertices.Length; i++) {
- vertexinslice[i]=slice.GetSide(vertices[i]);
- if (vertexinslice[i]) {
- vertexconvert[i]=vertexmove;
- vertexmove++;
- sliceda=true;
- } else {
- slicedb=true;
- }
- }
- if (!sliceda || !slicedb) {return null;}
- var newvertexcount=0;
- var newtrianglecount : int[]=new int[submeshes];
- var newtriangles = MultiDim.JaggedInt(submeshes);
- for (j=0; j<submeshes; j++) {
- for (i=0; i<triangles[j].Length; i+=3) {
- var pointsinslice = (vertexinslice[triangles[j][i]]?1:0) +
- (vertexinslice[triangles[j][i+1]]?1:0) +
- (vertexinslice[triangles[j][i+2]]?1:0);
- switch (pointsinslice) {
- case 0: break;
- case 1:
- newvertexcount += 2;
- newtrianglecount[j] += 3;
- break;
- case 2:
- newvertexcount += 2;
- newtrianglecount[j] += 6;
- break;
- case 3:
- newtrianglecount[j] += 3;
- break;
- }
- }
- newtriangles[j]=new int[newtrianglecount[j]];
- }
- var newvertices : Vector3[] = new Vector3[newvertexcount+vertexmove];
- var newuv : Vector2[] = new Vector2[newvertexcount+vertexmove];
- vertexmove=0;
- for (i=0; i<vertices.Length; i++) {
- if (vertexinslice[i]) {
- newvertices[vertexmove]=vertices[i];
- newuv[vertexmove]=uv[i];
- vertexmove++;
- }
- }
- var oldvertexcount : int = vertexmove;
- for (j=0; j<submeshes; j++) {
- newtrianglecount[j]=0;
- for (i=0; i<triangles[j].Length; i+=3) {
- pointsinslice = (vertexinslice[triangles[j][i]]?1:0) +
- (vertexinslice[triangles[j][i+1]]?2:0) +
- (vertexinslice[triangles[j][i+2]]?4:0);
- switch (pointsinslice) {
- case 0: break;
- case 1:
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i]];
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i]],vertices[triangles[j][i+1]],slice,uv[triangles[j][i]],uv[triangles[j][i+1]],newuv);
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i]],vertices[triangles[j][i+2]],slice,uv[triangles[j][i]],uv[triangles[j][i+2]],newuv);
- break;
- case 2:
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i]],vertices[triangles[j][i+1]],slice,uv[triangles[j][i]],uv[triangles[j][i+1]],newuv);
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+1]];
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i+1]],vertices[triangles[j][i+2]],slice,uv[triangles[j][i+1]],uv[triangles[j][i+2]],newuv);
- break;
- case 3:
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i]];
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+1]];
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i]],vertices[triangles[j][i+2]],slice,uv[triangles[j][i]],uv[triangles[j][i+2]],newuv);
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+1]];
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- newtriangles[j][newtrianglecount[j]++]=vertexmove-1;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i+1]],vertices[triangles[j][i+2]],slice,uv[triangles[j][i+1]],uv[triangles[j][i+2]],newuv);
- break;
- case 4:
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i]],vertices[triangles[j][i+2]],slice,uv[triangles[j][i]],uv[triangles[j][i+2]],newuv);
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i+1]],vertices[triangles[j][i+2]],slice,uv[triangles[j][i+1]],uv[triangles[j][i+2]],newuv);
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+2]];
- break;
- case 5:
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+2]];
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i]];
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i+2]],vertices[triangles[j][i+1]],slice,uv[triangles[j][i+2]],uv[triangles[j][i+1]],newuv);
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i]];
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- newtriangles[j][newtrianglecount[j]++]=vertexmove-1;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i]],vertices[triangles[j][i+1]],slice,uv[triangles[j][i]],uv[triangles[j][i+1]],newuv);
- break;
- case 6:
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+1]];
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+2]];
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i+1]],vertices[triangles[j][i]],slice,uv[triangles[j][i+1]],uv[triangles[j][i]],newuv);
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+2]];
- newtriangles[j][newtrianglecount[j]++]=vertexmove;
- newtriangles[j][newtrianglecount[j]++]=vertexmove-1;
- VertexSplit(newvertices,vertexmove++,vertices[triangles[j][i+2]],vertices[triangles[j][i]],slice,uv[triangles[j][i+2]],uv[triangles[j][i]],newuv);
- break;
- case 7:
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i]];
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+1]];
- newtriangles[j][newtrianglecount[j]++]=vertexconvert[triangles[j][i+2]];
- break;
- }
- }
- }
- var indexorder : int[] = new int[newvertexcount];
- var angles : float[] = new float[newvertexcount];
- var plane1 : Vector3 = Vector3.Cross(slice.normal,Vector3(1,0,0));
- if (Mathf.Abs(plane1.x)<0.1f && Mathf.Abs(plane1.y)<0.1f && Mathf.Abs(plane1.z)<0.1f) plane1 = Vector3.Cross(slice.normal,Vector3(0,0,1));
- plane1.Normalize();
- var plane2 : Vector3 = Vector3.Cross(slice.normal,plane1);
- var midpoint : Vector3 = new Vector3(0,0,0);
- for (i=0; i<newvertexcount; i++) {
- indexorder[i]=i;
- midpoint+=newvertices[oldvertexcount+i];
- }
- midpoint/=newvertexcount;
- var pretempsliceuvs : Vector2[] = new Vector2[newvertexcount];
- for (i=0; i<newvertexcount; i++) {
- var v : Vector3 = newvertices[oldvertexcount+i]-midpoint;
- var x : float = Vector3.Dot(v,plane1);
- var y : float = Vector3.Dot(v,plane2);
- pretempsliceuvs[i].x=x; pretempsliceuvs[i].y=y;
- angles[i]=Mathf.Atan2(x,y);
- }
- var tempsliceuvs : Vector2[] = new Vector2[newvertexcount];
- AntiClockwiseAngles=angles;
- System.Array.Sort(indexorder,AntiClockwise);
- var slicevertexcount : int = 1;
- var tempslicevertices : Vector3[] = new Vector3[newvertexcount];
- tempslicevertices[0]=newvertices[oldvertexcount+indexorder[0]];
- tempsliceuvs[0]=pretempsliceuvs[indexorder[0]];
- var prevline : Vector3 = newvertices[oldvertexcount+indexorder[1]]-newvertices[oldvertexcount+indexorder[0]];
- i=2;
- while (prevline.sqrMagnitude<0.001f && i<newvertexcount) {
- prevline=newvertices[oldvertexcount+indexorder[i]]-newvertices[oldvertexcount+indexorder[0]];
- i++;
- }
- for (; i<newvertexcount; i++) {
- var nextline : Vector3 = newvertices[oldvertexcount+indexorder[i]]-newvertices[oldvertexcount+indexorder[i-1]];
- if (nextline.sqrMagnitude<0.001f) continue;
- if (
- Vector3.Cross(
- nextline,
- prevline).sqrMagnitude>0.001) {
- tempslicevertices[slicevertexcount]=newvertices[oldvertexcount+indexorder[i-1]];
- tempsliceuvs[slicevertexcount]=pretempsliceuvs[indexorder[i-1]];
- slicevertexcount++;
- prevline=nextline;
- }
- }
- nextline = newvertices[oldvertexcount+indexorder[0]]-newvertices[oldvertexcount+indexorder[newvertexcount-1]];
- if (nextline.sqrMagnitude>0.001f && Vector3.Cross(
- nextline,
- prevline).sqrMagnitude>0.001) {
- tempslicevertices[slicevertexcount]=newvertices[oldvertexcount+indexorder[newvertexcount-1]];
- tempsliceuvs[slicevertexcount]=pretempsliceuvs[indexorder[newvertexcount-1]];
- slicevertexcount++;
- }
- newmesh.subMeshCount=submeshes;
- if (slicevertexcount>=3) {
- var fullnewvertices : Vector3[] = new Vector3[vertexmove+slicevertexcount];
- var fullnewuv : Vector2[] = new Vector2[vertexmove+slicevertexcount];
- newvertices.CopyTo(fullnewvertices,0);
- newuv.CopyTo(fullnewuv,0);
- for (i=0; i<slicevertexcount; i++) {
- fullnewvertices[vertexmove+i]=tempslicevertices[i];
- fullnewuv[vertexmove+i]=tempsliceuvs[i];
- }
- var fullnewtriangles : int[] = new int[newtrianglecount[slicesurfacematerialindex] + (slicevertexcount-2)*3];
- newtriangles[slicesurfacematerialindex].CopyTo(fullnewtriangles,0);
- for (i=1; i<slicevertexcount-1; i++) {
- fullnewtriangles[newtrianglecount[slicesurfacematerialindex]++]=vertexmove;
- fullnewtriangles[newtrianglecount[slicesurfacematerialindex]++]=vertexmove+i;
- fullnewtriangles[newtrianglecount[slicesurfacematerialindex]++]=vertexmove+i+1;
- }
- newmesh.vertices=fullnewvertices;
- for (j=0; j<slicesurfacematerialindex; j++) {
- newmesh.SetTriangles(newtriangles[j],j);
- }
- newmesh.SetTriangles(fullnewtriangles,j); j++;
- for (; j<submeshes; j++) {
- newmesh.SetTriangles(newtriangles[j],j);
- }
- newmesh.uv=fullnewuv;
- } else {
- newmesh.vertices=newvertices;
- for (j=0; j<submeshes; j++) {
- newmesh.SetTriangles(newtriangles[j],j);
- }
- newmesh.uv=newuv;
- }
- newmesh.RecalculateNormals();
- return newmesh;
- }
- function MakeChunk ( mesh : Mesh) : GameObject {
- var newobj : GameObject = Instantiate(ChunkPrefab,transform.parent.position,transform.parent.rotation);
- newobj.GetComponent("MeshFilter").sharedMesh = mesh;
- newobj.GetComponent("MeshCollider").sharedMesh = mesh;
- newobj.GetComponent("MeshRenderer").sharedMaterials = thisMaterials;
- return newobj;
- }
- public function Shatter (rows : int, xcols : int, zcols : int, container : GameObject) {
- var mesh : Mesh = thisMeshfilter.sharedMesh;
- var chunks : GameObject[] = new GameObject[xcols*rows*zcols];
- var rowstep : float = mesh.bounds.size.y/rows;
- var xcolstep : float = mesh.bounds.size.x/xcols;
- var zcolstep : float = mesh.bounds.size.z/zcols;
- var row_x_maxangle : float = Mathf.Atan2(rowstep,mesh.bounds.size.x) * Chaos;
- var row_z_maxangle : float = Mathf.Atan2(rowstep,mesh.bounds.size.z) * Chaos;
- var xcol_y_maxangle : float = Mathf.Atan2(xcolstep,mesh.bounds.size.y) * Chaos;
- var xcol_z_maxangle : float = Mathf.Atan2(xcolstep,mesh.bounds.size.z) * Chaos;
- var zcol_x_maxangle : float = Mathf.Atan2(zcolstep,mesh.bounds.size.x) * Chaos;
- var zcol_y_maxangle : float = Mathf.Atan2(zcolstep,mesh.bounds.size.y) * Chaos;
- var x_max=mesh.bounds.max.x;
- var y_max=mesh.bounds.max.y;
- var z_max=mesh.bounds.max.z;
- for (var yit=1; mesh!=null; yit++) {
- var y=y_max-rowstep*yit;
- var topmesh : Mesh;
- if (yit<rows) {
- var row_x_angle : float=Mathf.Rad2Deg * Mathf.Lerp(-row_x_maxangle,row_x_maxangle,Random.value);
- var row_z_angle : float=Mathf.Rad2Deg * Mathf.Lerp(-row_z_maxangle,row_z_maxangle,Random.value);
- var normal : Vector3 = new Vector3(0,1,0);
- var quat : Quaternion = Quaternion.Euler(row_x_angle,0,row_z_angle);
- normal=quat*normal;
- var slice : Plane = new Plane(normal,Vector3(mesh.bounds.center.x,y,mesh.bounds.center.z));
- topmesh = SliceMesh(mesh,slice);
- if (topmesh) {
- slice.normal=-slice.normal; slice.distance=-slice.distance;
- mesh = SliceMesh(mesh,slice);
- }
- } else {
- topmesh = mesh;
- mesh = null;
- }
- if (topmesh) {
- var xmesh : Mesh = topmesh;
- for (var xit=1; xmesh!=null; xit++) {
- var x=x_max-xcolstep*xit;
- var leftmesh : Mesh;
- if (xit<xcols) {
- var xcol_y_angle : float = Mathf.Rad2Deg * Mathf.Lerp(-xcol_y_maxangle,xcol_y_maxangle,Random.value);
- var xcol_z_angle : float = Mathf.Rad2Deg * Mathf.Lerp(-xcol_z_maxangle,xcol_z_maxangle,Random.value);
- var xnormal : Vector3 = new Vector3(1,0,0);
- var xquat : Quaternion = Quaternion.Euler(0,xcol_y_angle,xcol_z_angle);
- xnormal = xquat*xnormal;
- var xslice : Plane = new Plane(xnormal,Vector3(x,xmesh.bounds.center.y,xmesh.bounds.center.z));
- leftmesh = SliceMesh(xmesh,xslice);
- if (leftmesh) {
- xslice.normal=-xslice.normal; xslice.distance=-xslice.distance;
- xmesh = SliceMesh(xmesh,xslice);
- }
- } else {
- leftmesh = xmesh;
- xmesh = null;
- }
- if (leftmesh) {
- var zmesh : Mesh = leftmesh;
- for (var zit=1; zmesh!=null; zit++) {
- var z=z_max-zcolstep*zit;
- var backmesh : Mesh;
- if (zit<zcols) {
- var zcol_x_angle : float = Mathf.Rad2Deg * Mathf.Lerp(-zcol_x_maxangle,zcol_x_maxangle,Random.value);
- var zcol_y_angle : float = Mathf.Rad2Deg * Mathf.Lerp(-zcol_y_maxangle,zcol_y_maxangle,Random.value);
- var znormal : Vector3 = new Vector3(0,0,1);
- var zquat : Quaternion = Quaternion.Euler(zcol_x_angle,zcol_y_angle,0);
- znormal = zquat * znormal;
- var zslice : Plane = new Plane(znormal,Vector3(zmesh.bounds.center.x,zmesh.bounds.center.y,z));
- backmesh = SliceMesh(zmesh,zslice);
- if (backmesh) {
- zslice.normal=-zslice.normal; zslice.distance=-zslice.distance;
- zmesh = SliceMesh(zmesh,zslice);
- }
- } else {
- backmesh=zmesh;
- zmesh=null;
- }
- if (backmesh) {
- var newobj : GameObject=MakeChunk(backmesh);
- chunks[(zit-1)*xcols*rows + (yit-1)*xcols + (xit-1)]=newobj;
- newobj.transform.parent=container.transform;
- }
- }
- }
- }
- }
- }
- for (xit=0; xit<xcols; xit++) {
- for (yit=0; yit<rows; yit++) {
- for (zit=0; zit<zcols; zit++) {
- var joint : FixedJoint;
- if (xit!=0) {
- joint = chunks[zit*xcols*rows + yit*xcols + xit].AddComponent("FixedJoint");
- joint.connectedBody=chunks[zit*xcols*rows + yit*xcols + xit-1].rigidbody;
- joint.breakForce=MyBreakForce;
- joint.breakTorque=MyBreakForce;
- }
- if (yit!=rows-1) {
- joint = chunks[zit*xcols*rows + yit*xcols + xit].AddComponent("FixedJoint");
- joint.connectedBody=chunks[zit*xcols*rows + (yit+1)*xcols + xit].rigidbody;
- joint.breakForce=MyBreakForce;
- joint.breakTorque=MyBreakForce;
- } else if (AttachToGround) {
- joint = chunks[zit*xcols*rows + yit*xcols + xit].AddComponent("FixedJoint");
- joint.breakForce=MyBreakForce*GroundJoinMultiplier;
- joint.breakTorque=MyBreakForce*GroundJoinMultiplier;
- }
- if (zit!=0) {
- joint = chunks[zit*xcols*rows + yit*xcols + xit].AddComponent("FixedJoint");
- joint.connectedBody=chunks[(zit-1)*xcols*rows + yit*xcols + xit].rigidbody;
- joint.breakForce=MyBreakForce;
- joint.breakTorque=MyBreakForce;
- }
- }
- }
- }
- }
- function Awake() {
- thisMeshfilter = ReplacementPrefab.GetComponent("MeshFilter");
- thisMaterials = ReplacementPrefab.GetComponent("MeshRenderer").sharedMaterials;
- if (thisMeshfilter==null) {
- Debug.Log("ReplacementPrefab must exist and contain a mesh.");
- }
- if (!ChunkPrefab) {
- Debug.Log("ChunkPrefab needs to be set.");
- }
- if (SliceSurfaceMaterial==null) {
- slicesurfacematerialindex=0;
- } else {
- for (var i : int=0; i<thisMaterials.Length; i++) {
- if (thisMaterials[i]==SliceSurfaceMaterial) {
- break;
- }
- }
- slicesurfacematerialindex=i;
- if (i>=thisMaterials.Length) {
- var newmaterials=new Material[i+1];
- thisMaterials.CopyTo(newmaterials,0);
- newmaterials[i]=SliceSurfaceMaterial;
- thisMaterials=newmaterials;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement