Пример #1
0
        protected List <ExploderMesh> CutSingleMesh(MeshObject mesh)
        {
            Plane   plane = this.cuttingPlane.GetPlane(mesh.mesh, this.cutAttempt);
            bool    flag  = true;
            Color   crossSectionVertexColor = Color.get_white();
            Vector4 crossSectionUv;

            ((Vector4) ref crossSectionUv).\u002Ector(0.0f, 0.0f, 1f, 1f);
            if (Object.op_Implicit((Object)mesh.option))
            {
                flag = !mesh.option.Plane2D;
                crossSectionVertexColor     = mesh.option.CrossSectionVertexColor;
                crossSectionUv              = mesh.option.CrossSectionUV;
                this.core.splitMeshIslands |= mesh.option.SplitMeshIslands;
            }
            if (this.core.parameters.Use2DCollision)
            {
                flag = false;
            }
            bool triangulateHoles      = flag & !this.core.parameters.DisableTriangulation;
            List <ExploderMesh> meshes = (List <ExploderMesh>)null;
            double num = (double)this.cutter.Cut(mesh.mesh, mesh.transform, plane, triangulateHoles, this.core.parameters.DisableTriangulation, ref meshes, crossSectionVertexColor, crossSectionUv);

            if (meshes == null)
            {
                ++this.cutAttempt;
            }
            return(meshes);
        }
Пример #2
0
        protected List <ExploderMesh> CutSingleMesh(MeshObject mesh)
        {
            var plane = cuttingPlane.GetPlane(mesh.mesh, cutAttempt);

            var triangulateHoles         = true;
            var crossSectionVertexColour = Color.white;
            var crossSectionUV           = new Vector4(0, 0, 1, 1);

            if (mesh.option)
            {
                triangulateHoles         = !mesh.option.Plane2D;
                crossSectionVertexColour = mesh.option.CrossSectionVertexColor;
                crossSectionUV           = mesh.option.CrossSectionUV;
                core.splitMeshIslands   |= mesh.option.SplitMeshIslands;
            }

            if (core.parameters.Use2DCollision)
            {
                triangulateHoles = false;
            }

            triangulateHoles &= !core.parameters.DisableTriangulation;

            List <ExploderMesh> meshes = null;

            cutter.Cut(mesh.mesh, mesh.transform, plane, triangulateHoles, core.parameters.DisableTriangulation, ref meshes, crossSectionVertexColour, crossSectionUV);

            if (meshes == null)
            {
                cutAttempt++;
            }

            return(meshes);
        }
Пример #3
0
        protected List <ExploderMesh> CutSingleMesh(MeshObject mesh)
        {
            var randomPlaneNormal = new Vector3((float)random.NextDouble() * 2.0f - 1.0f,
                                                (float)random.NextDouble() * 2.0f - 1.0f,
                                                (float)random.NextDouble() * 2.0f - 1.0f);

            var plane = new Exploder.Plane(randomPlaneNormal, mesh.mesh.centroid);

            var triangulateHoles         = true;
            var crossSectionVertexColour = Color.white;
            var crossSectionUV           = new Vector4(0, 0, 1, 1);

            if (mesh.option)
            {
                triangulateHoles         = !mesh.option.Plane2D;
                crossSectionVertexColour = mesh.option.CrossSectionVertexColor;
                crossSectionUV           = mesh.option.CrossSectionUV;
                core.splitMeshIslands   |= mesh.option.SplitMeshIslands;
            }

            if (core.parameters.Use2DCollision)
            {
                triangulateHoles = false;
            }

            triangulateHoles &= !core.parameters.DisableTriangulation;

            List <ExploderMesh> meshes = null;

            cutter.Cut(mesh.mesh, mesh.transform, plane, triangulateHoles, core.parameters.DisableTriangulation, ref meshes, crossSectionVertexColour, crossSectionUV);

            return(meshes);
        }
Пример #4
0
        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);
        }
