/// <summary> /// Find native template given prefab template. This is only /// valid to access during runtime. /// </summary> /// <param name="template">Template prefab.</param> /// <returns>Native template if found, otherwise null.</returns> public agx.RigidBody GetNativeTemplate(RigidBody template) { if (!Application.isPlaying) { return(null); } var index = m_templates.FindIndex(entry => entry.RigidBody == template); // Template found, check if we have the instance in the distribution // model or we have to create an before we're initialized. if (index >= 0) { if (Native != null) { if (index < m_distributionModels.Count) { return(m_distributionModels[index].getBodyTemplate()); } } else if (m_preInitializedTemplates.TryGetValue(template, out var cachedPreInitialized)) { return(cachedPreInitialized); } else { var templateInstance = RigidBody.InstantiateTemplate(template, template.GetComponentsInChildren <Collide.Shape>()); if (templateInstance != null) { m_preInitializedTemplates.Add(template, templateInstance); } return(templateInstance); } } return(null); }
protected override bool Initialize() { RemoveInvalidTemplates(); if (m_templates.Count == 0) { Debug.LogWarning("Unable to initialize RigidBodyEmitter: 0 valid templates.", this); return(false); } if (EmitterShape == null) { Debug.LogWarning("Unable to initialize RigidBodyEmitter: Emitter Shape is null.", this); return(false); } if (EmitterShape.GetInitialized <Collide.Shape>() == null) { Debug.LogWarning($"Unable to initialize RigidBodyEmitter: Emitter Shape {EmitterShape.name} is invalid.", this); return(false); } if (!EmitterShape.IsSensor) { Debug.LogWarning($"RigidBodyEmitter Emitter Shape isn't a sensor but will be set to sensor by AGX Dynamics.", this); } Native = new agx.RigidBodyEmitter(); Native.setEnable(isActiveAndEnabled); m_event = new EmitEvent(this); NativeDistributionTable = new agx.Emitter.DistributionTable(); Native.setDistributionTable(NativeDistributionTable); m_distributionModels = new List <agx.RigidBodyEmitter.DistributionModel>(); var msProperties = GetComponent <MergeSplitProperties>()?.GetInitialized <MergeSplitProperties>(); foreach (var entry in TemplateEntries) { agx.RigidBody templateInstance = null; if (!m_preInitializedTemplates.TryGetValue(entry.RigidBody, out templateInstance)) { templateInstance = RigidBody.InstantiateTemplate(entry.RigidBody, entry.RigidBody.GetComponentsInChildren <Collide.Shape>()); } if (msProperties != null) { msProperties.RegisterNativeAndSynchronize(agxSDK.MergeSplitHandler.getOrCreateProperties(templateInstance)); } var distributionModel = new agx.RigidBodyEmitter.DistributionModel(templateInstance, entry.ProbabilityWeight); NativeDistributionTable.addModel(distributionModel); m_distributionModels.Add(distributionModel); m_event.MapResource(entry.RigidBody.name, entry.FindRenderResource()); // Handling collision group in the template hierarchy. // These components aren't instantiated during emit. // This enables collision filtering via the CollisionGroupsManager. var collisionGroupComponents = entry.RigidBody.GetComponentsInChildren <CollisionGroups>(); foreach (var collisionGroupComponent in collisionGroupComponents) { foreach (var collisionGroupEntry in collisionGroupComponent.Groups) { Native.addCollisionGroup(collisionGroupEntry.Tag.To32BitFnv1aHash()); } } } m_preInitializedTemplates.Clear(); Native.setGeometry(EmitterShape.NativeGeometry); GetSimulation().add(Native); Simulation.Instance.StepCallbacks.PostStepForward += SynchronizeVisuals; Simulation.Instance.StepCallbacks.SimulationPreCollide += OnSimulationPreCollide; return(true); }