/// <summary> /// Find if <paramref name="template"/> is part of this emitter. /// </summary> /// <param name="template">Template rigid body to check.</param> /// <returns>True if <paramref name="template"/> is part of this emitter, otherwise false.</returns> public bool ContainsTemplate(RigidBody template) { return(m_templates.Find(t => t.RigidBody == template) != 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); }
/// <summary> /// Creates native instance and adds it to the simulation if this constraint /// is properly configured. /// </summary> /// <returns>True if successful.</returns> protected override bool Initialize() { if (AttachmentPair.ReferenceObject == null) { Debug.LogError("Unable to initialize constraint. Reference object must be valid and contain a rigid body component.", this); return(false); } // Synchronize frames to make sure connected frame is up to date. AttachmentPair.Synchronize(); // TODO: Disabling rigid body game object (activeSelf == false) and will not be // able to create native body (since State == Constructed and not Awake). // Do: GetComponentInParent<RigidBody>( true <- include inactive ) and wait // for the body to become active? // E.g., rb.AwaitInitialize += ThisConstraintInitialize. RigidBody rb1 = AttachmentPair.ReferenceObject.GetInitializedComponentInParent <RigidBody>(); if (rb1 == null) { Debug.LogError("Unable to initialize constraint. Reference object must contain a rigid body component.", AttachmentPair.ReferenceObject); return(false); } // Native constraint frames. agx.Frame f1 = new agx.Frame(); agx.Frame f2 = new agx.Frame(); // Note that the native constraint want 'f1' given in rigid body frame, and that // 'ReferenceFrame' may be relative to any object in the children of the body. f1.setLocalTranslate(AttachmentPair.ReferenceFrame.CalculateLocalPosition(rb1.gameObject).ToHandedVec3()); f1.setLocalRotate(AttachmentPair.ReferenceFrame.CalculateLocalRotation(rb1.gameObject).ToHandedQuat()); RigidBody rb2 = AttachmentPair.ConnectedObject != null?AttachmentPair.ConnectedObject.GetInitializedComponentInParent <RigidBody>() : null; if (rb2 != null) { // Note that the native constraint want 'f2' given in rigid body frame, and that // 'ReferenceFrame' may be relative to any object in the children of the body. f2.setLocalTranslate(AttachmentPair.ConnectedFrame.CalculateLocalPosition(rb2.gameObject).ToHandedVec3()); f2.setLocalRotate(AttachmentPair.ConnectedFrame.CalculateLocalRotation(rb2.gameObject).ToHandedQuat()); } else { f2.setLocalTranslate(AttachmentPair.ConnectedFrame.Position.ToHandedVec3()); f2.setLocalRotate(AttachmentPair.ConnectedFrame.Rotation.ToHandedQuat()); } try { Native = (agx.Constraint)Activator.CreateInstance(NativeType, new object[] { rb1.Native, f1, (rb2 != null ? rb2.Native : null), f2 }); // Assigning native elementary constraints to our elementary constraint instances. foreach (ElementaryConstraint ec in ElementaryConstraints) { if (!ec.OnConstraintInitialize(this)) { throw new Exception("Unable to initialize elementary constraint: " + ec.NativeName + " (not present in native constraint). ConstraintType: " + Type); } } bool added = GetSimulation().add(Native); Native.setEnable(IsEnabled); // Not possible to handle collisions if connected frame parent is null/world. if (CollisionsState != ECollisionsState.KeepExternalState && AttachmentPair.ConnectedObject != null) { string groupName = gameObject.name + "_" + gameObject.GetInstanceID().ToString(); GameObject go1 = null; GameObject go2 = null; bool propagateToChildren1 = false; bool propagateToChildren2 = false; if (CollisionsState == ECollisionsState.DisableReferenceVsConnected) { go1 = AttachmentPair.ReferenceObject; go2 = AttachmentPair.ConnectedObject; } else { go1 = rb1.gameObject; propagateToChildren1 = true; go2 = rb2 != null ? rb2.gameObject : AttachmentPair.ConnectedObject; propagateToChildren2 = true; } go1.GetOrCreateComponent <CollisionGroups>().GetInitialized <CollisionGroups>().AddGroup(groupName, propagateToChildren1); go2.GetOrCreateComponent <CollisionGroups>().GetInitialized <CollisionGroups>().AddGroup(groupName, propagateToChildren2); CollisionGroupsManager.Instance.GetInitialized <CollisionGroupsManager>().SetEnablePair(groupName, groupName, false); } Native.setName(name); bool valid = added && Native.getValid(); Simulation.Instance.StepCallbacks.PreSynchronizeTransforms += OnPreStepForwardUpdate; return(valid); } catch (System.Exception e) { Debug.LogException(e, gameObject); return(false); } }