コード例 #1
0
        // Clusterize not connected groups
        void Clusterize()
        {
            for (int i = 0; i < cluster.childClusters.Count; i++)
            {
                // set demolishable state for child cluster
                cluster.demolishable = demolishable;

                // Set bound
                cluster.childClusters[i].bound = RFCluster.GetShardsBound(cluster.childClusters[i].shards);

                // Create cluster
                cluster.childClusters[i].shards[0].rigid.simulationType = SimType.Dynamic; // TODO IN BETTER WAY
                cluster.childClusters[i].shards[0].rigid.objectType     = ObjectType.ConnectedCluster;
                RFDemolitionCluster.CreateClusterRuntime(cluster.childClusters[i].shards[0].rigid, cluster.childClusters[i]);
                cluster.childClusters[i].shards[0].rigid.objectType = ObjectType.Mesh;

                // Copy preview
                cluster.childClusters[i].rigid.clusterDemolition.cn = showConnections;
                cluster.childClusters[i].rigid.clusterDemolition.nd = showNodes;

                // Destroy components
                for (int s = 0; s < cluster.childClusters[i].shards.Count; s++)
                {
                    Destroy(cluster.childClusters[i].shards[s].rigid.physics.rigidBody);
                    Destroy(cluster.childClusters[i].shards[s].rigid);
                }
            }
        }
コード例 #2
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);
        }
コード例 #3
0
        // Copy from
        public void CopyFrom(RFDemolitionCluster demolition)
        {
            meshDemolition = demolition.meshDemolition;
            connectivity   = demolition.connectivity;
            contactRadius  = demolition.contactRadius;

            Reset();
        }
コード例 #4
0
 // Slice object
 public void Slice()
 {
     if (objectType == ObjectType.Mesh || objectType == ObjectType.SkinnedMesh)
     {
         RFDemolitionMesh.SliceMesh(this);
     }
     else if (objectType == ObjectType.ConnectedCluster)
     {
         RFDemolitionCluster.SliceConnectedCluster(this);
     }
 }
コード例 #5
0
        // Demolish cluster
        IEnumerator DelayedClusterCor(RayfireRigid rigid, Collider coll)
        {
            // Wait life time
            yield return(new WaitForSeconds(delay));

            // Activate
            if (rigid != null && coll != null)
            {
                RFDemolitionCluster.DemolishConnectedCluster(rigid, new[] { coll });
            }
        }
コード例 #6
0
        void ClusterSetupUI()
        {
            GUILayout.BeginHorizontal();

            if (GUILayout.Button("Setup Cluster", GUILayout.Height(25)))
            {
                if (Application.isPlaying == false)
                {
                    foreach (var targ in targets)
                    {
                        if (targ as RayfireRigid != null)
                        {
                            RFPhysic.DestroyColliders(targ as RayfireRigid);
                            (targ as RayfireRigid).clusterDemolition.cluster       = new RFCluster();
                            (targ as RayfireRigid).clusterDemolition.clsCount      = 1;
                            (targ as RayfireRigid).clusterDemolition.minorClusters = null;

                            (targ as RayfireRigid).SetComponentsBasic();
                            (targ as RayfireRigid).SetParticleComponents();

                            if (RFDemolitionCluster.Clusterize(targ as RayfireRigid) == false)
                            {
                                Debug.Log("RayFire Rigid: " + (targ as RayfireRigid).name + " has no children with mesh.");
                            }
                            SetDirty(targ as RayfireRigid);
                        }
                    }
                }
            }

            if (GUILayout.Button("Reset Cluster", GUILayout.Height(25)))
            {
                if (Application.isPlaying == false)
                {
                    foreach (var targ in targets)
                    {
                        if (targ as RayfireRigid != null)
                        {
                            RFPhysic.DestroyColliders(targ as RayfireRigid);
                            (targ as RayfireRigid).clusterDemolition.cluster       = new RFCluster();
                            (targ as RayfireRigid).clusterDemolition.clsCount      = 1;
                            (targ as RayfireRigid).clusterDemolition.minorClusters = null;
                            SetDirty(targ as RayfireRigid);
                        }
                    }
                }
            }

            EditorGUILayout.EndHorizontal();
        }
