Exemple #1
0
    public static void avoidProcess(Boid[] boids)
    {
        int count = FirstCheck(boids);
        int index = 0;

        int[] map = new int[count];

        while (count > 0 && index < BoidHelper.directions.Length)
        {
            Vector3 rayDirection = BoidHelper.directions[index];
            var     results      = new NativeArray <RaycastHit>(count, Allocator.TempJob);
            var     commands     = new NativeArray <SpherecastCommand>(count, Allocator.TempJob);

            int cmdId = 0;

            for (int i = 0; i < boids.Length; i++)
            {
                if (boids[i].checkState == CheckState.Updated)
                {
                    continue;
                }
                Vector3 dir = boids[i].cachedTransform.TransformDirection(rayDirection);

                map[cmdId] = i;

                commands[cmdId] = new SpherecastCommand(
                    boids[i].position,
                    boids[i].settings.boundsRadius,
                    dir,
                    boids[i].settings.collisionAvoidDst,
                    boids[i].settings.obstacleMask
                    );
                cmdId++;
            }

            // Schedule the batch of raycasts
            JobHandle handle = SpherecastCommand.ScheduleBatch(commands, results, batchSize, default(JobHandle));

            // Wait for the batch processing job to complete
            handle.Complete();
            int currentCount = count;
            // Copy the result. If batchedHit.collider is null there was no hit
            for (int i = 0; i < currentCount; i++)
            {
                int mapId = map[i];
                if (results[i].collider == null)
                {
                    boids[mapId].checkState = CheckState.Updated;
                    boids[mapId].accelerate = boids[mapId].cachedTransform.TransformDirection(rayDirection);
                    count--;
                    break;
                }
            }

            // Dispose the buffers
            results.Dispose();
            commands.Dispose();
            index++;
        }
    }
    private JobHandle SphereRaycastAhead([ReadOnly] TransformAccessArray transformAccessArray,
                                         JobHandle dependency = default)
    {
        float radius = 0.5f;

        for (int i = 0; i < _avoidanceCommands.Length; i++)
        {
            _avoidanceCommands[i] = new SpherecastCommand(transformAccessArray[i].position, radius,
                                                          transformAccessArray[i].forward, 100);
        }

        var handle = SpherecastCommand.ScheduleBatch(_avoidanceCommands, _avoidanceHits, 64, dependency);

        return(handle);
    }
    private JobHandle SphereCastUnder([ReadOnly] TransformAccessArray transformAccessArray,
                                      JobHandle dependency = default)
    {
        float radius = 0.5f;

        for (int i = 0; i < _surfaceNormalsCommands.Length; i++)
        {
            _surfaceNormalsCommands[i] = new SpherecastCommand(
                transformAccessArray[i].position + transformAccessArray[i].up * settings.height, radius,
                -transformAccessArray[i].up, 100);
        }

        var handle = SpherecastCommand.ScheduleBatch(_surfaceNormalsCommands, _surfaceNormalsHits, 64, dependency);

        return(handle);
    }
Exemple #4
0
    private Vector3 ObstacleRaysJob()
    {
        Vector3[] rayDirections = BoidHelper.directions;
        int       count         = rayDirections.Length;
        // count = 1;

        // Perform a single raycast using RaycastCommand and wait for it to complete
        // Setup the command and result buffers
        var results = new NativeArray <RaycastHit>(count, Allocator.TempJob);

        // var commands = new NativeArray<RaycastCommand>(count, Allocator.TempJob);
        var commands = new NativeArray <SpherecastCommand>(count, Allocator.TempJob);

        // Set the data of the first command
        Vector3 origin = position;

        for (int i = 0; i < count; i++)
        {
            Vector3 dir = cachedTransform.TransformDirection(rayDirections[i]);

            Vector3 direction = dir;

            commands[i] = new SpherecastCommand(origin, settings.boundsRadius, direction, settings.collisionAvoidDst, settings.obstacleMask);
        }

        // Schedule the batch of raycasts
        JobHandle handle = SpherecastCommand.ScheduleBatch(commands, results, batchSize, default(JobHandle));

        // Wait for the batch processing job to complete
        handle.Complete();
        Vector3 result = forward;

        // Copy the result. If batchedHit.collider is null there was no hit
        for (int i = 0; i < count; i++)
        {
            if (results[i].collider == null)
            {
                result = cachedTransform.TransformDirection(rayDirections[i]);
                break;
            }
        }

        // Dispose the buffers
        results.Dispose();
        commands.Dispose();
        return(result);
    }