Пример #5
0
 public void AddMesh(MeshObject meshObject)
 {
     Debug.Assert(!running);
     meshSet.Add(meshObject);
 }
Пример #6
0
        protected override bool Cut(float frameBudget)
        {
            if (cutInitialized)
            {
                return(true);
            }

            localWatch.Start();

            cutInitialized = true;

            //
            // thread_max = <2, 4>
            //
            Debug.Assert(THREAD_MAX > 1, "At least one worker is required!");

            if (core.parameters.TargetFragments < 2 ||
                core.meshSet.Count == core.parameters.TargetFragments)
            {
                return(true);
            }

            //
            // cut object if necessary
            //
            var cuts = THREAD_MAX - 1 - core.meshSet.Count;

//            Debug.AssertFormat(cuts <= 2, "Invalid number of cuts: {0}", cuts);
//            var cutsTotal = cuts;

            if (cuts > core.parameters.TargetFragments - 1)
            {
                cuts = core.parameters.TargetFragments - 1;
            }

            var cycleCounter = 0;

            idCounter = core.targetFragments.Count + 1;

            while (cuts > 0)
            {
                newFragments.Clear();

                foreach (var mesh in core.meshSet)
                {
                    var meshes = CutSingleMesh(mesh);
                    cycleCounter++;

                    if (cycleCounter > core.parameters.TargetFragments)
                    {
                        ExploderUtils.Log("Explode Infinite loop!");
                        cuts = 0;
                        break;
                    }

                    if (meshes != null)
                    {
                        cuts--;

                        var ids = SplitMeshTargetFragments(mesh.id);
                        var ctr = 0;

                        foreach (var cutterMesh in meshes)
                        {
                            var fragment = new MeshObject
                            {
                                mesh = cutterMesh,

                                material        = mesh.material,
                                transform       = mesh.transform,
                                id              = mesh.id,
                                original        = mesh.original,
                                skinnedOriginal = mesh.skinnedOriginal,
                                bakeObject      = mesh.bakeObject,

                                parent     = mesh.transform.parent,
                                position   = mesh.transform.position,
                                rotation   = mesh.transform.rotation,
                                localScale = mesh.transform.localScale,

                                option = mesh.option,
                            };

                            fragment.id = ids[ctr++];
                            newFragments.Add(fragment);
                        }

                        meshToRemove.Add(mesh);
                        break;
                    }
                }

                core.meshSet.ExceptWith(meshToRemove);
                core.meshSet.UnionWith(newFragments);
            }

            if (core.meshSet.Count >= core.parameters.TargetFragments)
            {
                return(true);
            }

            //
            // assign meshes to workers
            //
            var meshPerThread = core.meshSet.Count / (THREAD_MAX - 1);
            var workerId      = 0;
            var meshCounter   = 0;

            foreach (var meshObject in core.meshSet)
            {
                workers[workerId].AddMesh(meshObject);
                meshCounter++;

                if (meshCounter >= meshPerThread && workerId < THREAD_MAX - 2)
                {
                    meshCounter = 0;
                    workerId++;
                }
            }

            core.meshSet.Clear();

            //
            // kick off workers
            //
            foreach (var worker in workers)
            {
                worker.Run();
            }

            localWatch.Stop();
//            Debug.Log("MeshesPerThread: " + meshPerThread + " workers: " + workers.Length + " cuts: " + cutsTotal + " time: " + localWatch.ElapsedMilliseconds);

            return(true);
        }
