Ejemplo n.º 1
0
        // Add rigid component to transform list
        static void AddRigidComponent(RayfireRigid scr, List <Transform> tmList)
        {
            for (int i = 0; i < tmList.Count; i++)
            {
                // Turn off
                tmList[i].gameObject.SetActive(false);

                // Check if object already has Rigid script
                RayfireRigid newScr = tmList[i].gameObject.AddComponent <RayfireRigid>();
                newScr.initialization = RayfireRigid.InitType.AtStart;

                // Skip excluded                                    ????????????
                if (newScr.physics.exclude == true)
                {
                    continue;
                }

                // Collect fragment
                scr.fragments.Add(newScr);

                // Copy properties from parent to fragment node
                scr.CopyPropertiesTo(newScr);

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

                // Set to mesh
                newScr.objectType           = ObjectType.Mesh;
                newScr.physics.colliderType = RFColliderType.Mesh;

                // Set as cluster if has children with meshes TODO check for mesh filter
                if (newScr.transform.childCount > 0)
                {
                    newScr.objectType = ObjectType.NestedCluster;
                }

                // Set to dynamic if solo TODO fix
                else
                {
                    newScr.simulationType = SimType.Dynamic;
                }

                // Update depth level and amount
                newScr.limitations.currentDepth = scr.limitations.currentDepth + 1;

                // Turn on
                tmList[i].gameObject.SetActive(true);

                // IMPORTANT. Set mesh collider convex for gun impact detection
                if (newScr.objectType == ObjectType.Mesh)
                {
                    if (newScr.physics.meshCollider != null)
                    {
                        ((MeshCollider)newScr.physics.meshCollider).convex = true;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        // Create runtime clusters
        static void CreateClusterRuntime(RayfireRigid source, RFCluster cls)
        {
            // Cluster with solo shard. Add rigid component, reparent
            if (cls.shards.Count == 1)
            {
                AddRigidComponent(source, new List <Transform> (1)
                {
                    cls.shards[0].tm
                });
                cls.shards[0].tm.parent = RayfireMan.inst.transForm;
                return;
            }

            // Create root for left children
            GameObject leftRoot = new GameObject();

            // Turn off
            leftRoot.SetActive(false);

            leftRoot.name = source.gameObject.name + "_cls";
            leftRoot.transform.position = source.transForm.position;
            leftRoot.transform.rotation = source.transForm.rotation;
            leftRoot.transform.parent   = RayfireMan.inst.transForm;

            // Parent to main root
            for (int s = 0; s < cls.shards.Count; s++)
            {
                cls.shards[s].tm.parent = leftRoot.transform;
            }

            // Add rigid to object
            RayfireRigid target = leftRoot.gameObject.AddComponent <RayfireRigid>();

            target.initialization = RayfireRigid.InitType.AtStart;

            // Collect fragment
            source.fragments.Add(target);

            // Copy properties from parent to fragment node
            source.CopyPropertiesTo(target);

            // Copy particles
            RFParticles.CopyParticles(source, target);

            // Set to mesh
            target.objectType           = ObjectType.ConnectedCluster;
            target.physics.colliderType = RFColliderType.Mesh;

            // Set cluster
            target.clusterDemolition.cluster    = cls;
            target.clusterDemolition.cluster.id = 2;

            // Turn on
            leftRoot.SetActive(true);
        }
Ejemplo n.º 3
0
        // Create slices by mesh and pivots array
        public static List <RayfireRigid> CreateSlices(RayfireRigid scr)
        {
            // Fragments list
            List <RayfireRigid> scrArray = new List <RayfireRigid>();

            // Stop if has no any meshes
            if (scr.meshes == null)
            {
                return(scrArray);
            }

            // Create RayFire manager if not created
            RayfireMan.RayFireManInit();

            // Create root object and parent
            RFLimitations.CreateRoot(scr);

            // Vars
            int    baseLayer = scr.meshDemolition.GetLayer(scr);
            string baseTag   = scr.gameObject.tag;
            string baseName  = scr.gameObject.name + fragmentStr;

            // Get original mats
            Material[] mats = scr.skinnedMeshRend != null
                ? scr.skinnedMeshRend.sharedMaterials
                : scr.meshRenderer.sharedMaterials;

            // Create fragment objects
            for (int i = 0; i < scr.meshes.Length; ++i)
            {
                // Get object from pool or create
                RayfireRigid rfScr = RayfireMan.inst == null
                    ? RFPoolingFragment.CreateRigidInstance()
                    : RayfireMan.inst.fragments.GetPoolObject(RayfireMan.inst.transForm);

                // Setup
                rfScr.transform.position = scr.transForm.position + scr.pivots[i];
                rfScr.transform.parent   = scr.rootChild;
                rfScr.name                  = baseName + i;
                rfScr.gameObject.tag        = baseTag;
                rfScr.gameObject.layer      = baseLayer;
                rfScr.meshFilter.sharedMesh = scr.meshes[i];
                rfScr.rootParent            = scr.rootChild;

                // Copy properties from parent to fragment node
                scr.CopyPropertiesTo(rfScr);

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

                // Set collider
                RFPhysic.SetFragmentMeshCollider(rfScr, scr.meshes[i]);

                // Shadow casting
                if (RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > 0 &&
                    RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > scr.meshes[i].bounds.size.magnitude)
                {
                    rfScr.meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
                }

                // Turn on
                rfScr.gameObject.SetActive(true);

                // Set multymaterial
                RFSurface.SetMaterial(scr.subIds, mats, scr.materials, rfScr.meshRenderer, i, scr.meshes.Length);

                // Update depth level and amount
                rfScr.limitations.currentDepth = scr.limitations.currentDepth + 1;
                //rfScr.meshDemolition.amount = (int)(rfScr.meshDemolition.amount * rfScr.meshDemolition.depthFade);
                //if (rfScr.meshDemolition.amount < 2)
                //    rfScr.meshDemolition.amount = 2;

                // Add in array
                scrArray.Add(rfScr);
            }

            // Empty lists
            scr.DeleteCache();

            return(scrArray);
        }
Ejemplo n.º 4
0
        // Create fragments by mesh and pivots array
        public static List <RayfireRigid> CreateFragments(RayfireRigid scr)
        {
            // Fragments list
            List <RayfireRigid> scrArray = new List <RayfireRigid>();

            // Stop if has no any meshes
            if (scr.meshes == null)
            {
                return(scrArray);
            }

            // Create RayFire manager if not created
            RayfireMan.RayFireManInit();

            // Create root object and parent
            RFLimitations.CreateRoot(scr);

            // Vars
            int    baseLayer = scr.meshDemolition.GetLayer(scr);
            string baseTag   = scr.gameObject.tag;
            string baseName  = scr.gameObject.name + fragmentStr;

            // Save original rotation
            // Quaternion originalRotation = rootChild.transform.rotation;

            // Set rotation to precache rotation
            if (scr.demolitionType == DemolitionType.AwakePrecache)
            {
                scr.rootChild.transform.rotation = scr.cacheRotation;
            }

            // Get original mats
            Material[] mats = scr.skinnedMeshRend != null
                ? scr.skinnedMeshRend.sharedMaterials
                : scr.meshRenderer.sharedMaterials;

            // Create fragment objects
            for (int i = 0; i < scr.meshes.Length; ++i)
            {
                // Get object from pool or create
                RayfireRigid rfScr = RayfireMan.inst == null
                    ? RFPoolingFragment.CreateRigidInstance()
                    : RayfireMan.inst.fragments.GetPoolObject(RayfireMan.inst.transForm);

                // Setup
                rfScr.transform.position = scr.transForm.position + scr.pivots[i];
                rfScr.transform.parent   = scr.rootChild;
                rfScr.name                  = baseName + i;
                rfScr.gameObject.tag        = baseTag;
                rfScr.gameObject.layer      = baseLayer;
                rfScr.meshFilter.sharedMesh = scr.meshes[i];
                rfScr.rootParent            = scr.rootChild;

                // Copy properties from parent to fragment node
                scr.CopyPropertiesTo(rfScr);

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

                // Set collider
                RFPhysic.SetFragmentMeshCollider(rfScr, scr.meshes[i]);

                // Shadow casting
                if (RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > 0 &&
                    RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > scr.meshes[i].bounds.size.magnitude)
                {
                    rfScr.meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
                }

                // Turn on
                rfScr.gameObject.SetActive(true);

                // Set multymaterial
                RFSurface.SetMaterial(scr.subIds, mats, scr.materials, rfScr.meshRenderer, i, scr.meshes.Length);

                // Update depth level and amount
                rfScr.limitations.currentDepth = scr.limitations.currentDepth + 1;
                rfScr.meshDemolition.amount    = (int)(rfScr.meshDemolition.amount * rfScr.meshDemolition.depthFade);
                if (rfScr.meshDemolition.amount < 3)
                {
                    rfScr.meshDemolition.amount = 3;
                }

                // Add in array
                scrArray.Add(rfScr);

                // Debug.Log (rfScr.rootParent);
            }

            // Fix transform for precached fragments
            if (scr.demolitionType == DemolitionType.AwakePrecache)
            {
                scr.rootChild.rotation = scr.transForm.rotation;
            }

            // Fix runtime caching rotation difference. Get rotation difference and add to root
            if (scr.demolitionType == DemolitionType.Runtime && scr.meshDemolition.runtimeCaching.type != CachingType.Disable)
            {
                Quaternion cacheRotationDif = scr.transForm.rotation * Quaternion.Inverse(scr.meshDemolition.cacheRotationStart);
                scr.rootChild.rotation = cacheRotationDif * scr.rootChild.rotation;
            }

            return(scrArray);
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
        }