コード例 #7
0
        /// /////////////////////////////////////////////////////////
        /// Activation
        /// /////////////////////////////////////////////////////////

        // Check for RayFire Rigid component activation
        void ActivationCheck(Collider coll)
        {
            // Get rigid from collider or rigid body
            RayfireRigid rigid = coll.attachedRigidbody == null
                ? coll.GetComponent <RayfireRigid>()
                : coll.attachedRigidbody.GetComponent <RayfireRigid>();

            // Has no rigid
            if (rigid == null)
            {
                return;
            }

            // Activation
            if (rigid.activation.byActivator == true)
            {
                if (rigid.simulationType == SimType.Inactive || rigid.simulationType == SimType.Kinematic)
                {
                    if (delay <= 0)
                    {
                        rigid.Activate();
                    }
                    else
                    {
                        StartCoroutine(DelayedActivationCor(rigid));
                    }
                }
            }

            // Connected cluster one fragment detach
            if (rigid.objectType == ObjectType.ConnectedCluster)
            {
                if (demolishCluster == true)
                {
                    if (delay <= 0)
                    {
                        RFDemolitionCluster.DemolishConnectedCluster(rigid, new[] { coll });
                    }
                    else
                    {
                        StartCoroutine(DelayedClusterCor(rigid, coll));
                    }
                }
            }
        }
コード例 #8
0
        // Clusterize
        void Clusterize()
        {
            // TODO skip if minor nested cluster
            if (objectType == ObjectType.NestedCluster)
            {
                if (clusterDemolition.cluster.id > 1)
                {
                    return;
                }
            }

            // Fail check
            if (RFDemolitionCluster.Clusterize(this) == true)
            {
                return;
            }

            // Fail
            physics.exclude = true;
            Debug.Log("RayFire Rigid: " + name + " has no children with mesh. Object Excluded from simulation.", gameObject);
        }
コード例 #9
0
        void ClusterSetupUI()
        {
            GUILayout.BeginHorizontal();

            if (GUILayout.Button("Setup Cluster", GUILayout.Height(25)))
            {
                if (Application.isPlaying == false)
                {
                    foreach (var targ in targets)
                    {
                        if (targ as RayfireRigid != null)
                        {
                            RFDemolitionCluster.SetupCluster(targ as RayfireRigid);
                            SetDirty(targ as RayfireRigid);
                        }
                    }
                }
            }

            if (GUILayout.Button("Reset Cluster", GUILayout.Height(25)))
            {
                if (Application.isPlaying == false)
                {
                    foreach (var targ in targets)
                    {
                        if (targ as RayfireRigid != null)
                        {
                            RFPhysic.DestroyColliders(targ as RayfireRigid);
                            (targ as RayfireRigid).clusterDemolition.cluster       = new RFCluster();
                            (targ as RayfireRigid).clusterDemolition.clsCount      = 1;
                            (targ as RayfireRigid).clusterDemolition.minorClusters = null;
                            SetDirty(targ as RayfireRigid);
                        }
                    }
                }
            }

            EditorGUILayout.EndHorizontal();
        }
コード例 #10
0
        // Define components
        void SetComponentsPhysics()
        {
            // Excluded from simulation
            if (physics.exclude == true)
            {
                return;
            }

            // Physics components
            physics.rigidBody    = GetComponent <Rigidbody>();
            physics.meshCollider = GetComponent <Collider>();

            // Mesh Set collider
            if (objectType == ObjectType.Mesh)
            {
                RFPhysic.SetMeshCollider(this);
            }

            // Cluster check TODO EXPOSE IN UI !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            if (objectType == ObjectType.NestedCluster || objectType == ObjectType.ConnectedCluster)
            {
                // No children mesh for clustering
                bool clusteringState = RFDemolitionCluster.Clusterize(this);
                if (clusteringState == false)
                {
                    physics.exclude = true;
                    Debug.Log("RayFire Rigid: " + name + " has no children with mesh. Object Excluded from simulation.", gameObject);
                    return;
                }
            }

            // Rigid body
            if (simulationType != SimType.Static && physics.rigidBody == null)
            {
                physics.rigidBody = gameObject.AddComponent <Rigidbody>();
                physics.rigidBody.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
            }
        }
