protected override void OnUpdate()
    {
        if (m_CharacterControllersGroup.CalculateEntityCount() == 0)
        {
            return;
        }

        var chunks = m_CharacterControllersGroup.CreateArchetypeChunkArray(Allocator.TempJob);

        var ccComponentType          = GetComponentTypeHandle <CharacterControllerComponentData>();
        var ccInternalType           = GetComponentTypeHandle <CharacterControllerInternalData>();
        var physicsColliderType      = GetComponentTypeHandle <PhysicsCollider>();
        var translationType          = GetComponentTypeHandle <Translation>();
        var rotationType             = GetComponentTypeHandle <Rotation>();
        var collisionEventBufferType = GetBufferTypeHandle <StatefulCollisionEvent>();
        var triggerEventBufferType   = GetBufferTypeHandle <StatefulTriggerEvent>();

        var deferredImpulses = new NativeStream(chunks.Length, Allocator.TempJob);

        var ccJob = new CharacterControllerJob
        {
            // Archetypes
            CharacterControllerComponentType = ccComponentType,
            CharacterControllerInternalType  = ccInternalType,
            PhysicsColliderType      = physicsColliderType,
            TranslationType          = translationType,
            RotationType             = rotationType,
            CollisionEventBufferType = collisionEventBufferType,
            TriggerEventBufferType   = triggerEventBufferType,

            // Input
            DeltaTime             = UnityEngine.Time.fixedDeltaTime,
            PhysicsWorld          = m_BuildPhysicsWorldSystem.PhysicsWorld,
            DeferredImpulseWriter = deferredImpulses.AsWriter()
        };

        Dependency = JobHandle.CombineDependencies(Dependency, m_ExportPhysicsWorldSystem.GetOutputDependency());
        Dependency = ccJob.Schedule(m_CharacterControllersGroup, Dependency);

        var applyJob = new ApplyDefferedPhysicsUpdatesJob()
        {
            Chunks = chunks,
            DeferredImpulseReader = deferredImpulses.AsReader(),
            PhysicsVelocityData   = GetComponentDataFromEntity <PhysicsVelocity>(),
            PhysicsMassData       = GetComponentDataFromEntity <PhysicsMass>(),
            TranslationData       = GetComponentDataFromEntity <Translation>(),
            RotationData          = GetComponentDataFromEntity <Rotation>()
        };

        Dependency = applyJob.Schedule(Dependency);
        var disposeHandle = deferredImpulses.Dispose(Dependency);

        // Must finish all jobs before physics step end
        m_EndFramePhysicsSystem.AddInputDependency(disposeHandle);
    }
