// Fragments initialisation public void InitMeshFragments() { // No fragments if (HasFragments == false) { return; } // Set velocity RFPhysic.SetFragmentsVelocity(this); // Sum total new fragments amount RayfireMan.inst.advancedDemolitionProperties.currentAmount += fragments.Count; // Set ancestor and descendants if (reset.mesh == RFReset.MeshResetType.ReuseInputMesh) { RFLimitations.SetAncestor(this); RFLimitations.SetDescendants(this); } // Fading. move to fragment if (fading.onDemolition == true) { fading.DemolitionFade(fragments); } }
// 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 if (objectType == ObjectType.NestedCluster || objectType == ObjectType.ConnectedCluster) { Clusterize(); } // Rigid body if (simulationType != SimType.Static && physics.rigidBody == null) { physics.rigidBody = gameObject.AddComponent <Rigidbody>(); physics.rigidBody.collisionDetectionMode = RayfireMan.inst.collisionDetection; } }
// Set physics properties void SetPhysics() { // Excluded from sim if (physics.exclude == true) { return; } // MeshCollider physic material preset. Set new or take from parent RFPhysic.SetColliderMaterial(this); // Set physical simulation type. Important. Should after collider material define RFPhysic.SetSimulationType(this); // Do not set convex, mass, drag for static if (simulationType == SimType.Static) { return; } // Convex collider meshCollider. After SetSimulation Type to turn off convex for kinematic RFPhysic.SetColliderConvex(this); // Set density. After collider defined RFPhysic.SetDensity(this); // Set drag properties RFPhysic.SetDrag(this); // Set material solidity and destructible physics.solidity = physics.Solidity; physics.destructible = physics.Destructible; }
// Explode kinematik objects void SetKinematic(Projectile projectile) { if (affectKinematic == true && projectile.fade > 0 && projectile.rb.isKinematic == true) { // Convert kinematic to dynamic via rigid script if (projectile.scrRigid != null) { projectile.scrRigid.simulationType = SimType.Dynamic; RFPhysic.SetSimulationType(projectile.scrRigid); // Set convex shape if (projectile.scrRigid.physics.meshCollider is MeshCollider == true) { ((MeshCollider)projectile.scrRigid.physics.meshCollider).convex = true; } } // Convert regular kinematik to dynamic else { projectile.rb.isKinematic = false; // TODO Set mass // Set convex MeshCollider meshCol = projectile.rb.gameObject.GetComponent <MeshCollider>(); if (meshCol != null && meshCol.convex == false) { meshCol.convex = true; } } } }
// Restore rigid properties static void Reset(RayfireRigid scr) { // Reset caching if it is on scr.meshDemolition.StopRuntimeCaching(); // Reset limitations scr.activation.Reset(); if (scr.restriction != null) { scr.restriction.Reset(); } scr.limitations.Reset(); scr.meshDemolition.Reset(); scr.clusterDemolition.Reset(); scr.fading.Reset(); // Reset damage if (scr.reset.damage == true) { scr.damage.Reset(); } // Set physical simulation type. Important. Should after collider material define RFPhysic.SetSimulationType(scr); }
// Fragments initialisation void InitFragments() { // No fragments if (HasFragments == false) { return; } // Set velocity RFPhysic.SetFragmentsVelocity(this); // TODO set current frame for cluster demol types // Sum total new fragments amount RayfireMan.inst.advancedDemolitionProperties.currentAmount += fragments.Count; // Set ancestor RFLimitations.SetAncestor(this); RFLimitations.SetDescendants(this); // Fading. move to fragment if (fading.onDemolition == true) { fading.DemolitionFade(fragments); } }
// Copy from public void CopyFrom(RFPhysic physics) { materialType = physics.materialType; material = physics.material; massBy = physics.massBy; mass = physics.mass; colliderType = physics.colliderType; useGravity = physics.useGravity; dampening = physics.dampening; Reset(); }
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(); }
// Create one cluster which includes all children meshes static bool ClusterizeNested(RayfireRigid scr) { // Get all nested children with meshes MeshFilter[] childMeshes = scr.gameObject.GetComponentsInChildren <MeshFilter>(); // No meshes in children if (childMeshes.Length == 0) { return(false); } // Create mesh colliders for every input mesh RFPhysic.SetClusterColliders(scr, childMeshes); return(true); }
// Create one cluster which includes only children meshes, not children of children meshes. static bool ClusterizeConnected(RayfireRigid scr) { // Setup cluster and shard if first time. Do not if copied from parent if (scr.clusterDemolition.cluster == null || scr.clusterDemolition.cluster.id == 0) { // Set cluster scr.clusterDemolition.cluster = RFCluster.SetCluster(scr.transForm, scr.clusterDemolition.connectivity); scr.clusterDemolition.cluster.id = 1; // Set shard neibs RFShard.SetShardNeibs(scr.clusterDemolition.cluster.shards, scr.clusterDemolition.connectivity); } // Get all children meshes List <MeshFilter> childMeshes = new List <MeshFilter>(); for (int i = 0; i < scr.transForm.childCount; i++) { MeshFilter mf = scr.transForm.GetChild(i).GetComponent <MeshFilter>(); if (mf != null) { childMeshes.Add(mf); } } // No meshes in children if (childMeshes.Count == 0) { return(false); } // float t1 = Time.realtimeSinceStartup; // Create mesh colliders for every input mesh and collect RFPhysic.SetClusterColliders(scr, childMeshes.ToArray()); // TODO connectivity check to find solo shards and make sure they are not connected return(true); }
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(); }
// 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; } }
// Set rigid props void SetRigid() { if (mode == AnimatorType.Play) { List <RayfireRigid> rigidList = gameObject.GetComponentsInChildren <RayfireRigid>().ToList(); foreach (RayfireRigid rigid in rigidList) { if (rigid.physics.exclude == false) { rigid.physics.recorder = true; // Check for kinematic state if (setToKinematic == true) { if (rigid.simulationType != SimType.Static || rigid.simulationType == SimType.Kinematic) { rigid.simulationType = SimType.Kinematic; RFPhysic.SetSimulationType(rigid); } } } } } }
// 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); }
// 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); }
// Restore cluster using backup cluster public static void RestoreBackup(RayfireRigid scr) { if (scr.reset.action == RFReset.PostDemolitionType.DeactivateToReset) { // Do not restore child clusters if (scr.clusterDemolition.cluster.id > 1) { return; } // Has no backup if (scr.clusterDemolition.backup == null) { return; } // Cluster was not demolished. Stop if (scr.objectType == ObjectType.ConnectedCluster) { if (scr.clusterDemolition.cluster.shards.Count == scr.clusterDemolition.backup.cluster.shards.Count) { return; } } // TODO check if nested cluster was demolished // if (false) if (scr.objectType == ObjectType.NestedCluster) // if (scr.clusterDemolition.cluster.tm.gameObject.activeSelf == true) //return; // Completely demolished child clusters do not deactivates if saved // Unyielding component with inactive overlap bug // Reset fragments list scr.fragments = null; // Remove particles DestroyParticles(scr); // Reset local shard rigid, destroy components TODO INPUT ORIGINAL CLUSTER, GET RIGIDS ResetDeepShardRigid(scr, scr.clusterDemolition.backup.cluster); // Create new child clusters roots destroy by nested cluster. BEFORE reparent shards if (scr.objectType == ObjectType.NestedCluster) { ResetRootsRecursive(scr.clusterDemolition.backup.cluster); RestoreClusterTmRecursive(scr.clusterDemolition.backup.cluster); ResetRootsParentsRecursive(scr.clusterDemolition.backup.cluster); } // Restore shards parent, position and rotation RestoreShardTmRecursive(scr.clusterDemolition.backup.cluster); // Destroy new child clusters roots created by connected cluster. AFTER reparent shards if (scr.objectType == ObjectType.ConnectedCluster) { DestroyRoots(scr); } // Copy class scr.clusterDemolition.cluster = new RFCluster(scr.clusterDemolition.backup.cluster); // Reset colliders RFPhysic.CollectClusterColliders(scr, scr.clusterDemolition.cluster); // Init shards: set non serialized vars RFCluster.InitCluster(scr, scr.clusterDemolition.cluster); scr.clusterDemolition.collapse.inProgress = false; } }