コード例 #11
0
        // Demolish object
        public void Demolish()
        {
            // Profiler.BeginSample ("Demolition");
            // Debug.Log (limitations.demolitionShould);

            // Initialize if not
            if (initialized == false)
            {
                Initialize();
            }

            // Timestamp
            float t1 = Time.realtimeSinceStartup;

            // Restore position and rotation to prevent high collision offset
            transForm.position = physics.position;
            transForm.rotation = physics.rotation;

            // Demolish mesh or cluster to reference
            if (RFReferenceDemolition.DemolishReference(this) == false)
            {
                return;
            }

            // Demolish mesh and create fragments. Stop if runtime caching or no meshes/fragments were created
            if (RFDemolitionMesh.DemolishMesh(this) == false)
            {
                return;
            }

            /* EXPERIMENTAL
             * // TODO Clusterize
             * bool clusterize = true;
             * if (clusterize == true && objectType == ObjectType.Mesh && demolitionType == DemolitionType.Runtime)
             * {
             *
             *  foreach (var frag in fragments)
             *  {
             *      Destroy (frag.physics.rigidBody);
             *      Destroy (frag);
             *  }
             *
             *  RayfireRigid scr = this.rootChild.gameObject.AddComponent<RayfireRigid>();
             *  this.CopyPropertiesTo (scr);
             *  scr.demolitionType = DemolitionType.Runtime;
             *  scr.objectType     = ObjectType.ConnectedCluster;
             *
             *  scr.limitations.contactPoint   = this.limitations.contactPoint;
             *  scr.limitations.contactNormal  = this.limitations.contactNormal;
             *  scr.limitations.contactVector3 = this.limitations.contactVector3;
             *
             *  scr.physics.velocity = this.physics.velocity;
             *
             *  scr.clusterDemolition.cluster  = new RFCluster();
             *  scr.Initialize();
             *
             *  scr.physics.rigidBody.velocity   = this.physics.velocity;
             *  scr.limitations.demolitionShould = true;
             *  //scr.Demolish();
             *  RayfireMan.DestroyFragment (this, rootParent);
             *  return;
             * }
             */


            // Demolish cluster to children nodes
            if (RFDemolitionCluster.DemolishCluster(this) == true)
            {
                return;
            }

            // Check fragments and proceed TODO separate flow for connected cls demolition
            if (limitations.demolished == false)
            {
                limitations.demolitionShould = false;
                demolitionType = DemolitionType.None;
                return;
            }

            // Connectivity check
            activation.CheckConnectivity();

            // Fragments initialisation
            InitMeshFragments();

            // Sum total demolition time
            RayfireMan.inst.maxTimeThisFrame += Time.realtimeSinceStartup - t1;

            // Init particles
            RFParticles.InitDemolitionParticles(this);

            // Init sound
            RFSound.DemolitionSound(sound, limitations.bboxSize);

            // Event
            demolitionEvent.InvokeLocalEvent(this);
            RFDemolitionEvent.InvokeGlobalEvent(this);

            // Destroy demolished object
            RayfireMan.DestroyFragment(this, rootParent);

            // Timestamp
            // float t2 = Time.realtimeSinceStartup;
            // Debug.Log (t2 - t1);
            // Profiler.EndSample();
        }
コード例 #12
0
        // Demolish object
        public void Demolish()
        {
            // Profiler.BeginSample ("Demolition");
            // Debug.Log (limitations.demolitionShould);

            // Initialize if not
            if (initialized == false)
            {
                Initialize();
            }

            // Timestamp
            float t1 = Time.realtimeSinceStartup;

            // Restore position and rotation to prevent high collision offset
            transForm.position = physics.position;
            transForm.rotation = physics.rotation;

            // Demolish mesh or cluster to reference
            if (RFReferenceDemolition.DemolishReference(this) == false)
            {
                return;
            }

            // Demolish mesh and create fragments. Stop if runtime caching or no meshes/fragments were created
            if (RFDemolitionMesh.DemolishMesh(this) == false)
            {
                return;
            }

            // Demolish cluster to children nodes
            if (RFDemolitionCluster.DemolishCluster(this) == true)
            {
                return;
            }

            // Check fragments and proceed TODO separate flow for connected cls demolition
            if (limitations.demolished == false)
            {
                limitations.demolitionShould = false;
                demolitionType = DemolitionType.None;
                return;
            }

            // Connectivity check
            activation.CheckConnectivity();

            // Fragments initialisation
            InitMeshFragments();

            // Sum total demolition time
            RayfireMan.inst.maxTimeThisFrame += Time.realtimeSinceStartup - t1;

            // Init particles
            RFParticles.InitDemolitionParticles(this);

            // Event
            demolitionEvent.InvokeLocalEvent(this);
            RFDemolitionEvent.InvokeGlobalEvent(this);

            // Destroy demolished object
            RayfireMan.DestroyFragment(this, rootParent);

            // Timestamp
            // float t2 = Time.realtimeSinceStartup;
            // Debug.Log (t2 - t1);
            // Profiler.EndSample();
        }