Ejemplo n.º 2
0
        protected override void OnUpdate()
        {
            SimulatedFramesInCurrentTest++;
            var handle = JobHandle.CombineDependencies(Dependency, m_ExportPhysicsWorld.GetOutputDependency());

            if (SimulatedFramesInCurrentTest == k_TestDurationInFrames)
            {
                handle.Complete();
                FinishTesting();
            }

            Dependency = handle;
        }
        protected override void OnUpdate()
        {
            if (!m_RecordingBegan)
            {
                // > 1 because of default static body, logically should be > 0
                m_RecordingBegan = m_BuildPhysicsWorld.PhysicsWorld.NumBodies > 1;
            }
            else
            {
                SimulatedFramesInCurrentTest++;
                var handle = JobHandle.CombineDependencies(Dependency, m_ExportPhysicsWorld.GetOutputDependency());

                if (SimulatedFramesInCurrentTest == k_TestDurationInFrames)
                {
                    handle.Complete();
                    FinishTesting();
                }

                Dependency = handle;
            }
        }
    protected override void OnUpdate()
    {
        Dependency = JobHandle.CombineDependencies(m_ExportPhysicsWorld.GetOutputDependency(), Dependency);
        Dependency = JobHandle.CombineDependencies(m_TriggerSystem.OutDependency, Dependency);

        var deltaTime = Time.DeltaTime;

        // Need extra variables here so that they can be
        // captured by the Entities.Foreach loop below
        var hierarchyChildMask        = m_HierarchyChildMask;
        var nonTriggerDynamicBodyMask = m_NonTriggerDynamicBodyMask;

        Entities
        .WithName("TriggerVolumePortalJob")
        .WithBurst()
        .WithAll <TriggerVolumePortal>()
        .ForEach((Entity portalEntity, ref DynamicBuffer <StatefulTriggerEvent> triggerBuffer) =>
        {
            var triggerVolumePortal          = GetComponent <TriggerVolumePortal>(portalEntity);
            var companionEntity              = triggerVolumePortal.Companion;
            var companionTriggerVolumePortal = GetComponent <TriggerVolumePortal>(companionEntity);

            for (int i = 0; i < triggerBuffer.Length; i++)
            {
                var triggerEvent = triggerBuffer[i];
                var otherEntity  = triggerEvent.GetOtherEntity(portalEntity);

                // exclude other triggers, static bodies and processed events
                if (triggerEvent.State != EventOverlapState.Enter || !nonTriggerDynamicBodyMask.Matches(otherEntity))
                {
                    continue;
                }

                // Check if entity just teleported to this portal,
                // and if it did, decrement TransferCount
                if (triggerVolumePortal.TransferCount != 0)
                {
                    triggerVolumePortal.TransferCount--;
                    continue;
                }

                // a static body may be in a hierarchy, in which case Translation and Rotation may not be in world space
                var portalTransform = hierarchyChildMask.Matches(portalEntity)
                        ? Math.DecomposeRigidBodyTransform(GetComponent <LocalToWorld>(portalEntity).Value)
                        : new RigidTransform(GetComponent <Rotation>(portalEntity).Value, GetComponent <Translation>(portalEntity).Value);
                var companionTransform = hierarchyChildMask.Matches(companionEntity)
                        ? Math.DecomposeRigidBodyTransform(GetComponent <LocalToWorld>(companionEntity).Value)
                        : new RigidTransform(GetComponent <Rotation>(companionEntity).Value, GetComponent <Translation>(companionEntity).Value);

                var portalPositionOffset = companionTransform.pos - portalTransform.pos;
                var portalRotationOffset = math.mul(companionTransform.rot, math.inverse(portalTransform.rot));

                var entityPositionComponent = GetComponent <Translation>(otherEntity);
                var entityRotationComponent = GetComponent <Rotation>(otherEntity);
                var entityVelocityComponent = GetComponent <PhysicsVelocity>(otherEntity);

                entityVelocityComponent.Linear = math.rotate(portalRotationOffset, entityVelocityComponent.Linear);
                entityPositionComponent.Value += portalPositionOffset;
                entityRotationComponent.Value  = math.mul(entityRotationComponent.Value, portalRotationOffset);

                SetComponent(otherEntity, entityPositionComponent);
                SetComponent(otherEntity, entityRotationComponent);
                SetComponent(otherEntity, entityVelocityComponent);
                companionTriggerVolumePortal.TransferCount++;
            }

            SetComponent(portalEntity, triggerVolumePortal);
            SetComponent(companionEntity, companionTriggerVolumePortal);
        }).Schedule();
        m_EndFramePhysicsSystem.AddInputDependency(Dependency);
    }
        protected override void OnUpdate()
        {
            m_Counter++;
            if (m_Counter == 10)
            {
                m_ExportPhysicsWorld.GetOutputDependency().Complete();

                var staticEntities = m_BuildPhysicsWorld.StaticEntityGroup.ToEntityArray(Allocator.TempJob);

                // Change filter of child 0 in compound
                unsafe
                {
                    var colliderComponent = EntityManager.GetComponentData <PhysicsCollider>(staticEntities[0]);

                    ColliderKey colliderKey0 = ColliderKey.Empty;
                    colliderKey0.PushSubKey(colliderComponent.Value.Value.NumColliderKeyBits, 0);

                    CompoundCollider *compoundCollider = (CompoundCollider *)colliderComponent.ColliderPtr;
                    compoundCollider->GetChild(ref colliderKey0, out ChildCollider child0);
                    child0.Collider->Filter = CollisionFilter.Zero;
                    compoundCollider->RefreshCollisionFilter();

                    EntityManager.SetComponentData(staticEntities[0], colliderComponent);
                }

                // Change filter of child 1 in compound
                unsafe
                {
                    var colliderComponent = EntityManager.GetComponentData <PhysicsCollider>(staticEntities[1]);

                    ColliderKey colliderKey1 = ColliderKey.Empty;
                    colliderKey1.PushSubKey(colliderComponent.Value.Value.NumColliderKeyBits, 1);

                    CompoundCollider *compoundCollider = (CompoundCollider *)colliderComponent.ColliderPtr;
                    compoundCollider->GetChild(ref colliderKey1, out ChildCollider child1);
                    child1.Collider->Filter = CollisionFilter.Zero;
                    compoundCollider->RefreshCollisionFilter();

                    EntityManager.SetComponentData(staticEntities[1], colliderComponent);
                }

                // Change filter of both children in compound
                unsafe
                {
                    var colliderComponent = EntityManager.GetComponentData <PhysicsCollider>(staticEntities[2]);

                    ColliderKey colliderKey0 = ColliderKey.Empty;
                    colliderKey0.PushSubKey(colliderComponent.Value.Value.NumColliderKeyBits, 0);
                    ColliderKey colliderKey1 = ColliderKey.Empty;
                    colliderKey1.PushSubKey(colliderComponent.Value.Value.NumColliderKeyBits, 1);

                    CompoundCollider *compoundCollider = (CompoundCollider *)colliderComponent.ColliderPtr;
                    compoundCollider->GetChild(ref colliderKey0, out ChildCollider child0);
                    compoundCollider->GetChild(ref colliderKey1, out ChildCollider child1);
                    child0.Collider->Filter = CollisionFilter.Zero;
                    child1.Collider->Filter = CollisionFilter.Zero;
                    compoundCollider->RefreshCollisionFilter();

                    EntityManager.SetComponentData(staticEntities[2], colliderComponent);
                }

                // Change filter of the compound itself
                {
                    var colliderComponent = EntityManager.GetComponentData <PhysicsCollider>(staticEntities[3]);
                    colliderComponent.Value.Value.Filter = CollisionFilter.Zero;
                    EntityManager.SetComponentData(staticEntities[3], colliderComponent);
                }

                staticEntities.Dispose();
            }
            else if (m_Counter == 50)
            {
                var dynamicEntities = m_BuildPhysicsWorld.DynamicEntityGroup.ToEntityArray(Allocator.TempJob);

                // First 2 boxes should stay still, while other 2 should fall through
                {
                    var translation1 = EntityManager.GetComponentData <Translation>(dynamicEntities[0]);
                    Assert.IsTrue(translation1.Value.y > 0.99f, "Box started falling!");
                    var translation2 = EntityManager.GetComponentData <Translation>(dynamicEntities[1]);
                    Assert.IsTrue(translation2.Value.y > 0.99f, "Box started falling!");
                    var translation3 = EntityManager.GetComponentData <Translation>(dynamicEntities[2]);
                    Assert.IsTrue(translation3.Value.y < 0.9f, "Box didn't start falling!");
                    var translation4 = EntityManager.GetComponentData <Translation>(dynamicEntities[3]);
                    Assert.IsTrue(translation4.Value.y < 0.9f, "Box didn't start falling!");
                }

                dynamicEntities.Dispose();
            }
        }
        protected override void OnUpdate()
        {
            m_Counter++;
            if (m_Counter == 30)
            {
                m_ExportPhysicsWorld.GetOutputDependency().Complete();
                // First change filter of all ground colliders to collide with nothing
                var staticEntities = m_BuildPhysicsWorld.StaticEntityGroup.ToEntityArray(Allocator.TempJob);
                for (int i = 0; i < staticEntities.Length; i++)
                {
                    var colliderComponent = EntityManager.GetComponentData <PhysicsCollider>(staticEntities[i]);
                    colliderComponent.Value.Value.Filter = new CollisionFilter
                    {
                        BelongsTo    = ~CollisionFilter.Default.BelongsTo,
                        CollidesWith = ~CollisionFilter.Default.CollidesWith,
                        GroupIndex   = 1
                    };
                    EntityManager.SetComponentData(staticEntities[i], colliderComponent);
                }

                var verificationData          = m_VerificationGroup.ToEntityArray(Allocator.TempJob);
                var verificationComponentData = GetComponentDataFromEntity <VerifyActivationData>(true)[verificationData[0]];

                // Do nothing for ground 0 (other than filter change)
                int counter = 0;
                if (verificationComponentData.PureFilter > 0)
                {
                    counter++;
                }

                // Completely remove one ground (1)
                if (verificationComponentData.Remove > 0)
                {
                    EntityManager.DestroyEntity(staticEntities[counter]);
                    counter++;
                }

                // Convert one ground to dynamic object (2)
                if (verificationComponentData.MotionChange > 0)
                {
                    var colliderComponent = EntityManager.GetComponentData <PhysicsCollider>(staticEntities[counter]);
                    EntityManager.AddComponentData(staticEntities[counter], PhysicsMass.CreateDynamic(colliderComponent.MassProperties, 1.0f));
                    EntityManager.AddComponentData(staticEntities[counter], new PhysicsVelocity
                    {
                        Linear  = new float3(0.0f, -1.0f, 0.0f),
                        Angular = float3.zero
                    });
                    counter++;
                }

                // Teleport one ground (3)
                if (verificationComponentData.Teleport > 0)
                {
                    var translationComponent = EntityManager.GetComponentData <Translation>(staticEntities[counter]);
                    translationComponent.Value.y = -10.0f;
                    EntityManager.SetComponentData(staticEntities[counter], translationComponent);
                    counter++;
                }

                // Change collider of one ground (4)
                if (verificationComponentData.ColliderChange > 0)
                {
                    var colliderComponent = EntityManager.GetComponentData <PhysicsCollider>(staticEntities[counter]);
                    var oldFilter         = colliderComponent.Value.Value.Filter;
                    colliderComponent.Value = BoxCollider.Create(new BoxGeometry {
                        Orientation = quaternion.identity, Size = new float3(5.0f, 1.0f, 50.0f)
                    });
                    colliderComponent.Value.Value.Filter = oldFilter;
                    m_VerifyActivationSystem.CreatedColliders.Add(colliderComponent.Value);
                    EntityManager.SetComponentData(staticEntities[counter], colliderComponent);
                    counter++;
                }

                // Set new collider of one ground (5)
                if (verificationComponentData.NewCollider > 0)
                {
                    var colliderComponent    = EntityManager.GetComponentData <PhysicsCollider>(staticEntities[counter]);
                    var newColliderComponent = BoxCollider.Create(new BoxGeometry {
                        Orientation = quaternion.identity, Size = new float3(5.0f, 1.0f, 50.0f)
                    });
                    m_VerifyActivationSystem.CreatedColliders.Add(newColliderComponent);
                    newColliderComponent.Value.Filter = colliderComponent.Value.Value.Filter;
                    EntityManager.SetComponentData(staticEntities[counter], new PhysicsCollider {
                        Value = newColliderComponent
                    });
                    counter++;
                }

                verificationData.Dispose();
                staticEntities.Dispose();
            }
            else if (m_Counter == 40)
            {
                // Verify that all boxes started falling after the ground was changed
                var dynamicEntities = m_BuildPhysicsWorld.DynamicEntityGroup.ToEntityArray(Allocator.TempJob);
                for (int i = 0; i < dynamicEntities.Length; i++)
                {
                    var translation = EntityManager.GetComponentData <Translation>(dynamicEntities[i]);
                    Assert.IsTrue(translation.Value.y < 0.99f, "Box didn't start falling!");
                }

                dynamicEntities.Dispose();
            }
        }