Example #1
0
        static void DrawGizmosSelected(RayfireShatter shatter, GizmoType gizmoType)
        {
            // Color preview
            if (shatter.colorPreview == true)
            {
                ColorPreview(shatter);
            }

            // Custom point cloud preview
            if (shatter.type == FragType.Custom)
            {
                if (shatter.custom.enable == true)
                {
                    Gizmos.color = Color.green;

                    // Get bounds for preview
                    Bounds bound = shatter.GetBound();
                    if (bound.size.magnitude > 0)
                    {
                        List <Vector3> pointCloud = RFFragment.GetCustomPointCLoud(shatter.custom, shatter.transform, shatter.advanced.seed, bound);
                        if (pointCloud.Count > 0)
                        {
                            for (int i = 0; i < pointCloud.Count; i++)
                            {
                                Gizmos.DrawSphere(pointCloud[i], shatter.custom.size);
                            }
                        }
                    }
                }
            }
        }
        // Instant caching into meshes
        public static void CacheInstant(RayfireRigid scr)
        {
            // Timestamp
            float t1 = Time.realtimeSinceStartup;

            // Input mesh, setup
            if (RFFragment.InputMesh(scr) == false)
            {
                return;
            }

            // Timestamp
            float t2 = Time.realtimeSinceStartup;

            //Debug.Log (scr.gameObject.name +  " Input time: " + (t2 - t1));

            // Create fragments
            RFFragment.CacheMeshesInst(ref scr.meshes, ref scr.pivots, ref scr.subIds, scr);

            // Timestamp
            float t3 = Time.realtimeSinceStartup;

            //Debug.Log (t2 - t1);
            //Debug.Log (scr.gameObject.name +  " Cache time: " + (t3 - t1));
        }
Example #3
0
        /// /////////////////////////////////////////////////////////
        /// Methods
        /// /////////////////////////////////////////////////////////

        // Fragment this object by shatter properties
        public void Fragment()
        {
            // Cache variables
            if (DefineComponents() == false)
            {
                return;
            }

            // Cache default vars
            SetVariables();

            // Check if object is too small
            ScaleCheck();

            // Cache
            RFFragment.CacheMeshes(ref meshes, ref pivots, ref origSubMeshIdsRF, this);

            // Stop
            if (meshes == null)
            {
                return;
            }

            // Create fragments
            fragmentsLast = CreateFragments();

            // Collect to all fragments
            fragmentsAll.AddRange(fragmentsLast);

            // Reset original object back if it was scaled
            transForm.localScale = originalScale;
        }
Example #4
0
        // Instant caching into meshes
        public static void CacheInstant(RayfireRigid scr)
        {
            // Input mesh, setup
            if (RFFragment.InputMesh(scr) == false)
            {
                return;
            }

            // Create fragments
            RFFragment.CacheMeshesInst(ref scr.meshes, ref scr.pivots, ref scr.subIds, scr);
        }
Example #5
0
        /// /////////////////////////////////////////////////////////
        /// Methods
        /// /////////////////////////////////////////////////////////

        // Fragment this object by shatter properties
        public void Fragment(int fragmentMode = 0)
        {
            // Cache variables
            if (DefineComponents() == false)
            {
                return;
            }

            // Cache default vars
            SetVariables();

            // Check if object is too small
            ScaleCheck();

            // Cache
            RFFragment.CacheMeshes(ref meshes, ref pivots, ref origSubMeshIdsRF, this);

            // Stop
            if (meshes == null)
            {
                return;
            }

            // Create fragments
            if (fragmentMode == 1)
            {
                if (rootChildList[rootChildList.Count - 1] != null)
                {
                    fragmentsLast = CreateFragments(rootChildList[rootChildList.Count - 1].gameObject);
                }
                else
                {
                    fragmentMode = 0;
                }
            }
            if (fragmentMode == 0)
            {
                fragmentsLast = CreateFragments();
            }

            // Vertex limitation
            VertexLimitation();

            // Collect to all fragments
            fragmentsAll.AddRange(fragmentsLast);

            // Reset original object back if it was scaled
            transForm.localScale = originalScale;
        }
Example #6
0
        /// /////////////////////////////////////////////////////////
        /// Demolition types
        /// /////////////////////////////////////////////////////////

        // Awake Mesh input // TODO add checks in case has input mesh but mesh input is off
        public void MeshInput()
        {
            if (objectType == ObjectType.Mesh)
            {
                // Set components for mesh / skinned mesh / clusters
                SetComponentsBasic();

                // Timestamp
                //float t1 = Time.realtimeSinceStartup;

                // Input
                RFFragment.InputMesh(this);

                // Timestamp
                //float t2 = Time.realtimeSinceStartup;

                //Debug.Log (gameObject.name +  " Input time: " + (t2 - t1));
            }
        }