コード例 #13
0
ファイル: RayfireGun.cs プロジェクト: Lime43/Shuriken-Ninja
        // Impact hit to rigid bodies. Activated inactive, detach clusters
        void ImpactHit(RayfireRigid rigid, RaycastHit hit, Vector3 impactPoint, Vector3 shootVector)
        {
            // Prepare impact list
            List <Rigidbody> impactRbList = new List <Rigidbody>();

            // Hit object Impact activation and detach before impact force
            if (radius == 0)
            {
                // Inactive Activation
                if (rigid.objectType == ObjectType.Mesh)
                {
                    if (rigid.simulationType == SimType.Inactive || rigid.simulationType == SimType.Kinematic)
                    {
                        if (rigid.activation.byImpact == true)
                        {
                            rigid.Activate();
                        }
                    }
                }

                // Connected cluster one fragment detach
                if (rigid.objectType == ObjectType.ConnectedCluster)
                {
                    if (demolishCluster == true)
                    {
                        RFDemolitionCluster.DemolishConnectedCluster(rigid, new[] { hit.collider });
                    }
                }

                // Collect for impact
                impactRbList.Add(hit.collider.attachedRigidbody);
            }

            // Group by radius Impact activation and detach before impact force
            if (radius > 0)
            {
                // Get all colliders
                impactColliders = null;
                impactColliders = Physics.OverlapSphere(impactPoint, radius, mask);

                // TODO tag filter
                if (tagFilter != untagged)
                {
                    //  && colliders[i].CompareTag (tagFilter) == false)
                }

                // No colliders. Stop
                if (impactColliders == null)
                {
                    return;
                }

                // Connected cluster group detach first, check for rigids in range next
                if (rigid.objectType == ObjectType.ConnectedCluster)
                {
                    if (demolishCluster == true)
                    {
                        RFDemolitionCluster.DemolishConnectedCluster(rigid, impactColliders);
                    }
                }

                // Collect all rigid bodies in range
                RayfireRigid        scr;
                List <RayfireRigid> impactRigidList = new List <RayfireRigid>();
                for (int i = 0; i < impactColliders.Length; i++)
                {
                    // Get rigid from collider or rigid body
                    scr = impactColliders[i].attachedRigidbody == null
                        ? impactColliders[i].GetComponent <RayfireRigid>()
                        : impactColliders[i].attachedRigidbody.transform.GetComponent <RayfireRigid>();

                    // Collect uniq rigids in radius
                    if (scr != null)
                    {
                        if (impactRigidList.Contains(scr) == false)
                        {
                            impactRigidList.Add(scr);
                        }
                    }
                    // Collect RigidBodies without rigid script
                    else
                    {
                        if (affectRigidBodies == true)
                        {
                            if (impactColliders[i].attachedRigidbody == null)
                            {
                                if (impactRbList.Contains(impactColliders[i].attachedRigidbody) == false)
                                {
                                    impactRbList.Add(impactColliders[i].attachedRigidbody);
                                }
                            }
                        }
                    }
                }

                // Group Activation first
                for (int i = 0; i < impactRigidList.Count; i++)
                {
                    if (impactRigidList[i].activation.byImpact == true)
                    {
                        if (impactRigidList[i].simulationType == SimType.Inactive || impactRigidList[i].simulationType == SimType.Kinematic)
                        {
                            impactRigidList[i].Activate();
                        }
                    }
                }

                // Collect rigid body from rigid components
                if (strength > 0)
                {
                    for (int i = 0; i < impactRigidList.Count; i++)
                    {
                        // Skip inactive objects
                        if (impactRigidList[i].simulationType == SimType.Inactive && affectInactive == false)
                        {
                            continue;
                        }

                        // Collect
                        impactRbList.Add(impactRigidList[i].physics.rigidBody);
                    }
                }
            }

            // NO Strength
            if (strength == 0)
            {
                return;
            }

            // No rigid bodies
            if (impactRbList.Count == 0)
            {
                return;
            }

            // Apply force
            for (int i = 0; i < impactRbList.Count; i++)
            {
                // Skip static and kinematik objects
                if (impactRbList[i] == null || impactRbList[i].isKinematic == true)
                {
                    continue;
                }

                // Add force
                impactRbList[i].AddForceAtPosition(shootVector * strength, impactPoint, ForceMode.VelocityChange);
            }
        }
