public static List<GameObject> GenerateTriangularPieces(GameObject source, int extraPoints = 0, int subshatterSteps = 0, Material mat = null) { List<GameObject> pieces = new List<GameObject>(); if (mat == null) { mat = createFragmentMaterial(source); } //get transform information Vector3 origScale = source.transform.localScale; source.transform.localScale = Vector3.one; Quaternion origRotation = source.transform.localRotation; source.transform.localRotation = Quaternion.identity; //get rigidbody information Vector2 origVelocity = source.GetComponent<Rigidbody2D>().velocity; //get collider information PolygonCollider2D sourcePolyCollider = source.GetComponent<PolygonCollider2D>(); BoxCollider2D sourceBoxCollider = source.GetComponent<BoxCollider2D>(); List<Vector2> points = new List<Vector2>(); List<Vector2> borderPoints = new List<Vector2>(); //add points from the present collider if (sourcePolyCollider != null) { points = getPoints(sourcePolyCollider); borderPoints = getPoints(sourcePolyCollider); } else if (sourceBoxCollider != null) { points = getPoints(sourceBoxCollider); borderPoints = getPoints(sourceBoxCollider); } //create a bounding rectangle based on the polygon points Rect rect = getRect(source); //if the target polygon is a triangle, generate a point in the middle to allow for fracture if (points.Count == 3) { points.Add((points[0] + points[1] + points[2]) / 3); } for (int i = 0; i < extraPoints; i++) { points.Add(new Vector2(Random.Range(rect.width / -2, rect.width / 2), Random.Range(rect.height / -2 + rect.center.y, rect.height / 2 + rect.center.y))); } Voronoi voronoi = new Delaunay.Voronoi(points, null, rect); List<List<Vector2>> clippedTriangles = new List<List<Vector2>>(); foreach (Triangle tri in voronoi.Triangles()) { clippedTriangles = ClipperHelper.clip(borderPoints, tri); foreach (List<Vector2> triangle in clippedTriangles) { pieces.Add(generateTriangularPiece(source, triangle, origVelocity, origScale, origRotation, mat)); } } List<GameObject> morePieces = new List<GameObject>(); if (subshatterSteps > 0) { subshatterSteps--; foreach (GameObject piece in pieces) { morePieces.AddRange(SpriteExploder.GenerateTriangularPieces(piece, extraPoints, subshatterSteps, mat)); GameObject.DestroyImmediate(piece); } } else { morePieces = pieces; } //reset transform information source.transform.localScale = origScale; source.transform.localRotation = origRotation; Resources.UnloadUnusedAssets(); return morePieces; }
void Update() { if (aud_shakeIt_springingBegin == true) { aud_shakeIt_springingBegin = false; } selectedGO = UnityEditor.Selection.activeGameObject; hitpoint_camToMouse = mouseRaycast_script.hitpoint; Input_DoubleClick(); // ***************************** // new Delaunay of only the void points...because our mesh needs to be made out of triangles anyway newDelaunay_Vertices2D = new List <Vector2>(); colorsForDelaunay = new List <uint>(); sumX = 0; sumZ = 0; for (int i = 0; i < boundingQbits_allInfo.Count; i++) { // stuff for new delaunay... Vector3 positionForDelaunay; if (boundingQbits_allInfo[i].qbitMovementScript.qtype == 1) { positionForDelaunay = boundingQbits_allInfo[i].transform.position; } else { positionForDelaunay = boundingQbits_allInfo[i].qbitMovementScript.jittery_centerPosition; } newDelaunay_Vertices2D.Add(new Vector2(positionForDelaunay.x, positionForDelaunay.z)); sumX += positionForDelaunay.x; sumZ += positionForDelaunay.z; colorsForDelaunay.Add(0); } Delaunay.Voronoi voronoi = new Delaunay.Voronoi(newDelaunay_Vertices2D, colorsForDelaunay, new Rect(0, 0, floorWidth, floorHeight)); trianglesFromNewDelaunay = voronoi.Triangles(); convexHullPts_FromNewDelaunay = voronoi.HullPointsInOrder(); meshArea = 0; voidMesh_Vertices3D = new Vector3[trianglesFromNewDelaunay.Count * 3]; voidMesh_Triangles = new int[trianglesFromNewDelaunay.Count * 3]; if (swarmParams_script.void_upsideDownReveal_on == true && iAmOpen == true) { // prepare randRange for Y values for voidMesh_Vertices3D generated below upsideDownReveal_amp = swarmParams_script.void_upsideDownReveal_ampLocal; // the max allowed Y height is scaled from the current upsideDownReveal_amp upsideDownReveal_meshY_randRange = new Vector2(0f, Scale(upsideDownReveal_amp, 0f, 1f, 0f, upsideDownReveal_meshY_maxHeight)); } else { // 0 Y height, cuz not upsideDownReveal upsideDownReveal_meshY_randRange = Vector2.one * 0f; } for (int t = 0; t < trianglesFromNewDelaunay.Count; t++) { int index0 = t * 3; int index1 = (t * 3) + 1; int index2 = (t * 3) + 2; voidMesh_Triangles[index0] = index0; voidMesh_Triangles[index1] = index1; voidMesh_Triangles[index2] = index2; float[] y_values = new float[3]; int indexRand = Random.Range(0, 3); float randValue = Random.Range(upsideDownReveal_meshY_randRange[0], upsideDownReveal_meshY_randRange[1]); for (int i = 0; i < y_values.Length; i++) { if (i == indexRand) { y_values[i] = randValue; } else { y_values[i] = 0; } } voidMesh_Vertices3D[index0] = new Vector3(trianglesFromNewDelaunay[t].sites[0].Coord.x, y_values[0], trianglesFromNewDelaunay[t].sites[0].Coord.y); voidMesh_Vertices3D[index1] = new Vector3(trianglesFromNewDelaunay[t].sites[1].Coord.x, y_values[1], trianglesFromNewDelaunay[t].sites[1].Coord.y); voidMesh_Vertices3D[index2] = new Vector3(trianglesFromNewDelaunay[t].sites[2].Coord.x, y_values[2], trianglesFromNewDelaunay[t].sites[2].Coord.y); meshArea += delaunayScript.TriangleArea(trianglesFromNewDelaunay[t]); } // ***************************** // opening and closing the void... // destroy me if below area thresh if (meshArea < trackingAreaThresh) { AllPolysOff(); Destroy(gameObject); // Destroy() finishes excecuting the Update() loop, which leads to the polys turning back on - boo // so we create a bool here telling the ReportOSC() to not execute this frame destroyMe = true; } // opening... if (meshArea >= xfadeAreaThresh && startOpening == true) { startOpening = false; isClosing = false; isOpening = true; voidXfadePhase = 0; xfadeStartTime = Time.time; colorStart = colorClosed; colorEnd = colorOpen; } // closing... if (meshArea < xfadeAreaThresh && isOpening == false && startOpening == false) { startClosing = true; } if (startClosing == true) { isClosing = true; startClosing = false; startOpening = true; voidXfadePhase = 0; xfadeStartTime = Time.time; colorStart = colorOpen; colorEnd = colorClosed; } // xfading for opening and closing... if (voidXfadePhase != -1) { if (isOpening == true) { voidXfadePhase = (Time.time - xfadeStartTime) / xfadeTotalTime; voidMaterial.color = Color.Lerp(colorStart, colorEnd, voidXfadePhase); if (voidXfadePhase >= 1.0f) { iAmOpen = true; aud_voidOpen_click = true; isOpening = false; voidXfadePhase = -1; } } else if (isClosing == true) { voidXfadePhase = (Time.time - xfadeStartTime) / xfadeTotalTime; voidMaterial.color = Color.Lerp(colorStart, colorEnd, voidXfadePhase); if (voidXfadePhase >= 1.0f) { iAmOpen = false; isClosing = false; aud_voidClose_click = true; // EdgeMovingPolyOff(); <-- todo delete ShakeItPolyOff(); } } } // ***************************** // draw mesh // draw the mesh... voidMesh.Clear(); voidMesh.vertices = voidMesh_Vertices3D; voidMesh.triangles = voidMesh_Triangles; voidMesh.RecalculateNormals(); meshCentroid = new Vector3(sumX / boundingQbits_allInfo.Count, 0, sumZ / boundingQbits_allInfo.Count); // ScaleAround( this.gameObject, meshCentroid, new Vector3( voidScale, voidScale, voidScale) ); // ***************************** // static, shakeIt if ((isOpening == true || iAmOpen == true) && isClosing == false) { Input_ShakeIt(); // EdgeMoving(); } if (iAmOpen == true && isClosing == false) { VoidStatic(); } // ***************************** // prepare data for Qbits, etc // this method includes concave detection: Build_ConvexHullOrder_AllInfo(); // we also separately maintain an array of all the positions because the Method in QbitMovement.cs that checks for // qbits inside voids needs a Vector2[] - and I did not write that method: boundingQbits_convexHullOrder_positions = new Vector2[convexHullPts_FromNewDelaunay.Count]; convexHullPts_FromNewDelaunay.CopyTo(boundingQbits_convexHullOrder_positions); // to self_voidAllInfo contribute info... // area, centroid, and convexHullOrder_allInfo, igniterEvent, shakeIt etc self_voidAllInfo.area = meshArea; self_voidAllInfo.centroid = meshCentroid; self_voidAllInfo.isOpening = isOpening; self_voidAllInfo.isOpen = iAmOpen; self_voidAllInfo.boundingQbits_convexHullOrder_positions = boundingQbits_convexHullOrder_positions; self_voidAllInfo.boundingQbits_convexHullOrder_allInfo = boundingQbits_convexHullOrder_allInfo; self_voidAllInfo.hitby_igniter = aud_hitby_igniter; self_voidAllInfo.hitby_voidIgniterType = hitby_voidIgniterType; self_voidAllInfo.shakeIt_displacingBegin = aud_shakeIt_displacingBegin; self_voidAllInfo.shakeIt_springingBegin = aud_shakeIt_springingBegin; // ***************************** // osc if (destroyMe == false) { ReportOsc(); } /* * if (selectedGO != null) * { * if (selectedGO.name == this.transform.name) * { Debug.Log("allInfo " + ( self_voidAllInfo == null ) + " prev " + ( self_voidAllInfoPrev == null)); } * }*/ // ***************************** // prev, setbacks self_voidAllInfoPrev = self_voidAllInfo.DeepCopy(); mouse_hitMePrev = mouse_hitMe; localPosPrev = transform.position; aud_static_oneClick = false; }
private static int[] calcTriangles(Voronoi region) { //calculate unity triangles int[] triangles = new int[region.Triangles().Count*3]; List<Site> sites = region.Sites()._sites; int idx = 0; foreach (Triangle t in region.Triangles()) { triangles[idx++] = sites.IndexOf(t.sites[0]); triangles[idx++] = sites.IndexOf(t.sites[1]); triangles[idx++] = sites.IndexOf(t.sites[2]); } return triangles; }
public static List <GameObject> GenerateTriangularPieces(GameObject source, int extraPoints = 0, int subshatterSteps = 0, Material mat = null) { List <GameObject> pieces = new List <GameObject>(); if (mat == null) { mat = createFragmentMaterial(source); } //get transform information Vector3 origScale = source.transform.localScale; source.transform.localScale = Vector3.one; Quaternion origRotation = source.transform.localRotation; source.transform.localRotation = Quaternion.identity; //get rigidbody information Vector2 origVelocity = source.GetComponent <Rigidbody2D>().velocity; //get collider information PolygonCollider2D sourcePolyCollider = source.GetComponent <PolygonCollider2D>(); BoxCollider2D sourceBoxCollider = source.GetComponent <BoxCollider2D>(); List <Vector2> points = new List <Vector2>(); List <Vector2> borderPoints = new List <Vector2>(); //add points from the present collider if (sourcePolyCollider != null) { points = getPoints(sourcePolyCollider); borderPoints = getPoints(sourcePolyCollider); } else if (sourceBoxCollider != null) { points = getPoints(sourceBoxCollider); borderPoints = getPoints(sourceBoxCollider); } //create a bounding rectangle based on the polygon points Rect rect = getRect(source); //if the target polygon is a triangle, generate a point in the middle to allow for fracture if (points.Count == 3) { points.Add((points[0] + points[1] + points[2]) / 3); } for (int i = 0; i < extraPoints; i++) { points.Add(new Vector2(Random.Range(rect.width / -2, rect.width / 2), Random.Range(rect.height / -2 + rect.center.y, rect.height / 2 + rect.center.y))); } Voronoi voronoi = new Delaunay.Voronoi(points, null, rect); List <List <Vector2> > clippedTriangles = new List <List <Vector2> >(); foreach (Triangle tri in voronoi.Triangles()) { clippedTriangles = ClipperHelper.clip(borderPoints, tri); foreach (List <Vector2> triangle in clippedTriangles) { pieces.Add(generateTriangularPiece(source, triangle, origVelocity, origScale, origRotation, mat)); } } List <GameObject> morePieces = new List <GameObject>(); if (subshatterSteps > 0) { subshatterSteps--; foreach (GameObject piece in pieces) { morePieces.AddRange(SpriteExploder.GenerateTriangularPieces(piece, extraPoints, subshatterSteps, mat)); GameObject.DestroyImmediate(piece); } } else { morePieces = pieces; } //reset transform information source.transform.localScale = origScale; source.transform.localRotation = origRotation; Resources.UnloadUnusedAssets(); return(morePieces); }