Example #7
0
        // SLice mesh
        public static void SliceMesh(RayfireRigid scr)
        {
            // Empty lists
            scr.DeleteCache();
            scr.DeleteFragments();

            // SLice
            RFFragment.SliceMeshes(ref scr.meshes, ref scr.pivots, ref scr.subIds, scr, scr.limitations.slicePlanes);

            // Remove plane info
            scr.limitations.slicePlanes.Clear();

            // Stop
            if (scr.HasMeshes == false)
            {
                return;
            }

            // Get fragments
            scr.fragments = RFDemolitionMesh.CreateSlices(scr);

            // TODO check for fragments

            // Set demolition
            scr.limitations.demolished = true;

            // Fragments initialisation
            scr.InitMeshFragments();

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

            // Destroy original
            RayfireMan.DestroyFragment(scr, scr.rootParent);
        }
Example #8
0
        // Slice object
        public void SliceObjectByPlanes()
        {
            // Empty lists
            DeleteCache();
            DeleteFragments();

            // SLice
            RFFragment.SliceMeshes(ref meshes, ref pivots, ref subIds, this, limitations.slicePlanes);

            // Remove plane info
            limitations.slicePlanes.Clear();

            // Stop
            if (HasMeshes == false)
            {
                return;
            }

            // Get fragments
            fragments = CreateSlices();

            // TODO check for fragments

            // Set demolition
            limitations.demolished = true;

            // Fragments initialisation
            InitFragments();

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

            // Destroy original
            RayfireMan.DestroyFragment(this, rootParent);
        }
Example #9
0
        // Cor to fragment mesh over several frames
        public IEnumerator RuntimeCachingCor(RayfireRigid scr)
        {
            // Object should be demolished when cached all meshes but not during caching
            bool demolitionShouldLocal = scr.limitations.demolitionShould == true;

            scr.limitations.demolitionShould = false;

            // Input mesh, setup, record time
            float t1 = Time.realtimeSinceStartup;

            if (RFFragment.InputMesh(scr) == false)
            {
                yield break;
            }

            // Set list with amount of mesh for every frame
            List <int> batchAmount = runtimeCaching.type == CachingType.ByFrames
                ? RFRuntimeCaching.GetBatchByFrames(runtimeCaching.frames, totalAmount)
                : RFRuntimeCaching.GetBatchByFragments(runtimeCaching.fragments, totalAmount);

            // Caching in progress
            runtimeCaching.inProgress = true;

            // Wait next frame if input took too much time or long batch
            float t2 = Time.realtimeSinceStartup - t1;

            if (t2 > 0.025f || batchAmount.Count > 5)
            {
                yield return(null);
            }

            // Save tm for multi frame caching
            GameObject tmRefGo = RFRuntimeCaching.CreateTmRef(scr);

            // Start rotation
            cacheRotationStart = scr.transForm.rotation;

            // Iterate every frame. Calc local frame meshes
            List <Mesh>         meshesList = new List <Mesh>();
            List <Vector3>      pivotsList = new List <Vector3>();
            List <RFDictionary> subList    = new List <RFDictionary>();

            for (int i = 0; i < batchAmount.Count; i++)
            {
                // Check for stop
                if (runtimeCaching.stop == true)
                {
                    ResetRuntimeCaching(scr, tmRefGo);
                    yield break;
                }

                // Cache defined points
                RFFragment.CacheMeshesMult(tmRefGo.transform, ref meshesList, ref pivotsList, ref subList, scr, batchAmount, i);
                // TODO create fragments for current batch
                // TODO record time and decrease batches amount if less 30 fps
                yield return(null);
            }

            // Set to main data vars
            scr.meshes = meshesList.ToArray();
            scr.pivots = pivotsList.ToArray();
            scr.subIds = subList;

            // Clear
            scr.DestroyObject(tmRefGo);
            scr.meshDemolition.scrShatter = null;

            // Set demolition ready state
            if (runtimeCaching.skipFirstDemolition == false && demolitionShouldLocal == true)
            {
                scr.limitations.demolitionShould = true;
            }

            // Reset damage
            if (runtimeCaching.skipFirstDemolition == true && demolitionShouldLocal == true)
            {
                scr.damage.Reset();
            }

            // Caching finished
            runtimeCaching.inProgress = false;
            runtimeCaching.wasUsed    = true;
        }