Пример #7
0
        private List <MeshObject> GetMeshList()
        {
            List <GameObject> gameObjectList;

            if (this.core.parameters.Targets != null)
            {
                gameObjectList = new List <GameObject>((IEnumerable <GameObject>) this.core.parameters.Targets);
            }
            else if (this.core.parameters.DontUseTag)
            {
                Object[] objectsOfType = Object.FindObjectsOfType(typeof(Explodable));
                gameObjectList = new List <GameObject>(objectsOfType.Length);
                foreach (Explodable explodable in objectsOfType)
                {
                    if (Object.op_Implicit((Object)explodable))
                    {
                        gameObjectList.Add(((Component)explodable).get_gameObject());
                    }
                }
            }
            else
            {
                gameObjectList = new List <GameObject>((IEnumerable <GameObject>)GameObject.FindGameObjectsWithTag(ExploderObject.Tag));
            }
            if (this.core.parameters.ExplodeSelf)
            {
                gameObjectList.Add(this.core.parameters.ExploderGameObject);
            }
            List <MeshObject> meshObjectList = new List <MeshObject>(gameObjectList.Count);
            int     num1      = 0;
            Vector3 vector3_1 = Vector3.get_zero();
            int     num2      = 0;

            using (List <GameObject> .Enumerator enumerator = gameObjectList.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    GameObject current = enumerator.Current;
                    if (Object.op_Implicit((Object)current) && (this.core.parameters.ExplodeSelf || !Object.op_Equality((Object)current, (Object)this.core.parameters.ExploderGameObject)) && (!Object.op_Inequality((Object)current, (Object)this.core.parameters.ExploderGameObject) || !this.core.parameters.ExplodeSelf || !this.core.parameters.DisableRadiusScan) && (this.core.parameters.Targets != null || this.IsInRadius(current)))
                    {
                        List <Preprocess.MeshData> meshData = this.GetMeshData(current);
                        int count = meshData.Count;
                        for (int index = 0; index < count; ++index)
                        {
                            Vector3 centroid = meshData[index].centroid;
                            if (this.core.parameters.Targets != null)
                            {
                                this.core.parameters.Position = centroid;
                                vector3_1 = Vector3.op_Addition(vector3_1, centroid);
                                ++num2;
                            }
                            Vector3 vector3_2 = Vector3.op_Subtraction(centroid, this.core.parameters.Position);
                            float   magnitude = ((Vector3) ref vector3_2).get_magnitude();
                            meshObjectList.Add(new MeshObject()
                            {
                                id              = num1++,
                                mesh            = new ExploderMesh(meshData[index].sharedMesh),
                                material        = meshData[index].sharedMaterial,
                                transform       = new ExploderTransform(meshData[index].gameObject.get_transform()),
                                parent          = meshData[index].gameObject.get_transform().get_parent(),
                                position        = meshData[index].gameObject.get_transform().get_position(),
                                rotation        = meshData[index].gameObject.get_transform().get_rotation(),
                                localScale      = meshData[index].gameObject.get_transform().get_localScale(),
                                bakeObject      = meshData[index].gameObject,
                                distanceRatio   = this.GetDistanceRatio(magnitude, this.core.parameters.Radius),
                                original        = meshData[index].parentObject,
                                skinnedOriginal = meshData[index].skinnedBakeOriginal,
                                option          = (ExploderOption)current.GetComponent <ExploderOption>()
                            });
                        }
                    }
                }
            }
            if (num2 > 0)
            {
                this.core.parameters.Position = Vector3.op_Division(vector3_1, (float)num2);
            }
            if (meshObjectList.Count == 0)
            {
                return(meshObjectList);
            }
            if (this.core.parameters.UniformFragmentDistribution || this.core.parameters.Targets != null)
            {
                int num3             = this.core.parameters.TargetFragments / meshObjectList.Count;
                int targetFragments1 = this.core.parameters.TargetFragments;
                foreach (MeshObject meshObject in meshObjectList)
                {
                    this.core.targetFragments[meshObject.id] = num3;
                    targetFragments1 -= num3;
                }
                while (targetFragments1 > 0)
                {
                    --targetFragments1;
                    MeshObject            meshObject = meshObjectList[Random.Range(0, meshObjectList.Count - 1)];
                    Dictionary <int, int> targetFragments2;
                    int id;
                    (targetFragments2 = this.core.targetFragments)[id = meshObject.id] = targetFragments2[id] + 1;
                }
            }
            else
            {
                float num3 = 0.0f;
                int   num4 = 0;
                foreach (MeshObject meshObject in meshObjectList)
                {
                    num3 += meshObject.distanceRatio;
                }
                foreach (MeshObject meshObject in meshObjectList)
                {
                    this.core.targetFragments[meshObject.id] = (int)((double)meshObject.distanceRatio / (double)num3 * (double)this.core.parameters.TargetFragments);
                    num4 += this.core.targetFragments[meshObject.id];
                }
                if (num4 < this.core.parameters.TargetFragments)
                {
                    int num5 = this.core.parameters.TargetFragments - num4;
                    while (num5 > 0)
                    {
                        foreach (MeshObject meshObject in meshObjectList)
                        {
                            Dictionary <int, int> targetFragments;
                            int id;
                            (targetFragments = this.core.targetFragments)[id = meshObject.id] = targetFragments[id] + 1;
                            --num5;
                            if (num5 == 0)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            return(meshObjectList);
        }
        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);
        }
Пример #9
0
        protected override bool Cut(float frameBudget)
        {
            if (this.cutInitialized)
            {
                return(true);
            }
            this.localWatch.Start();
            this.cutInitialized = true;
            if (this.core.parameters.TargetFragments < 2 || this.core.meshSet.Count == this.core.parameters.TargetFragments)
            {
                return(true);
            }
            int num1 = this.THREAD_MAX - 1 - this.core.meshSet.Count;

            if (num1 > this.core.parameters.TargetFragments - 1)
            {
                num1 = this.core.parameters.TargetFragments - 1;
            }
            int num2 = 0;

            while (num1 > 0)
            {
                this.newFragments.Clear();
                foreach (MeshObject mesh in this.core.meshSet)
                {
                    List <ExploderMesh> exploderMeshList = this.CutSingleMesh(mesh);
                    ++num2;
                    if (num2 > this.core.parameters.TargetFragments)
                    {
                        num1 = 0;
                        break;
                    }
                    if (exploderMeshList != null)
                    {
                        --num1;
                        int[] numArray = this.SplitMeshTargetFragments(mesh.id);
                        int   num3     = 0;
                        foreach (ExploderMesh exploderMesh in exploderMeshList)
                        {
                            MeshObject meshObject = new MeshObject()
                            {
                                mesh            = exploderMesh,
                                material        = mesh.material,
                                transform       = mesh.transform,
                                id              = mesh.id,
                                original        = mesh.original,
                                skinnedOriginal = mesh.skinnedOriginal,
                                bakeObject      = mesh.bakeObject,
                                parent          = mesh.transform.parent,
                                position        = mesh.transform.position,
                                rotation        = mesh.transform.rotation,
                                localScale      = mesh.transform.localScale,
                                option          = mesh.option
                            };
                            meshObject.id = numArray[num3++];
                            this.newFragments.Add(meshObject);
                        }
                        this.meshToRemove.Add(mesh);
                        break;
                    }
                }
                this.core.meshSet.ExceptWith((IEnumerable <MeshObject>) this.meshToRemove);
                this.core.meshSet.UnionWith((IEnumerable <MeshObject>) this.newFragments);
            }
            if (this.core.meshSet.Count >= this.core.parameters.TargetFragments)
            {
                return(true);
            }
            int num4  = this.core.meshSet.Count / (this.THREAD_MAX - 1);
            int index = 0;
            int num5  = 0;

            foreach (MeshObject mesh in this.core.meshSet)
            {
                this.workers[index].AddMesh(mesh);
                ++num5;
                if (num5 >= num4 && index < this.THREAD_MAX - 2)
                {
                    num5 = 0;
                    ++index;
                }
            }
            this.core.meshSet.Clear();
            foreach (CutterWorker worker in this.workers)
            {
                worker.Run();
            }
            this.localWatch.Stop();
            return(true);
        }
Пример #10
0
 public void AddMesh(MeshObject meshObject)
 {
     this.meshSet.Add(meshObject);
 }