Exemple #1
0
 /// <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);
 }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
            }
        }