예제 #1
0
        // Init collapse after connection loss
        static void CollapseCluster(RayfireRigid scr)
        {
            // Collect solo shards, remove from cluster, no need to reinit
            List <RFShard> detachShards = new List <RFShard>();

            RFCluster.GetSoloShards(scr.clusterDemolition.cluster, detachShards);

            // Clear fragments in case of previous demolition
            if (scr.HasFragments == true)
            {
                scr.fragments.Clear();
            }

            // Dynamic cluster connectivity check, all clusters are equal, pick biggest to keep as original
            if (scr.simulationType == SimType.Dynamic || scr.simulationType == SimType.Sleeping)
            {
                // Check left cluster shards for connectivity and collect not connected child clusters. Should be before ClusterizeDetachShards
                RFCluster.ConnectivityCheck(scr.clusterDemolition.cluster);

                // Cluster is not connected. Set biggest child cluster shards to original cluster. Cant be 1 child cluster here
                RFCluster.ReduceChildClusters(scr.clusterDemolition.cluster);
            }

            // Kinematik/ Inactive cluster, Connectivity check if cluster has uny shards. Main cluster keeps all not activated
            else if (scr.simulationType == SimType.Kinematic || scr.simulationType == SimType.Inactive)
            {
                RFCluster.ConnectivityUnyCheck(scr.clusterDemolition.cluster);
            }

            // Init final cluster ops
            RFDemolitionCluster.PostDemolitionCluster(scr, detachShards);
        }
예제 #2
0
        // Check for connectivity
        public void CheckConnectivity()
        {
            // Do once
            checkNeed = false;

            // Clear all activated/demolished shards
            CleanUpActivatedShards(cluster);

            // No shards to check
            if (cluster.shards.Count == 0)
            {
                return;
            }

            // Reinit neibs after cleaning
            RFShard.ReinitNeibs(cluster.shards);

            // List of shards to be activated
            List <RFShard> soloShards = new List <RFShard>();

            // TODO do not collect solo uny shards
            // Check for solo shards and collect
            RFCluster.GetSoloShards(cluster, soloShards);

            // Reinit neibs before connectivity check
            RFShard.ReinitNeibs(cluster.shards);

            // Connectivity check
            RFCluster.ConnectivityCheck(cluster);

            // Get not connected and not unyielding child cluster
            CheckUnyielding(cluster);

            // TODO ONE NEIB DETACH FOR CHILD CLUSTERS

            // Activate not connected shards.
            if (soloShards.Count > 0)
            {
                for (int i = 0; i < soloShards.Count; i++)
                {
                    soloShards[i].rigid.Activate();
                }
            }

            // Clusterize childClusters  or activate their shards
            if (cluster.HasChildClusters == true)
            {
                if (clusterize == true)
                {
                    Clusterize();
                }
                else
                {
                    for (int c = 0; c < cluster.childClusters.Count; c++)
                    {
                        for (int s = 0; s < cluster.childClusters[c].shards.Count; s++)
                        {
                            cluster.childClusters[c].shards[s].rigid.Activate();
                        }
                    }
                }
            }

            // Stop checking. Everything activated
            if (cluster.shards.Count == 0)
            {
                checkConnectivity = false;
            }
        }
예제 #3
0
        // Demolish connected cluster
        static void DemolishClusterConnected(RayfireRigid scr)
        {
            // TODO If demolition.chunkRadius == 100. Detach all.
            // TODO Infinite demolition to detached frags.

            // Get detach radius distance
            float detachRadius = scr.limitations.bboxSize / 100f * scr.clusterDemolition.contactRadius;

            // Damage radius. TODO reset it.
            if (scr.clusterDemolition.damageRadius > 0)
            {
                detachRadius = scr.clusterDemolition.damageRadius;
            }

            // Detached solo fragments
            List <RFShard> detachShards = new List <RFShard>();

            // Get all colliders TODO input mask by gameobject
            List <Collider> detachColliders = Physics.OverlapSphere(scr.limitations.contactPoint, detachRadius).ToList();

            // No colliders to detach
            if (detachColliders.Count == 0)
            {
                return;
            }

            // Detach contacted fragments to solo. IMPROVE force spread by shards connection info. Connectivity check
            for (int i = scr.physics.clusterColliders.Count - 1; i >= 0; i--)
            {
                if (detachColliders.Contains(scr.physics.clusterColliders[i]))
                {
                    // Detach shard ans im them solo
                    detachShards.Add(scr.clusterDemolition.cluster.shards[i]);
                    scr.clusterDemolition.cluster.shards.RemoveAt(i);

                    // Destroy colliders to keep original cluster in scene
                    scr.DestroyCollider(scr.physics.clusterColliders[i]);
                    scr.physics.clusterColliders.RemoveAt(i);
                }
            }

            // No detach shards
            if (detachShards.Count == 0)
            {
                return;
            }

            // Prepare
            scr.fragments = new List <RayfireRigid>();

            // Create parent for all fragments.
            GameObject root = new GameObject(scr.gameObject.name + "_root");

            root.transform.parent  = RayfireMan.inst.transForm;
            scr.rootChild          = root.transform;
            scr.rootChild.position = scr.transForm.position;
            scr.rootChild.rotation = scr.transForm.rotation;

            // Get tm list for detached shards
            List <Transform> detachChildren = detachShards.Select(t => t.tm).ToList();

            // Add rigid component to detached children
            AddRigidComponent(scr, detachChildren);

            // Parent to main root
            for (int i = 0; i < detachChildren.Count; i++)
            {
                detachChildren[i].parent = root.transform;
            }

            // All shards were detached. Set demolished state
            if (scr.clusterDemolition.cluster.shards.Count == 0)
            {
                scr.limitations.demolished = true;
                return;
            }

            // Check cluster for connectivity and return list of not connected clusters
            scr.clusterDemolition.cluster.childClusters = RFCluster.ConnectivityCheck(scr.clusterDemolition.cluster.shards);

            // CLuster is demolished
            scr.limitations.demolished = true;

            // Main cluster connected. Create new cluster based on left shards. IMPORTANT. attempt to use old cluster with old RB cause sim instability
            if (scr.clusterDemolition.cluster.childClusters.Count == 0)
            {
                CreateClusterRuntime(scr, scr.clusterDemolition.cluster);
            }

            // Main cluster not connected. Create connected cluster for every cluster in list
            else
            {
                foreach (RFCluster cls in scr.clusterDemolition.cluster.childClusters)
                {
                    CreateClusterRuntime(scr, cls);
                }
            }

            // Turn off demolition for solo fragments
            if (scr.clusterDemolition.meshDemolition == false)
            {
                foreach (var frag in scr.fragments)
                {
                    if (frag.objectType == ObjectType.Mesh)
                    {
                        frag.demolitionType = DemolitionType.None;
                    }
                }
            }
        }