Example #10
0
        // Create fragments by mesh and pivots array
        private List <GameObject> CreateFragments(GameObject lastRoot = null)
        {
            // No mesh were cached
            if (meshes == null)
            {
                return(null);
            }

            // Clear array for new fragments
            GameObject[] fragArray = new GameObject[meshes.Length];

            // Vars
            string goName   = gameObject.name;
            string baseName = goName + "_sh_";

            // Create root object
            GameObject root = lastRoot;

            if (lastRoot == null)
            {
                root = new GameObject(goName + "_root");
                root.transform.position = transForm.position;
                root.transform.rotation = transForm.rotation;
                root.transform.parent   = transForm.parent;
                rootChildList.Add(root.transform);
            }

            // KEVINJ: when operating on project assets, causes the new root object to be in the scene rather than a child of the prefab
            // Use https://docs.unity3d.com/ScriptReference/PrefabUtility.LoadPrefabContents.html in order to be able to set the parent
            // PrefabMode prefabMode = GetPrefabMode(gameObject);
            // if ( prefabMode != PrefabMode.Scene)
            // {
            //  // PREFAB, AVOID CREATING INTO SCENE
            //  root.transform.parent = transForm;
            // }
            // else
            // {
            //  // ORIGINAL BEHAVIOR
            //  root.transform.parent = transForm.parent;
            // }

            // Create instance for fragments
            GameObject fragInstance;

            if (advanced.copyComponents == true)
            {
                fragInstance = Instantiate(gameObject);
                fragInstance.transform.rotation   = Quaternion.identity;
                fragInstance.transform.localScale = Vector3.one;

                // Destroy shatter
                DestroyImmediate(fragInstance.GetComponent <RayfireShatter>());
            }
            else
            {
                fragInstance = new GameObject();
                fragInstance.AddComponent <MeshFilter>();
                fragInstance.AddComponent <MeshRenderer>();
            }

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

            // Create fragment objects
            for (int i = 0; i < meshes.Length; ++i)
            {
                // Rescale mesh
                if (rescaleFix != 1f)
                {
                    RFFragment.RescaleMesh(meshes[i], rescaleFix);
                }

                // Instantiate. IMPORTANT do not parent when Instantiate
                GameObject fragGo = Instantiate(fragInstance);
                fragGo.transform.localScale = Vector3.one;

                // Set multymaterial
                MeshRenderer targetRend = fragGo.GetComponent <MeshRenderer>();
                RFSurface.SetMaterial(origSubMeshIdsRF, mats, material, targetRend, i, meshes.Length);

                // Set fragment object name and tm
                fragGo.name = baseName + (i + 1);
                fragGo.transform.position = root.transform.position + (pivots[i] / rescaleFix);
                fragGo.transform.parent   = root.transform;

                // Set fragment mesh
                MeshFilter mf = fragGo.GetComponent <MeshFilter>();


                /*// KevinJ:
                 #if UNITY_EDITOR
                 * // Up to the caller to use AssetDatabase.RemoveObjectFromAsset to remove meshes from any prior calls to CreateFragments()
                 * if (prefabMode == PrefabMode.Asset)
                 * {
                 *      AssetDatabase.AddObjectToAsset(meshes[i], gameObject.scene.path);
                 * }
                 * else if (prefabMode == PrefabMode.PrefabEditingMode)
                 * {
                 *      //string assetPath = UnityEditor.Experimental.GetPrefabStage(gameObject).prefabAssetPath;
                 *      //AssetDatabase.AddObjectToAsset(meshes[i], assetPath);
                 * }
                 #endif*/


                mf.sharedMesh      = meshes[i];
                mf.sharedMesh.name = fragGo.name;

                // Set mesh collider
                MeshCollider mc = fragGo.GetComponent <MeshCollider>();
                if (mc != null)
                {
                    mc.sharedMesh = meshes[i];
                }

                // Add in array
                fragArray[i] = fragGo;
            }

            // Destroy instance
            DestroyImmediate(fragInstance);

            // Empty lists
            meshes           = null;
            pivots           = null;
            origSubMeshIdsRF = new List <RFDictionary>();

            return(fragArray.ToList());
        }
Example #11
0
        /// /////////////////////////////////////////////////////////
        /// Methods
        /// /////////////////////////////////////////////////////////

        // Fragment this object by shatter properties
        public void Fragment(int fragmentMode = 0)
        {
            // Cache variables
            if (DefineComponents() == false)
            {
                return;
            }

            // Cache default vars
            SetVariables();

            // Check if object is too small
            ScaleCheck();

            // Cache
            RFFragment.CacheMeshes(ref meshes, ref pivots, ref origSubMeshIdsRF, this);

            // Stop
            if (meshes == null)
            {
                return;
            }

            // Create fragments
            if (fragmentMode == 1)
            {
                if (rootChildList[rootChildList.Count - 1] != null)
                {
                    fragmentsLast = CreateFragments(rootChildList[rootChildList.Count - 1].gameObject);
                }
                else
                {
                    fragmentMode = 0;
                }
            }
            if (fragmentMode == 0)
            {
                fragmentsLast = CreateFragments();
            }

            // Vertex limitation
            if (advanced.vertexLimitation == true)
            {
                for (int i = fragmentsLast.Count - 1; i >= 0; i--)
                {
                    MeshFilter mf = fragmentsLast[i].GetComponent <MeshFilter>();
                    if (mf.sharedMesh.vertexCount > advanced.vertexAmount)
                    {
                        RayfireShatter shat = fragmentsLast[i].AddComponent <RayfireShatter>();
                        shat.voronoi.amount = 4;

                        shat.Fragment();
                        Debug.Log(shat.name);

                        if (shat.fragmentsLast.Count > 0)
                        {
                            fragmentsLast.AddRange(shat.fragmentsLast);
                            DestroyImmediate(shat.gameObject);
                            fragmentsLast.RemoveAt(i);
                        }
                    }
                }
            }

            // Collect to all fragments
            fragmentsAll.AddRange(fragmentsLast);

            // Reset original object back if it was scaled
            transForm.localScale = originalScale;
        }