Exemple #5
0
            public void Execute(int index)
            {
                var rayHit = spherecastHits[index];

                if (rayHit.point != default(Vector3))
                {
                    var previousCommand = previousCommands[index];
                    //little hack to bypass same collider hit in specific cases
                    var point    = rayHit.point;
                    var distance = previousCommand.distance - (point - previousCommand.origin).magnitude;
                    spherecastCommands[index] = new SpherecastCommand(point, previousCommand.radius, previousCommand.direction, distance, previousCommand.layerMask);
                }
                else
                {
                    spherecastCommands[index] = default(SpherecastCommand);
                }
            }
Exemple #6
0
    public static int FirstCheck(Boid[] boids)
    {
        int count    = boids.Length;
        var results  = new NativeArray <RaycastHit>(count, Allocator.TempJob);
        var commands = new NativeArray <SpherecastCommand>(count, Allocator.TempJob);

        for (int i = 0; i < boids.Length; i++)
        {
            commands[i] = new SpherecastCommand(
                boids[i].position,
                boids[i].settings.boundsRadius,
                boids[i].forward,
                boids[i].settings.collisionAvoidDst,
                boids[i].settings.obstacleMask
                );
        }

        JobHandle handle = SpherecastCommand.ScheduleBatch(commands, results, batchSize, default(JobHandle));

        // Wait for the batch processing job to complete
        handle.Complete();

        // Copy the result. If batchedHit.collider is null there was no hit
        for (int i = 0; i < boids.Length; i++)
        {
            if (results[i].collider == null)
            {
                boids[i].checkState = CheckState.Updated;
                boids[i].accelerate = Vector3.zero;
                count--;
            }
            else
            {
                boids[i].checkState = CheckState.NeedUpdate;
            }
        }

        // Dispose the buffers
        results.Dispose();
        commands.Dispose();
        return(count);
    }
Exemple #7
0
                public void Execute(int index)
                {
                    var entity         = Entities[StartIndex + index];
                    var position       = entityTransaction.GetComponentData <Position>(entity);
                    var rotation       = entityTransaction.GetComponentData <Rotation>(entity);
                    var sphere         = entityTransaction.GetComponentData <SphereColliderComponentData>(entity);
                    var collisionLayer = entityTransaction.GetSharedComponentData <CollisionLayerComponentData>(entity);

                    SpherecastCommand spherecast = Spherecasts[StartIndex + index * 3];
                    var dir = ((position.Value + sphere.Center) - (float3)spherecast.origin);

                    spherecast.direction = math.normalizesafe(dir);
                    spherecast.distance  = math.length(dir);
                    spherecast.layerMask = collisionLayer.Mask1;
                    Spherecasts[StartIndex + index * 3] = spherecast;
                    spherecast.layerMask = collisionLayer.Mask2;
                    Spherecasts[StartIndex + index * 3 + 1] = spherecast;
                    spherecast.layerMask = collisionLayer.Mask3;
                    Spherecasts[StartIndex + index * 3 + 2] = spherecast;
                }
