public override bool Run(float frameBudget) { int count = this.core.postList.Count; while (this.core.poolIdx < count) { MeshObject post = this.core.postList[this.core.poolIdx]; ++this.core.poolIdx; bool flag = false; if (this.core.parameters.SplitMeshIslands || Object.op_Implicit((Object)post.option) && post.option.SplitMeshIslands) { List <ExploderMesh> exploderMeshList = MeshUtils.IsolateMeshIslands(post.mesh); if (exploderMeshList != null) { flag = true; foreach (ExploderMesh exploderMesh in exploderMeshList) { this.islands.Add(new MeshObject() { mesh = exploderMesh, material = post.material, transform = post.transform, original = post.original, skinnedOriginal = post.skinnedOriginal, parent = post.transform.parent, position = post.transform.position, rotation = post.transform.rotation, localScale = post.transform.localScale, option = post.option }); } } } if (!flag) { this.islands.Add(post); } if ((double)this.Watch.ElapsedMilliseconds > (double)frameBudget) { return(false); } } this.core.postList = this.islands; this.Watch.Stop(); return(true); }
void Triangulate(List <Dictionary <int, int> > contours, Plane plane, List <Vector3>[] vertices, List <Vector3>[] normals, List <Vector2>[] uvs, List <Vector4>[] tangents, List <Color32>[] colors, List <int>[] triangles, bool uvCutMesh, bool useTangents, bool useColors, bool useNormals) { if (contours.Count == 0 || contours[0].Count < 3) { // Utils.Log("Contour empty!: "); return; } // prepare plane matrix var m = plane.GetPlaneMatrix(); var mInv = m.inverse; var zShit = 0.0f; var polygons = new List <Polygon>(contours.Count); // construct polygons from contours Polygon highAreaPoly = null; foreach (var ctr in contours) { var polygonPoints = new Vector2[ctr.Count]; var j = 0; foreach (var i in ctr.Values) { var p = mInv * vertices[0][i]; polygonPoints[j++] = p; // save z-coordinate zShit = p.z; } var polygon = new Polygon(polygonPoints); polygons.Add(polygon); if (highAreaPoly == null || Mathf.Abs(highAreaPoly.Area) < Mathf.Abs(polygon.Area)) { highAreaPoly = polygon; } } ExploderUtils.Assert(polygons.Count > 0, "Zero polygons!"); // test for holes if (polygons.Count > 0) { var polyToRemove = new List <Polygon>(); foreach (var polygon in polygons) { if (polygon != highAreaPoly) { if (highAreaPoly.IsPointInside(polygon.Points[0])) { highAreaPoly.AddHole(polygon); polyToRemove.Add(polygon); } } } foreach (var polygon in polyToRemove) { polygons.Remove(polygon); } } var vertCounter0 = vertices[0].Count; var vertCounter1 = vertices[1].Count; foreach (var polygon in polygons) { if (!polygon.Triangulate(polygonIndicesArray)) { continue; } // ExploderUtils.Assert(indices.Count == polygonIndicesArray.Count, "Count mismatch!"); // // for (int i = 0; i < indices.Count; i++) // { // ExploderUtils.Assert(polygonIndicesArray[i] == indices[i], "Indices not match: " + polygons.Count); // // if (indices[i] != polygonIndicesArray[i]) // { // ExploderUtils.Assert(false, ""); // } // } // get polygon bounding square size var min = Mathf.Min(polygon.Min.x, polygon.Min.y); var max = Mathf.Max(polygon.Max.x, polygon.Max.y); var polygonSize = max - min; // Utils.Log("PolygonSize: " + polygonSize + " " + polygon.Min + " " + polygon.Max); // Utils.Log("Triangulate polygons: " + polygon.Points.Length); foreach (var polyPoint in polygon.Points) { var p = m * new Vector3(polyPoint.x, polyPoint.y, zShit); vertices[0].Add(p); vertices[1].Add(p); if (useNormals) { normals[0].Add(-plane.Normal); normals[1].Add(plane.Normal); } if (uvCutMesh) { var uv0 = new Vector2((polyPoint.x - min) / polygonSize, (polyPoint.y - min) / polygonSize); var uv1 = new Vector2((polyPoint.x - min) / polygonSize, (polyPoint.y - min) / polygonSize); // normalize uv to fit cross-section uv area var areaSizeX = crossSectionUV.z - crossSectionUV.x; var areaSizeY = crossSectionUV.w - crossSectionUV.y; uv0.x = crossSectionUV.x + uv0.x * areaSizeX; uv0.y = crossSectionUV.y + uv0.y * areaSizeY; uv1.x = crossSectionUV.x + uv1.x * areaSizeX; uv1.y = crossSectionUV.y + uv1.y * areaSizeY; uvs[0].Add(uv0); uvs[1].Add(uv1); } else { uvs[0].Add(Vector2.zero); uvs[1].Add(Vector2.zero); } if (useTangents) { // fast and dirty way to create tangents var v0 = plane.Normal; MeshUtils.Swap(ref v0.x, ref v0.y); MeshUtils.Swap(ref v0.y, ref v0.z); Vector4 tangent = Vector3.Cross(plane.Normal, v0); tangent.w = 1.0f; tangents[0].Add(tangent); tangent.w = -1.0f; tangents[1].Add(tangent); } if (useColors) { colors[0].Add(crossSectionVertexColour); colors[1].Add(crossSectionVertexColour); } } var indicesCount = polygonIndicesArray.Count; var j = indicesCount - 1; for (int i = 0; i < indicesCount; i++) { triangles[0].Add(vertCounter0 + polygonIndicesArray[i]); triangles[1].Add(vertCounter1 + polygonIndicesArray[j]); j--; } vertCounter0 += polygon.Points.Length; vertCounter1 += polygon.Points.Length; } }
public override bool Run(float frameBudget) { var count = core.pool.Count; while (core.poolIdx < count) { var fragment = core.pool[core.poolIdx]; var mesh = core.postList[core.poolIdx]; core.poolIdx++; if (!mesh.original) { continue; } var unityMesh = mesh.mesh.ToUnityMesh(); fragment.meshFilter.sharedMesh = unityMesh; // choose proper material if (mesh.option && mesh.option.FragmentMaterial) { fragment.meshRenderer.sharedMaterial = mesh.option.FragmentMaterial; } else { if (core.parameters.FragmentOptions.FragmentMaterial != null) { fragment.meshRenderer.sharedMaterial = core.parameters.FragmentOptions.FragmentMaterial; } else { fragment.meshRenderer.sharedMaterial = mesh.material; } } unityMesh.RecalculateBounds(); var oldParent = fragment.transform.parent; fragment.transform.parent = mesh.parent; fragment.transform.position = mesh.position; fragment.transform.rotation = mesh.rotation; fragment.transform.localScale = mesh.localScale; fragment.transform.parent = null; fragment.transform.parent = oldParent; if (core.parameters.PartialExplosion) { } else { if (mesh.original != core.parameters.ExploderGameObject) { ExploderUtils.SetActiveRecursively(mesh.original, false); } else { ExploderUtils.EnableCollider(mesh.original, false); ExploderUtils.SetVisible(mesh.original, false); } if (mesh.skinnedOriginal && mesh.skinnedOriginal != core.parameters.ExploderGameObject) { ExploderUtils.SetActiveRecursively(mesh.skinnedOriginal, false); } else { ExploderUtils.EnableCollider(mesh.skinnedOriginal, false); ExploderUtils.SetVisible(mesh.skinnedOriginal, false); } if (mesh.skinnedOriginal && mesh.bakeObject) { GameObject.DestroyObject(mesh.bakeObject, 1); } } var plane = mesh.option && mesh.option.Plane2D; var use2d = core.parameters.Use2DCollision; if (!core.parameters.FragmentOptions.DisableColliders) { if (core.parameters.MeshColliders && !use2d) { // dont use mesh colliders for 2d plane if (!plane) { fragment.meshCollider.sharedMesh = unityMesh; } } else { if (core.parameters.Use2DCollision) { MeshUtils.GeneratePolygonCollider(fragment.polygonCollider2D, unityMesh); } else { fragment.boxCollider.center = unityMesh.bounds.center; fragment.boxCollider.size = unityMesh.bounds.extents; } } } if (mesh.option) { mesh.option.DuplicateSettings(fragment.options); } fragment.Explode(); var force = core.parameters.Force; if (mesh.option && mesh.option.UseLocalForce) { force = mesh.option.Force; } // apply force to rigid body fragment.ApplyExplosion(mesh.transform, mesh.mesh.centroid, core.parameters.Position, core.parameters.FragmentOptions, core.parameters.UseForceVector, core.parameters.ForceVector, force, mesh.original, core.parameters.TargetFragments); #if SHOW_DEBUG_LINES UnityEngine.Debug.DrawLine(settings.Position, forceVector * settings.Force, Color.yellow, 3); #endif if (Watch.ElapsedMilliseconds > frameBudget) { return(false); } } if (core.parameters.DestroyOriginalObject) { foreach (var mesh in core.postList) { if (mesh.original && !mesh.original.GetComponent <Fragment>()) { Object.Destroy(mesh.original); } if (mesh.skinnedOriginal) { Object.Destroy(mesh.skinnedOriginal); } } } if (core.parameters.ExplodeSelf) { if (!core.parameters.DestroyOriginalObject) { ExploderUtils.SetActiveRecursively(core.parameters.ExploderGameObject, false); } } if (core.parameters.HideSelf) { ExploderUtils.SetActiveRecursively(core.parameters.ExploderGameObject, false); } #if DBG ExploderUtils.Log("Explosion finished! " + postList.Count + postList[0].original.transform.gameObject.name); #endif // core.exploder.OnExplosionFinished(true); Watch.Stop(); return(true); }
public override bool Run(float frameBudget) { if (crackedObject == null) { return(true); } var count = crackedObject.pool.Count; while (core.poolIdx < count) { var fragment = crackedObject.pool[core.poolIdx]; var mesh = core.postList[core.poolIdx]; core.poolIdx++; if (!mesh.original) { continue; } ExploderUtils.SetActiveRecursively(fragment.gameObject, false); var unityMesh = mesh.mesh.ToUnityMesh(); fragment.meshFilter.sharedMesh = unityMesh; // choose proper material if (mesh.option && mesh.option.FragmentMaterial) { fragment.meshRenderer.sharedMaterial = mesh.option.FragmentMaterial; } else { if (core.parameters.FragmentOptions.FragmentMaterial != null) { fragment.meshRenderer.sharedMaterial = core.parameters.FragmentOptions.FragmentMaterial; } else { fragment.meshRenderer.sharedMaterial = mesh.material; } } unityMesh.RecalculateBounds(); var oldParent = fragment.transform.parent; fragment.transform.parent = mesh.parent; fragment.transform.position = mesh.position; fragment.transform.rotation = mesh.rotation; fragment.transform.localScale = mesh.localScale; fragment.transform.parent = null; fragment.transform.parent = oldParent; fragment.cracked = true; var plane = mesh.option && mesh.option.Plane2D; var use2d = core.parameters.Use2DCollision; if (!core.parameters.FragmentOptions.DisableColliders) { if (core.parameters.MeshColliders && !use2d) { // dont use mesh colliders for 2d plane if (!plane) { fragment.meshCollider.sharedMesh = unityMesh; } } else { if (core.parameters.Use2DCollision) { MeshUtils.GeneratePolygonCollider(fragment.polygonCollider2D, unityMesh); } else { fragment.boxCollider.center = unityMesh.bounds.center; fragment.boxCollider.size = unityMesh.bounds.extents; } } } if (mesh.option) { mesh.option.DuplicateSettings(fragment.options); } var force = core.parameters.Force; if (mesh.option && mesh.option.UseLocalForce) { force = mesh.option.Force; } // apply force to rigid body fragment.ApplyExplosion(mesh.transform, mesh.mesh.centroid, core.parameters.Position, core.parameters.FragmentOptions, core.parameters.UseForceVector, core.parameters.ForceVector, force, mesh.original, core.parameters.TargetFragments); #if SHOW_DEBUG_LINES UnityEngine.Debug.DrawLine(settings.Position, forceVector * settings.Force, Color.yellow, 3); #endif if (Watch.ElapsedMilliseconds > frameBudget) { return(false); } } Watch.Stop(); return(true); }
public override bool Run(float frameBudget) { int count = this.core.pool.Count; while (this.core.poolIdx < count) { Fragment fragment = this.core.pool[this.core.poolIdx]; MeshObject post = this.core.postList[this.core.poolIdx]; ++this.core.poolIdx; if (Object.op_Implicit((Object)post.original)) { Mesh unityMesh = post.mesh.ToUnityMesh(); fragment.AssignMesh(unityMesh); if (Object.op_Implicit((Object)post.option) && Object.op_Implicit((Object)post.option.FragmentMaterial)) { ((Renderer)fragment.meshRenderer).set_sharedMaterial(post.option.FragmentMaterial); } else if (Object.op_Inequality((Object)this.core.parameters.FragmentOptions.FragmentMaterial, (Object)null)) { ((Renderer)fragment.meshRenderer).set_sharedMaterial(this.core.parameters.FragmentOptions.FragmentMaterial); } else { ((Renderer)fragment.meshRenderer).set_sharedMaterial(post.material); } unityMesh.RecalculateBounds(); Transform parent = ((Component)fragment).get_transform().get_parent(); ((Component)fragment).get_transform().set_parent(post.parent); ((Component)fragment).get_transform().set_position(post.position); ((Component)fragment).get_transform().set_rotation(post.rotation); ((Component)fragment).get_transform().set_localScale(post.localScale); ((Component)fragment).get_transform().set_parent((Transform)null); ((Component)fragment).get_transform().set_parent(parent); if (Object.op_Inequality((Object)post.original, (Object)this.core.parameters.ExploderGameObject)) { ExploderUtils.SetActiveRecursively(post.original, false); } else { ExploderUtils.EnableCollider(post.original, false); ExploderUtils.SetVisible(post.original, false); } if (Object.op_Implicit((Object)post.skinnedOriginal) && Object.op_Inequality((Object)post.skinnedOriginal, (Object)this.core.parameters.ExploderGameObject)) { ExploderUtils.SetActiveRecursively(post.skinnedOriginal, false); } else { ExploderUtils.EnableCollider(post.skinnedOriginal, false); ExploderUtils.SetVisible(post.skinnedOriginal, false); } if (Object.op_Implicit((Object)post.skinnedOriginal) && Object.op_Implicit((Object)post.bakeObject)) { Object.Destroy((Object)post.bakeObject, 1f); } bool flag = Object.op_Implicit((Object)post.option) && post.option.Plane2D; bool use2Dcollision = this.core.parameters.Use2DCollision; if (!this.core.parameters.FragmentOptions.DisableColliders) { if (this.core.parameters.FragmentOptions.MeshColliders && !use2Dcollision) { if (!flag) { fragment.meshCollider.set_sharedMesh(unityMesh); } } else if (this.core.parameters.Use2DCollision) { MeshUtils.GeneratePolygonCollider(fragment.polygonCollider2D, unityMesh); } else { BoxCollider boxCollider1 = fragment.boxCollider; Bounds bounds1 = unityMesh.get_bounds(); Vector3 center = ((Bounds) ref bounds1).get_center(); boxCollider1.set_center(center); BoxCollider boxCollider2 = fragment.boxCollider; Bounds bounds2 = unityMesh.get_bounds(); Vector3 extents = ((Bounds) ref bounds2).get_extents(); boxCollider2.set_size(extents); } } fragment.Explode(this.core.parameters); float force = this.core.parameters.Force; if (Object.op_Implicit((Object)post.option) && post.option.UseLocalForce) { force = post.option.Force; } fragment.ApplyExplosion(post.transform, post.mesh.centroid, force, post.original, this.core.parameters); if ((double)this.Watch.ElapsedMilliseconds > (double)frameBudget) { return(false); } } } if (this.core.parameters.DestroyOriginalObject) { foreach (MeshObject post in this.core.postList) { if (Object.op_Implicit((Object)post.original) && !Object.op_Implicit((Object)post.original.GetComponent <Fragment>())) { Object.Destroy((Object)post.original); } if (Object.op_Implicit((Object)post.skinnedOriginal)) { Object.Destroy((Object)post.skinnedOriginal); } } } if (this.core.parameters.ExplodeSelf && !this.core.parameters.DestroyOriginalObject) { ExploderUtils.SetActiveRecursively(this.core.parameters.ExploderGameObject, false); } if (this.core.parameters.HideSelf) { ExploderUtils.SetActiveRecursively(this.core.parameters.ExploderGameObject, false); } this.Watch.Stop(); return(true); }
public override bool Run(float frameBudget) { var count = core.postList.Count; while (core.poolIdx < count) { var mesh = core.postList[core.poolIdx]; core.poolIdx++; var islandsFound = false; if (core.parameters.SplitMeshIslands || (mesh.option && mesh.option.SplitMeshIslands)) { var meshIslands = MeshUtils.IsolateMeshIslands(mesh.mesh); if (meshIslands != null) { islandsFound = true; foreach (var meshIsland in meshIslands) { islands.Add(new MeshObject { mesh = meshIsland, material = mesh.material, transform = mesh.transform, original = mesh.original, skinnedOriginal = mesh.skinnedOriginal, parent = mesh.transform.parent, position = mesh.transform.position, rotation = mesh.transform.rotation, localScale = mesh.transform.localScale, option = mesh.option, }); } } } if (!islandsFound) { islands.Add(mesh); } if (Watch.ElapsedMilliseconds > frameBudget) { return(false); } } #if DBG ExploderUtils.Log("Replacing fragments: " + postList.Count + " by islands: " + islands.Count); #endif // replace postList by island list core.postList = islands; Watch.Stop(); return(true); }