// Create single dust particle system public void CreateDust(Transform host, RayfireDust scr, MeshFilter emitMeshFilter, int emitMatIndex, ParticleSystem ps) { // Set main module RFParticles.SetMain(ps.main, scr.emission.lifeMin, scr.emission.lifeMax, scr.emission.sizeMin, scr.emission.sizeMax, scr.dynamic.gravityMin, scr.dynamic.gravityMax, scr.dynamic.speedMin, scr.dynamic.speedMax, 0f, scr.limitations.maxParticles, scr.emission.duration); // Emission over distance RFParticles.SetEmission(ps.emission, scr.emission.distanceRate, (short)scr.amountFinal); // Emission from mesh or from impact point if (emitMeshFilter != null) { RFParticles.SetShapeMesh(ps.shape, emitMeshFilter.sharedMesh, emitMatIndex, emitMeshFilter.transform.localScale); } else { RFParticles.SetShapeObject(ps.shape); } // Collision RFParticles.SetCollisionDust(ps.collision, scr.collision); // Color over life time RFParticles.SetColorOverLife(ps.colorOverLifetime, scr.opacity); // Noise RFParticles.SetNoise(ps.noise, scr.noise); // Renderer SetParticleRendererDust(ps.GetComponent <ParticleSystemRenderer>(), scr.dustMaterial, scr.rendering.castShadows, scr.rendering.receiveShadows); // Start playing ps.Play(); }
// Emit particles public void Emit() { // Initialize Initialize(); // Emitter is not ready if (initialized == false) { return; } // Set material properties in case object has no rigid collision.SetMaterialProps(this); // Particle system ParticleSystem ps = RFParticles.CreateParticleSystemDebris(this); // Get components MeshFilter emitMeshFilter = GetComponent <MeshFilter>(); MeshRenderer meshRenderer = GetComponent <MeshRenderer>(); // Get emit material index int emitMatIndex = RFParticles.GetEmissionMatIndex(meshRenderer, emissionMaterial); // TODO set amount this.amountFinal = 30; // Create debris CreateDebris(transform, this, emitMeshFilter, emitMatIndex, ps); }
// Emit particles public void Emit() { // Initialize Initialize(); // Emitter is not ready if (initialized == false) { return; } // Particle system ParticleSystem ps = CreateParticleSystem(this); // Get components MeshFilter emitMeshFilter = GetComponent <MeshFilter>(); MeshRenderer meshRenderer = GetComponent <MeshRenderer>(); // Get emit material index int emitMatIndex = RFParticles.GetEmissionMatIndex(meshRenderer, emissionMaterial); // TODO set amount this.amountFinal = 30; // Create debris CreateDust(transform, this, emitMeshFilter, emitMatIndex, ps); }
// Awake ops void AwakeMethods() { // Create RayFire manager if not created RayfireMan.RayFireManInit(); // Set components for mesh / skinned mesh / clusters SetComponentsBasic(); // Set particles RFParticles.SetParticleComponents(this); // Init mesh root. if (SetRootMesh() == true) { return; } // Check for user mistakes RFLimitations.Checks(this); // Set components for mesh / skinned mesh / clusters SetComponentsPhysics(); // Initialization Mesh input if (meshDemolition.meshInput == RFDemolitionMesh.MeshInputType.AtInitialization) { MeshInput(); } // Precache meshes at awake AwakePrecache(); // Prefragment object at awake AwakePrefragment(); }
/// ///////////////////////////////////////////////////////// /// Awake ops /// ///////////////////////////////////////////////////////// // Init mesh root. Copy Rigid component for children with mesh bool SetRootMesh() { if (objectType == ObjectType.MeshRoot) { // Stop if already initiated if (limitations.demolished == true || physics.exclude == true) { return(true); } // Get children List <Transform> children = new List <Transform>(); for (int i = 0; i < transform.childCount; i++) { children.Add(transform.GetChild(i)); } // Add Rigid to child with mesh fragments = new List <RayfireRigid>(); for (int i = 0; i < children.Count; i++) { if (children[i].GetComponent <MeshFilter>() != null) { // Get rigid // TODO check if fragment already has Rigid, Reinit in this case. RayfireRigid childRigid = children[i].gameObject.GetComponent <RayfireRigid>(); if (childRigid == null) { childRigid = children[i].gameObject.AddComponent <RayfireRigid>(); } fragments.Add(childRigid); // Copy parent properties CopyPropertiesTo(childRigid); // Init childRigid.Initialize(); } } // Copy initialized particles RFParticles.CopyRootMeshParticles(this, fragments); // TODO Setup as clusters root children with transform only // Check for Unyielding component RayfireUnyielding[] unyArray = transform.GetComponents <RayfireUnyielding>(); for (int i = 0; i < unyArray.Length; i++) { unyArray[i].SetUnyByOverlap(this); } // Turn off demolition and physics demolitionType = DemolitionType.None; physics.exclude = true; return(true); } return(false); }
// 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; } } } }
// 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); }
// Impact Dust void ImpactDust(RayfireRigid source, Vector3 impactPos, Vector3 impactNormal) { if (dust == true && source.HasDust == true) { for (int i = 0; i < source.dustList.Count; i++) { if (source.dustList[i].onImpact == true) { RFParticles.CreateDustImpact(source.dustList[i], impactPos, impactNormal); } } } }
// Impact Debris void ImpactDebris(RayfireRigid source, Vector3 impactPos, Vector3 impactNormal) { if (debris == true && source.HasDebris == true) { foreach (var sourceDebris in source.debrisList) { if (sourceDebris.onImpact == true) { RFParticles.CreateDebrisImpact(sourceDebris, impactPos, impactNormal); } } } }
// Impact Dust void ImpactDust(RayfireRigid source, Vector3 impactPos, Vector3 impactNormal) { if (dust == true && source.HasDust == true) { foreach (var sourceDust in source.dustList) { if (sourceDust.onImpact == true) { RFParticles.CreateDustImpact(sourceDust, impactPos, impactNormal); } } } }
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(); RFParticles.SetParticleComponents(targ as RayfireRigid); 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 common /// ///////////////////////////////////////////////////////// // Create single debris particle system public void CreateDebris(Transform host, RayfireDebris scr, MeshFilter emitMeshFilter, int emitMatIndex, ParticleSystem ps) { // Set main module RFParticles.SetMain(ps.main, scr.emission.lifeMin, scr.emission.lifeMax, scr.emission.sizeMin, scr.emission.sizeMax, scr.dynamic.gravityMin, scr.dynamic.gravityMax, scr.dynamic.speedMin, scr.dynamic.speedMax, 3.1f, scr.limitations.maxParticles, scr.emission.duration); // Emission over distance RFParticles.SetEmission(ps.emission, scr.emission.distanceRate, scr.amountFinal); // Emission from mesh or from impact point if (emitMeshFilter != null) { RFParticles.SetShapeMesh(ps.shape, emitMeshFilter.sharedMesh, emitMatIndex, emitMeshFilter.transform.localScale); } else { RFParticles.SetShapeObject(ps.shape); } // Inherit velocity RFParticles.SetVelocity(ps.inheritVelocity, scr.dynamic); // Size over lifetime RFParticles.SetSizeOverLifeTime(ps.sizeOverLifetime, scr.refScale); // Rotation by speed RFParticles.SetRotationBySpeed(ps.rotationBySpeed, scr.dynamic.rotationSpeed); // Collision RFParticles.SetCollisionDebris(ps.collision, scr.collision); // Noise RFParticles.SetNoise(ps.noise, scr.noise); // Renderer SetParticleRendererDebris(ps.GetComponent <ParticleSystemRenderer>(), scr); // Start playing ps.Play(); }
/// ///////////////////////////////////////////////////////// /// Static /// ///////////////////////////////////////////////////////// // Activate inactive object public static void Activate(RayfireRigid scr) { // Stop if excluded if (scr.physics.exclude == true) { return; } // Skip not activatable unyielding objects if (scr.activation.activatable == false && scr.activation.unyielding == true) { return; } // Initialize if not if (scr.initialized == false) { scr.Initialize(); } // Turn convex if kinematik activation if (scr.simulationType == SimType.Kinematic) { MeshCollider meshCollider = scr.physics.meshCollider as MeshCollider; if (meshCollider != null) { meshCollider.convex = true; } // Swap with animated object if (scr.physics.rec == true) { // Set dynamic before copy scr.simulationType = SimType.Dynamic; scr.physics.rigidBody.isKinematic = false; scr.physics.rigidBody.useGravity = scr.physics.useGravity; // Create copy GameObject inst = UnityEngine.Object.Instantiate(scr.gameObject); inst.transform.position = scr.transForm.position; inst.transform.rotation = scr.transForm.rotation; // Save velocity Rigidbody rBody = inst.GetComponent <Rigidbody>(); if (rBody != null) { rBody.velocity = scr.physics.rigidBody.velocity; rBody.angularVelocity = scr.physics.rigidBody.angularVelocity; } // Activate and init rigid scr.gameObject.SetActive(false); } } // Connectivity check scr.activation.CheckConnectivity(); // Set state scr.activation.activated = true; // Set props scr.simulationType = SimType.Dynamic; scr.physics.rigidBody.isKinematic = false; scr.physics.rigidBody.useGravity = scr.physics.useGravity; // Fade on activation if (scr.fading.onActivation == true) { // Size check if (scr.fading.sizeFilter > 0 && scr.fading.sizeFilter > scr.limitations.bboxSize) { scr.Fade(); } else { scr.Fade(); } } // Init particles on activation RFParticles.InitActivationParticles(scr); // Event scr.activationEvent.InvokeLocalEvent(scr); RFActivationEvent.InvokeGlobalEvent(scr); // Add initial rotation if still TODO put in ui if (scr.physics.rigidBody.angularVelocity == Vector3.zero) { float val = 1.0f; scr.physics.rigidBody.angularVelocity = new Vector3( Random.Range(-val, val), Random.Range(-val, val), Random.Range(-val, val)); } }
// 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(); }
// Create slices by mesh and pivots array List <RayfireRigid> CreateSlices() { // Create root object RFLimitations.CreateRoot(this); // Clear array for new fragments List <RayfireRigid> scrArray = new List <RayfireRigid>(); // Vars int baseLayer = meshDemolition.GetLayer(this); string baseTag = gameObject.tag; string baseName = gameObject.name + "_sl_"; // Create fragment objects for (int i = 0; i < meshes.Length; ++i) { // Get object from pool or create RayfireRigid rfScr = RayfireMan.inst.GetPoolObject(); // Setup rfScr.transform.position = transForm.position + pivots[i]; rfScr.transform.parent = rootChild; rfScr.name = baseName + i; rfScr.gameObject.tag = baseTag; rfScr.gameObject.layer = baseLayer; rfScr.meshFilter.sharedMesh = meshes[i]; rfScr.meshFilter.sharedMesh.name = baseName + i; rfScr.rootParent = rootChild; // Copy properties from parent to fragment node CopyPropertiesTo(rfScr); // Copy particles RFParticles.CopyParticles(this, rfScr); // Shadow casting if (RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > 0 && RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > meshes[i].bounds.size.magnitude) { rfScr.meshRenderer.shadowCastingMode = ShadowCastingMode.Off; } // Turn on rfScr.gameObject.SetActive(true); // Set multymaterial RFSurface.SetMaterial(subIds, meshRenderer.sharedMaterials, materials, rfScr.meshRenderer, i, meshes.Length); // Inherit same current depth level rfScr.limitations.currentDepth = limitations.currentDepth + 1; // Set collider mesh MeshCollider mc = rfScr.physics.meshCollider as MeshCollider; if (mc != null) { mc.sharedMesh = meshes[i]; mc.name = meshes[i].name; } // Add in array scrArray.Add(rfScr); } // Empty lists DeleteCache(); return(scrArray); }
// 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(); }
/// ///////////////////////////////////////////////////////// /// Static /// ///////////////////////////////////////////////////////// // Activate inactive object public static void Activate(RayfireRigid scr) { // Stop if excluded if (scr.physics.exclude == true) { return; } // Initialize if not if (scr.initialized == false) { scr.Initialize(); } // Turn convex if kinematik activation if (scr.simulationType == SimType.Kinematic) { MeshCollider meshCollider = scr.physics.meshCollider as MeshCollider; if (meshCollider != null) { meshCollider.convex = true; } // Swap with animated object if (scr.physics.recorder == true) { // Set dynamic before copy scr.simulationType = SimType.Dynamic; scr.physics.rigidBody.isKinematic = false; scr.physics.rigidBody.useGravity = scr.physics.useGravity; // Create copy GameObject inst = scr.InstantiateGo(scr.gameObject); inst.transform.position = scr.transForm.position; inst.transform.rotation = scr.transForm.rotation; // Save velocity Rigidbody rBody = inst.GetComponent <Rigidbody>(); if (rBody != null) { rBody.velocity = scr.physics.rigidBody.velocity; rBody.angularVelocity = scr.physics.rigidBody.angularVelocity; } // Activate and init rigid scr.gameObject.SetActive(false); } } // Connectivity check scr.activation.CheckConnectivity(); // Set state scr.activation.activated = true; // Set props scr.simulationType = SimType.Dynamic; scr.physics.rigidBody.isKinematic = false; scr.physics.rigidBody.useGravity = scr.physics.useGravity; // Fade on activation if (scr.fading.onActivation == true) { scr.Fade(); } // Init particles on activation RFParticles.InitActivationParticles(scr); // Event scr.activationEvent.InvokeLocalEvent(scr); RFActivationEvent.InvokeGlobalEvent(scr); // TODO add initial velocity and rotation if still //rigidBody.velocity = }
// 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); }
// 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); }
// 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); }
// 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); }