コード例 #14
0
        // Demolish object to reference
        public static bool DemolishReference(RayfireRigid scr)
        {
            if (scr.demolitionType == DemolitionType.ReferenceDemolition)
            {
                // Get instance
                GameObject referenceGo = scr.referenceDemolition.GetReference();

                // Has reference
                if (referenceGo != null)
                {
                    // Instantiate turned off reference
                    bool refState = referenceGo.activeSelf;
                    referenceGo.SetActive(false);
                    GameObject fragRoot = scr.InstantiateGo(referenceGo);
                    referenceGo.SetActive(refState);
                    fragRoot.name = referenceGo.name;

                    // Set tm
                    scr.rootChild                  = fragRoot.transform;
                    scr.rootChild.position         = scr.transForm.position;
                    scr.rootChild.rotation         = scr.transForm.rotation;
                    scr.rootChild.transform.parent = RayfireMan.inst.transForm;

                    // Clear list for fragments
                    scr.fragments = new List <RayfireRigid>();

                    // Check root for rigid props
                    RayfireRigid rootScr = fragRoot.gameObject.GetComponent <RayfireRigid>();

                    // Reference Root has not rigid. Add to
                    if (rootScr == null && scr.referenceDemolition.addRigid == true)
                    {
                        // Add rigid and copy
                        rootScr = fragRoot.gameObject.AddComponent <RayfireRigid>();
                        rootScr.initialization = RayfireRigid.InitType.AtStart;

                        scr.CopyPropertiesTo(rootScr);

                        // Copy particles
                        RFParticles.CopyParticles(scr, rootScr);

                        // Single mesh TODO improve
                        if (fragRoot.transform.childCount == 0)
                        {
                            rootScr.objectType = ObjectType.Mesh;
                        }

                        // Multiple meshes
                        if (fragRoot.transform.childCount > 0)
                        {
                            rootScr.objectType = ObjectType.MeshRoot;
                        }
                    }

                    // Activate and init rigid
                    scr.rootChild.gameObject.SetActive(true);

                    // Reference has rigid
                    if (rootScr != null)
                    {
                        // Create rigid for root children
                        if (rootScr.objectType == ObjectType.MeshRoot)
                        {
                            for (int i = 0; i < rootScr.fragments.Count; i++)
                            {
                                rootScr.fragments[i].limitations.currentDepth++;
                            }
                            scr.fragments.AddRange(rootScr.fragments);
                            scr.DestroyRigid(rootScr);
                        }

                        // Get ref rigid
                        else if (rootScr.objectType == ObjectType.Mesh ||
                                 rootScr.objectType == ObjectType.SkinnedMesh)
                        {
                            rootScr.meshDemolition.runtimeCaching.type = CachingType.Disable;
                            RFDemolitionMesh.DemolishMesh(rootScr);

                            // TODO COPY MESH DATA FROM ROOTSCR TO THIS TO REUSE

                            scr.fragments.AddRange(rootScr.fragments);
                            RayfireMan.DestroyFragment(rootScr, rootScr.rootParent, 1f);
                        }

                        // Get ref rigid
                        else if (rootScr.objectType == ObjectType.NestedCluster ||
                                 rootScr.objectType == ObjectType.ConnectedCluster)
                        {
                            rootScr.Default();
                            rootScr.limitations.contactPoint = scr.limitations.contactPoint;
                            RFDemolitionCluster.DemolishCluster(rootScr);
                            rootScr.physics.exclude = true;
                            scr.fragments.AddRange(rootScr.fragments);
                            RayfireMan.DestroyFragment(rootScr, rootScr.rootParent, 1f);
                        }

                        // Has rigid by has No fragments. Stop demolition
                        if (scr.HasFragments == false)
                        {
                            scr.demolitionType = DemolitionType.None;
                            return(false);
                        }
                    }
                }

                // Has no rigid, has No fragments, but demolished
                scr.limitations.demolished = true;
            }

            return(true);
        }