Exemple #8
0
        void IEcsRunSystem.Run()
        {
            int count = _filter.GetEntitiesCount();

            if (count != 0)
            {
                // New Arrays
                hits     = new NativeArray <RaycastHit>(count, Allocator.TempJob);
                commands = new NativeArray <SpherecastCommand>(count, Allocator.TempJob);
                // Fill input Array
                foreach (var i in _filter)
                {
                    commands[i] = NewComand(i);
                }
                // Schedule
                handle = SpherecastCommand.ScheduleBatch(commands, hits, 4);
                // Finalize
                FinalizeJob();
            }
        }
        public void SingleHitsTest()
        {
            var maxHits           = 4;
            var rayStart          = new Vector3(0f, 2f, 0f);
            var cubeCommand       = new SpherecastCommand(cubeCollider.transform.position + rayStart, 1f, Vector3.down);
            var meshCubeCommand   = new SpherecastCommand(meshCubeCollider.transform.position + rayStart, 1f, Vector3.down);
            var meshConvexCommand = new SpherecastCommand(meshConvexCollider.transform.position + rayStart, 1f, Vector3.down);
            var emptyCommand      = new SpherecastCommand(new Vector3(30f, 0f, 0f) + rayStart, 1f, Vector3.down);

            var commandsArray = new SpherecastCommand[] { cubeCommand, meshCubeCommand, emptyCommand, meshConvexCommand };

            commands    = new NativeArray <SpherecastCommand>(commandsArray, Allocator.TempJob);
            commandHits = new NativeArray <RaycastHit>(commands.Length * maxHits, Allocator.TempJob);

            raycastAllCommand = new SpherecastAllCommand(commands, commandHits, maxHits);

            raycastAllCommand.Schedule(default(JobHandle)).Complete();

            Assert.AreEqual(cubeCollider, commandHits[maxHits * 0].collider);
            Assert.AreEqual(meshCubeCollider, commandHits[maxHits * 1].collider);
            Assert.AreEqual(null, commandHits[maxHits * 2].collider);

            var physicsHits = new RaycastHit[maxHits];

            for (int i = 0; i < commands.Length; i++)
            {
                var unityHitsCount = Physics.SphereCastNonAlloc(commands[i].origin, commands[i].radius, commands[i].direction, physicsHits);

                for (int j = 0; j < unityHitsCount; j++)
                {
                    var physicsHit = physicsHits[j];
                    var commandHit = commandHits[i * maxHits + j];
                    RaycastHitEquality.AssertEqual(physicsHit, commandHit);
                }
                if (unityHitsCount < maxHits)
                {
                    Assert.AreEqual(null, commandHits[i * maxHits + unityHitsCount].collider);
                }
            }
        }
        public void FromInsideHitsTest()
        {
            var maxHits           = 4;
            var direction         = new Vector3(1f, 1f).normalized;
            var cubeCommand       = new SpherecastCommand(cubeCollider.transform.position, 0.1f, direction);
            var meshCubeCommand   = new SpherecastCommand(meshCubeCollider.transform.position, 0.1f, direction);
            var meshConvexCommand = new SpherecastCommand(meshConvexCollider.transform.position, 0.1f, direction);

            var commandsArray = new SpherecastCommand[] { cubeCommand, meshCubeCommand, meshConvexCommand };

            commands    = new NativeArray <SpherecastCommand>(commandsArray, Allocator.TempJob);
            commandHits = new NativeArray <RaycastHit>(commands.Length * maxHits, Allocator.TempJob);

            raycastAllCommand = new SpherecastAllCommand(commands, commandHits, maxHits);

            raycastAllCommand.Schedule(default(JobHandle)).Complete();

            for (int i = 0; i < commands.Length; i++)
            {
                Assert.IsNull(commandHits[i * maxHits].collider, "SpherecastCommand behaviour changed, spherecasting from inside now returns collision");
            }
        }
Exemple #11
0
                public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
                {
                    NativeArray <SphereColliderComponentData> sphereColliders = chunk.GetNativeArray(SphereColliderType);
                    NativeArray <Position> positions = chunk.GetNativeArray(PositionType);
                    NativeArray <Scale>    scales    = chunk.GetNativeArray(ScaleType);

                    NativeArray <Entity> entities = chunk.GetNativeArray(EntityType);

                    float3 zero = float3.zero;

                    for (int i = 0, length = sphereColliders.Length; i < length; ++i)
                    {
                        SphereColliderComponentData sphere = sphereColliders[i];
                        Position position = positions[i];
                        Scale    scale    = scales[i];

                        SpherecastCommand sphereCast = new SpherecastCommand(position.Value + sphere.Center,
                                                                             sphere.Radius * math.max(scale.Value.z, math.max(scale.Value.y, scale.Value.x)),
                                                                             zero, 0,
                                                                             0);
                        SphereCasts.TryAdd(entities[i], sphereCast);
                    }
                }
        public void NeedForMinStepTest()
        {
            var maxHits           = 4;
            var rayStart          = new Vector3(0f, 4f, 0f);
            var meshConvexCommand = new SpherecastCommand(meshConvexCollider.transform.position + rayStart, 0.1f, Vector3.down);

            var commandsArray = new SpherecastCommand[] { meshConvexCommand };

            commands    = new NativeArray <SpherecastCommand>(commandsArray, Allocator.TempJob);
            commandHits = new NativeArray <RaycastHit>(commands.Length * maxHits, Allocator.TempJob);

            //setting minStep to 0f
            raycastAllCommand = new SpherecastAllCommand(commands, commandHits, maxHits);

            raycastAllCommand.Schedule(default(JobHandle)).Complete();

            Assert.AreEqual(meshConvexCollider, commandHits[0].collider);

            var physicsHits = new RaycastHit[maxHits];

            for (int i = 0; i < commands.Length; i++)
            {
                var unityHitsCount = Physics.SphereCastNonAlloc(commands[i].origin, commands[i].radius, commands[i].direction, physicsHits);

                for (int j = 0; j < unityHitsCount; j++)
                {
                    var physicsHit = physicsHits[j];
                    var commandHit = commandHits[i * maxHits + j];
                    RaycastHitEquality.AssertEqual(physicsHit, commandHit);
                }
                if (unityHitsCount < maxHits)
                {
                    Assert.IsNull(commandHits[i * maxHits + unityHitsCount].collider, "RaycastHit in corner point behaviour changed, minStep may be required");
                }
            }
        }