コード例 #15
0
        // Demolish object to reference
        public static bool DemolishReference(RayfireRigid scr)
        {
            if (scr.demolitionType == DemolitionType.ReferenceDemolition)
            {
                // Demolished
                scr.limitations.demolished = true;

                // Turn off original
                scr.gameObject.SetActive(false);

                // Get instance
                GameObject refGo = scr.referenceDemolition.GetReference();

                // Has no reference
                if (refGo == null)
                {
                    return(true);
                }

                // Instantiate turned off reference with null parent
                GameObject instGo = Object.Instantiate(refGo, scr.transForm.position, scr.transForm.rotation);
                instGo.name = refGo.name;

                // Set root to manager or to the same parent
                if (RayfireMan.inst != null && RayfireMan.inst.advancedDemolitionProperties.parent == RFManDemolition.FragmentParentType.Manager)
                {
                    instGo.transform.parent = RayfireMan.inst.transform;
                }
                else
                {
                    instGo.transform.parent = scr.transForm.parent;
                }

                // Set tm
                scr.rootChild = instGo.transform;

                // Copy scale
                if (scr.referenceDemolition.inheritScale == true)
                {
                    scr.rootChild.localScale = scr.transForm.localScale;
                }

                // Clear list for fragments
                scr.fragments = new List <RayfireRigid>();

                // Check root for rigid props
                RayfireRigid refScr = instGo.gameObject.GetComponent <RayfireRigid>();

                // Reference Root has not rigid. Add to
                if (refScr == null && scr.referenceDemolition.addRigid == true)
                {
                    // Add rigid and copy
                    refScr = instGo.gameObject.AddComponent <RayfireRigid>();

                    // Copy rigid
                    scr.CopyPropertiesTo(refScr);

                    // Copy particles
                    RFParticles.CopyParticles(scr, refScr);

                    // Single mesh TODO improve
                    if (instGo.transform.childCount == 0)
                    {
                        refScr.objectType = ObjectType.Mesh;
                    }

                    // Multiple meshes
                    if (instGo.transform.childCount > 0)
                    {
                        refScr.objectType = ObjectType.MeshRoot;
                    }
                }

                // Activate and init rigid
                instGo.transform.gameObject.SetActive(true);

                // Reference has rigid
                if (refScr != null)
                {
                    // Init if not initialized yet
                    refScr.Initialize();

                    // Create rigid for root children
                    if (refScr.objectType == ObjectType.MeshRoot)
                    {
                        for (int i = 0; i < refScr.fragments.Count; i++)
                        {
                            refScr.fragments[i].limitations.currentDepth++;
                        }
                        scr.fragments.AddRange(refScr.fragments);
                        scr.DestroyRigid(refScr);
                    }

                    // Get ref rigid
                    else if (refScr.objectType == ObjectType.Mesh ||
                             refScr.objectType == ObjectType.SkinnedMesh)
                    {
                        refScr.meshDemolition.runtimeCaching.type = CachingType.Disable;
                        RFDemolitionMesh.DemolishMesh(refScr);

                        // TODO COPY MESH DATA FROM ROOTSCR TO THIS TO REUSE

                        scr.fragments.AddRange(refScr.fragments);


                        RayfireMan.DestroyFragment(refScr, refScr.rootParent, 1f);
                    }

                    // Get ref rigid
                    else if (refScr.objectType == ObjectType.NestedCluster ||
                             refScr.objectType == ObjectType.ConnectedCluster)
                    {
                        refScr.Default();

                        // Copy contact data
                        refScr.limitations.contactPoint   = scr.limitations.contactPoint;
                        refScr.limitations.contactVector3 = scr.limitations.contactVector3;
                        refScr.limitations.contactNormal  = scr.limitations.contactNormal;

                        // Demolish
                        RFDemolitionCluster.DemolishCluster(refScr);

                        // Collect new fragments
                        scr.fragments.AddRange(refScr.fragments);


                        //refScr.physics.exclude = true;
                        //RayfireMan.DestroyFragment (refScr, refScr.rootParent, 1f);
                    }
                }
            }

            return(true);
        }