Exemple #13
0
            protected override JobHandle OnUpdate(JobHandle inputDeps)
            {
                PreCollisionSystem preCollisionSystem = World.Active.GetExistingManager <PreCollisionSystem>();

                if (preCollisionSystem != null)
                {
                    var entities     = preCollisionSystem.Entities;
                    var boxcasts     = preCollisionSystem.Boxcasts;
                    var spherecasts  = preCollisionSystem.Spherecasts;
                    var capsulecasts = preCollisionSystem.Capsulecasts;

                    EntityManager.CompleteAllJobs();

                    if (boxcasts.IsCreated && boxcasts.Length != 0)
                    {
                        var hitBoxCollider = new NativeArray <RaycastHit>(boxcasts.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                        var transaction = EntityManager.BeginExclusiveEntityTransaction();

                        var job = new UpdateBoxDistDir {
                            Boxcasts          = boxcasts,
                            Entities          = entities,
                            entityTransaction = transaction
                        };


                        var handle = job.Schedule(boxcasts.Length / 3, 32, inputDeps);

                        EntityManager.ExclusiveEntityTransactionDependency = handle;

                        Utils.Utils.ScheduleBatchedJobAndComplete(handle);

                        EntityManager.EndExclusiveEntityTransaction();

                        handle = BoxcastCommand.ScheduleBatch(boxcasts, hitBoxCollider, 1, default);

                        Utils.Utils.ScheduleBatchedJobAndComplete(handle);

                        InvokeCollisionResponse(entities, hitBoxCollider, 0, boxcasts.Length);

                        hitBoxCollider.Dispose();
                    }

                    if (spherecasts.IsCreated && spherecasts.Length != 0)
                    {
                        var hitSphereCollider = new NativeArray <RaycastHit>(spherecasts.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                        var transaction = EntityManager.BeginExclusiveEntityTransaction();

                        var job = new UpdateSphereDistDir {
                            Spherecasts       = spherecasts,
                            Entities          = entities,
                            entityTransaction = transaction,
                            StartIndex        = boxcasts.Length / 3
                        };

                        var handle = job.Schedule(spherecasts.Length / 3, 32, inputDeps);

                        EntityManager.ExclusiveEntityTransactionDependency = handle;

                        Utils.Utils.ScheduleBatchedJobAndComplete(handle);

                        EntityManager.EndExclusiveEntityTransaction();

                        handle = SpherecastCommand.ScheduleBatch(spherecasts, hitSphereCollider, 1, default);

                        Utils.Utils.ScheduleBatchedJobAndComplete(handle);

                        InvokeCollisionResponse(entities, hitSphereCollider, boxcasts.Length, spherecasts.Length);

                        hitSphereCollider.Dispose();
                    }

                    if (capsulecasts.IsCreated && capsulecasts.Length != 0)
                    {
                        var hitCapsuleCollider = new NativeArray <RaycastHit>(capsulecasts.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

                        var transaction = EntityManager.BeginExclusiveEntityTransaction();

                        var job = new UpdateCapsuleDistDir {
                            Capsulecasts      = capsulecasts,
                            Entities          = entities,
                            entityTransaction = transaction,
                            StartIndex        = (boxcasts.Length + spherecasts.Length) / 3
                        };

                        var handle = job.Schedule(capsulecasts.Length / 3, 32, inputDeps);

                        EntityManager.ExclusiveEntityTransactionDependency = handle;

                        Utils.Utils.ScheduleBatchedJobAndComplete(handle);

                        EntityManager.EndExclusiveEntityTransaction();

                        handle = CapsulecastCommand.ScheduleBatch(capsulecasts, hitCapsuleCollider, 1, default);

                        Utils.Utils.ScheduleBatchedJobAndComplete(handle);

                        InvokeCollisionResponse(entities, hitCapsuleCollider, spherecasts.Length, capsulecasts.Length);

                        hitCapsuleCollider.Dispose();
                    }
                }
                return(inputDeps);
            }