Esempio n. 1
0
        /// <summary>
        /// Schedules background jobs to move all agents using the given delta time
        /// </summary>
        public JobHandle MoveAgents(float dt, JobHandle dependsOn = default)
        {
            m_spatialMap.Clear();

            AgentWorld agentWorld = new AgentWorld();

            agentWorld.offset   = world.transform.position;
            agentWorld.rotation = world.transform.rotation;
            agentWorld.center   = world.data.center;
            agentWorld.scale    = world.scale;
            agentWorld.size     = new int3(
                world.size.x,
                world.size.y,
                world.size.z
                );

            if (!movingAllAgents.IsCompleted)
            {
                movingAllAgents.Complete();
            }

            // update the spatial map with all agent positions
            JobHandle spatialMaps = UpdateSpatialMap(agentWorld, dependsOn);

            // update each agents position by archetype
            for (int i = 0; i < archetypes.Count; i++)
            {
                m_movingByArchetype[i] = MoveByArchetype(i, agentWorld, dt, spatialMaps);
            }

            movingAllAgents = JobHandle.CombineDependencies(m_movingByArchetype);
            return(movingAllAgents);
        }
Esempio n. 2
0
        public void AgentsRiseWhenBuried()
        {
            NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(1, Allocator.Persistent);

            agents[0] = new AgentKinematics()
            {
                velocity = new float3(0, 0, 0)
            };

            NativeArray <float3> steering = new NativeArray <float3>(1, Allocator.Persistent);

            steering[0] = new float3(0, 0, 0);

            NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(1, Allocator.Persistent);

            active[0] = AgentBehaviors.Active;

            NativeArray <VRoxel.Navigation.Block> blocks = new NativeArray <VRoxel.Navigation.Block>(1, Allocator.Persistent);

            VRoxel.Navigation.Block solidBlock = new VRoxel.Navigation.Block();
            solidBlock.solid = true; solidBlock.cost = 1; blocks[0] = solidBlock;

            NativeArray <byte> voxels = new NativeArray <byte>(1, Allocator.Persistent);

            AgentWorld world = new AgentWorld()
            {
                scale    = 1f,
                offset   = float3.zero,
                center   = new float3(0.5f, 0.5f, 0.5f),
                rotation = quaternion.identity,
            };

            GravityBehavior job = new GravityBehavior()
            {
                gravity   = new float3(0, -4f, 0),
                world     = world,
                steering  = steering,
                behaviors = active,
                agents    = agents,
                blocks    = blocks,
                voxels    = voxels,
            };

            job.Schedule(1, 1).Complete();

            Assert.AreEqual(new float3(0, 2, 0), steering[0]);

            agents.Dispose();
            active.Dispose();
            blocks.Dispose();
            voxels.Dispose();
            steering.Dispose();
        }
Esempio n. 3
0
    // Use this for initialization
    void Start()
    {
        spawner         = FindObjectOfType <AgentSpawner>();
        world           = FindObjectOfType <AgentWorld>();
        leaderBoardText = FindObjectOfType <LeaderBoardText>();
        playerNameToId  = new Dictionary <string, int>();
        playerIdToName  = new string[leaderBoardSize];
        playerScores    = new int[leaderBoardSize];
        File.WriteAllText(logPath, string.Empty);
        FileStream fileStream = new FileStream(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

        streamReader = new StreamReader(fileStream);
    }
Esempio n. 4
0
        /// <summary>
        /// Schedules background jobs to update the spatial map for all agents
        /// </summary>
        protected JobHandle UpdateSpatialMap(AgentWorld agentWorld, JobHandle dependsOn = default)
        {
            JobHandle handle = dependsOn;

            for (int i = 0; i < archetypes.Count; i++)
            {
                BuildSpatialMapJob job = new BuildSpatialMapJob();
                job.movementConfigs = m_movementTypes;
                job.movement        = m_agentMovementTypes[i];
                job.collision       = archetypes[i].collision;
                job.spatialMap      = m_spatialMapWriter;
                job.behaviors       = m_agentBehaviors[i];
                job.agents          = m_agentKinematics[i];
                job.size            = spatialBucketSize;
                job.world           = agentWorld;

                handle = job.Schedule(
                    m_transformAccess[i],
                    handle
                    );
            }

            return(handle);
        }
Esempio n. 5
0
 // Use this for initialization
 void Start()
 {
     world    = FindObjectOfType <AgentWorld>();
     textMesh = GetComponent <TextMesh>();
 }
Esempio n. 6
0
        public void AddBrakeForceWhenAgentsCollide()
        {
            float3 position1 = float3.zero;
            float3 position2 = new float3(0f, 1f, 0f);

            NativeMultiHashMap <int3, SpatialMapData> spatialMap = new NativeMultiHashMap <int3, SpatialMapData>(1, Allocator.Persistent);

            spatialMap.Add(int3.zero, new SpatialMapData()
            {
                position = position1
            });
            spatialMap.Add(int3.zero, new SpatialMapData()
            {
                position = position2
            });

            NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(2, Allocator.Persistent);

            agents[0] = new AgentKinematics()
            {
                position = position1, velocity = new float3(0, 0, 0)
            };
            agents[1] = new AgentKinematics()
            {
                position = position2, velocity = new float3(0, 1, 0)
            };

            NativeArray <float3> steering = new NativeArray <float3>(2, Allocator.Persistent);

            steering[0] = new float3(0, 1, 0);
            steering[1] = new float3(1, 0, 1);

            NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(2, Allocator.Persistent);

            for (int i = 0; i < 2; i++)
            {
                active[i] = AgentBehaviors.Queueing;
            }

            AgentWorld world = new AgentWorld()
            {
                scale    = 1f,
                offset   = float3.zero,
                center   = new float3(0.5f, 0.5f, 0.5f),
                rotation = quaternion.identity,
            };

            QueueBehavior job = new QueueBehavior()
            {
                maxBrakeForce  = 0.8f,
                maxQueueAhead  = 1f,
                maxQueueRadius = 1f,
                maxDepth       = 100,

                world      = world,
                size       = new int3(1, 1, 1),
                spatialMap = spatialMap,
                steering   = steering,
                behaviors  = active,
                agents     = agents
            };

            job.Schedule(2, 1).Complete();

            // first agent should be braking
            float3 expected = new float3(0, 0.2f, 0);

            Assert.AreEqual(true, Mathf.Approximately(expected.x, steering[0].x));
            Assert.AreEqual(true, Mathf.Approximately(expected.y, steering[0].y));
            Assert.AreEqual(true, Mathf.Approximately(expected.z, steering[0].z));

            // second agent should not be braking
            expected = new float3(1, 0, 1);
            Assert.AreEqual(true, Mathf.Approximately(expected.x, steering[1].x));
            Assert.AreEqual(true, Mathf.Approximately(expected.y, steering[1].y));
            Assert.AreEqual(true, Mathf.Approximately(expected.z, steering[1].z));

            spatialMap.Dispose();
            steering.Dispose();
            agents.Dispose();
            active.Dispose();
        }
Esempio n. 7
0
 // Use this for initialization
 void Start()
 {
     agentManager    = FindObjectOfType <AgentWorld>();
     phosphorManager = FindObjectOfType <PhosphorManager>();
 }
Esempio n. 8
0
 // Use this for initialization
 void Start()
 {
     cloudMaterial = new Material(cloudShader);
     world         = FindObjectOfType <AgentWorld>();
     cloudMaterial.SetFloat("timeOffset", Random.value);
 }
Esempio n. 9
0
        public void UpdatesDirections()
        {
            NativeArray <float3>          directions = new NativeArray <float3>(1, Allocator.Persistent);
            NativeArray <AgentKinematics> agents     = new NativeArray <AgentKinematics>(1, Allocator.Persistent);

            agents[0] = new AgentKinematics()
            {
                position = Vector3.up
            };

            NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(1, Allocator.Persistent);

            active[0] = AgentBehaviors.Seeking;

            NativeArray <byte> flowField      = new NativeArray <byte>(1, Allocator.Persistent);
            NativeArray <int3> flowDirections = new NativeArray <int3>(27, Allocator.Persistent);

            for (int i = 0; i < 1; i++)
            {
                flowField[i] = (byte)Direction3Int.Name.Up;
            }

            for (int i = 0; i < 27; i++)
            {
                Vector3Int dir = Direction3Int.Directions[i];
                flowDirections[i] = new int3(dir.x, dir.y, dir.z);
            }

            NativeArray <int>           agentMovementTypes = new NativeArray <int>(1, Allocator.Persistent);
            NativeArray <AgentMovement> movementTypes      = new NativeArray <AgentMovement>(1, Allocator.Persistent);

            movementTypes[0] = new AgentMovement()
            {
                mass = 1f, topSpeed = 1f, turnSpeed = 1f
            };

            AgentWorld world = new AgentWorld()
            {
                scale    = 1f,
                offset   = float3.zero,
                center   = new float3(0.5f, 0.5f, 0.5f),
                rotation = quaternion.identity,
            };

            FlowFieldSeekJob job = new FlowFieldSeekJob()
            {
                movementTypes = movementTypes,
                agentMovement = agentMovementTypes,

                world          = world,
                flowField      = flowField,
                flowDirections = flowDirections,
                flowFieldSize  = new int3(1, 1, 1),

                agents    = agents,
                steering  = directions,
                behaviors = active,
            };

            JobHandle handle = job.Schedule(1, 1);

            handle.Complete();

            Assert.AreEqual(new float3(0, 1, 0), directions[0]);

            flowDirections.Dispose();
            flowField.Dispose();
            directions.Dispose();
            agents.Dispose();
            active.Dispose();
            movementTypes.Dispose();
            agentMovementTypes.Dispose();
        }
        public void AvoidsNearbyAgents()
        {
            float3 position1 = float3.zero;
            float3 position2 = new float3(0f, 1f, 0f);
            float3 max       = new float3(float.MaxValue, float.MaxValue, float.MaxValue);

            NativeMultiHashMap <int3, SpatialMapData> spatialMap = new NativeMultiHashMap <int3, SpatialMapData>(1, Allocator.Persistent);

            spatialMap.Add(int3.zero, new SpatialMapData()
            {
                position = position1
            });
            spatialMap.Add(int3.zero, new SpatialMapData()
            {
                position = position2
            });

            NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(2, Allocator.Persistent);

            agents[0] = new AgentKinematics()
            {
                position = position1, velocity = new float3(0, 0, 0)
            };
            agents[1] = new AgentKinematics()
            {
                position = position2, velocity = new float3(0, 1, 0)
            };

            NativeArray <float3>         steering = new NativeArray <float3>(2, Allocator.Persistent);
            NativeArray <AgentBehaviors> active   = new NativeArray <AgentBehaviors>(2, Allocator.Persistent);
            AgentBehaviors flags = AgentBehaviors.Avoiding;

            for (int i = 0; i < 2; i++)
            {
                active[i] = flags;
            }

            AgentWorld world = new AgentWorld()
            {
                scale    = 1f,
                offset   = float3.zero,
                center   = new float3(0.5f, 0.5f, 0.5f),
                rotation = quaternion.identity,
            };

            AvoidCollisionBehavior job = new AvoidCollisionBehavior()
            {
                avoidDistance = 1f,
                avoidRadius   = 1f,
                avoidForce    = 1f,
                maxDepth      = 100,

                world      = world,
                size       = new int3(1, 1, 1),
                spatialMap = spatialMap,
                steering   = steering,
                behaviors  = active,
                agents     = agents,
            };

            job.Schedule(2, 1).Complete();

            Assert.AreEqual(new float3(0, -1, 0), steering[0]);
            Assert.AreEqual(new float3(0, 0, 0), steering[1]);

            spatialMap.Dispose();
            steering.Dispose();
            agents.Dispose();
            active.Dispose();
        }
Esempio n. 11
0
        public void UpdatesPositionAndRotation()
        {
            Transform[] transforms = new Transform[2];
            transforms[0] = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
            transforms[1] = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
            TransformAccessArray asyncTransforms = new TransformAccessArray(transforms);

            NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(2, Allocator.Persistent);

            agents[0] = new AgentKinematics()
            {
                maxSpeed = 1f
            };
            agents[1] = new AgentKinematics()
            {
                maxSpeed = 1f
            };

            NativeArray <float3> directions = new NativeArray <float3>(2, Allocator.Persistent);

            directions[0] = Vector3.right;
            directions[1] = Vector3.left;

            NativeArray <byte> flowField = new NativeArray <byte>(1, Allocator.Persistent);

            for (int i = 0; i < 1; i++)
            {
                flowField[i] = 1;
            }

            NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(2, Allocator.Persistent);

            for (int i = 0; i < 2; i++)
            {
                active[i] = AgentBehaviors.Active;
            }

            NativeArray <int>           agentMovementTypes = new NativeArray <int>(2, Allocator.Persistent);
            NativeArray <AgentMovement> movementTypes      = new NativeArray <AgentMovement>(1, Allocator.Persistent);

            movementTypes[0] = new AgentMovement()
            {
                mass = 1f, topSpeed = 1f, turnSpeed = 1f
            };

            AgentWorld world = new AgentWorld()
            {
                scale    = 1f,
                offset   = float3.zero,
                center   = new float3(0.5f, 0.5f, 0.5f),
                rotation = quaternion.identity,
            };

            MoveAgentJob job = new MoveAgentJob()
            {
                maxForce = 1f,

                movementTypes = movementTypes,
                agentMovement = agentMovementTypes,

                agents    = agents,
                behaviors = active,
                steering  = directions,
                deltaTime = Time.deltaTime,

                world         = world,
                flowField     = flowField,
                flowFieldSize = new int3(1, 1, 1)
            };

            Vector3 position_0 = transforms[0].position;
            Vector3 position_1 = transforms[1].position;

            Quaternion rotation_0 = transforms[0].rotation;
            Quaternion rotation_1 = transforms[1].rotation;

            JobHandle handle = job.Schedule(asyncTransforms);

            handle.Complete();

            Assert.AreNotEqual(position_0, transforms[0].position);
            Assert.AreNotEqual(position_1, transforms[1].position);

            Assert.AreNotEqual(rotation_0, transforms[0].rotation);
            Assert.AreNotEqual(rotation_1, transforms[1].rotation);

            agents.Dispose();
            active.Dispose();
            flowField.Dispose();
            directions.Dispose();
            asyncTransforms.Dispose();

            agentMovementTypes.Dispose();
            movementTypes.Dispose();

            foreach (var t in transforms)
            {
                GameObject.DestroyImmediate(t.gameObject);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Schedules background jobs to move each agent in the scene by the given delta time
        /// </summary>
        protected JobHandle MoveByArchetype(int index, AgentWorld agentWorld, float dt, JobHandle dependsOn = default)
        {
            FlowFieldSeekJob seekJob = new FlowFieldSeekJob()
            {
                world         = agentWorld,
                movementTypes = m_movementTypes,
                agentMovement = m_agentMovementTypes[index],

                flowField      = m_flowFields[index],
                flowDirections = m_directions,
                flowFieldSize  = agentWorld.size,

                behaviors = m_agentBehaviors[index],
                agents    = m_agentKinematics[index],
                steering  = m_agentSteering[index],
            };
            JobHandle seekHandle = seekJob.Schedule(m_totalAgents[index], 1, dependsOn);

            AvoidCollisionBehavior avoidJob = new AvoidCollisionBehavior()
            {
                avoidForce    = avoidForce,
                avoidRadius   = avoidRadius,
                avoidDistance = avoidDistance,
                maxDepth      = maxAvoidDepth,

                world     = agentWorld,
                behaviors = m_agentBehaviors[index],
                agents    = m_agentKinematics[index],
                steering  = m_agentSteering[index],

                spatialMap = m_spatialMap,
                size       = spatialBucketSize
            };
            JobHandle avoidHandle = avoidJob.Schedule(m_totalAgents[index], 1, seekHandle);

            QueueBehavior queueJob = new QueueBehavior()
            {
                maxDepth       = maxQueueDepth,
                maxBrakeForce  = brakeForce,
                maxQueueRadius = queueRadius,
                maxQueueAhead  = queueDistance,

                world     = agentWorld,
                behaviors = m_agentBehaviors[index],
                agents    = m_agentKinematics[index],
                steering  = m_agentSteering[index],

                size       = spatialBucketSize,
                spatialMap = m_spatialMap
            };
            JobHandle queueHandle = queueJob.Schedule(m_totalAgents[index], 1, avoidHandle);

            StoppingBehavior stopJob = new StoppingBehavior()
            {
                maxBrakeForce = brakeForce,
                agents        = m_agentKinematics[index],
                steering      = m_agentSteering[index],
                behaviors     = m_agentBehaviors[index]
            };
            JobHandle stopHandle = stopJob.Schedule(m_totalAgents[index], 1, queueHandle);

            CollisionBehavior collisionJob = new CollisionBehavior()
            {
                movementConfigs = m_movementTypes,
                movement        = m_agentMovementTypes[index],
                collision       = archetypes[index].collision,
                minDistance     = minCollisionDistance,
                minForce        = minCollisionForce,
                maxDepth        = maxCollisionDepth,

                world     = agentWorld,
                behaviors = m_agentBehaviors[index],
                agents    = m_agentKinematics[index],
                steering  = m_agentSteering[index],

                spatialMap = m_spatialMap,
                size       = spatialBucketSize
            };
            JobHandle collisionHandle = collisionJob.Schedule(m_totalAgents[index], 1, stopHandle);

            GravityBehavior gravityJob = new GravityBehavior()
            {
                world     = agentWorld,
                behaviors = m_agentBehaviors[index],
                agents    = m_agentKinematics[index],
                steering  = m_agentSteering[index],

                blocks  = m_blockTypes[index],
                voxels  = world.data.voxels,
                gravity = new float3(
                    gravity.x,
                    gravity.y,
                    gravity.z
                    ),
            };
            JobHandle gravityHandle = gravityJob.Schedule(m_totalAgents[index], 1, collisionHandle);

            MoveAgentJob moveJob = new MoveAgentJob()
            {
                maxForce      = maxForce,
                movementTypes = m_movementTypes,
                agentMovement = m_agentMovementTypes[index],

                world     = agentWorld,
                behaviors = m_agentBehaviors[index],
                agents    = m_agentKinematics[index],
                steering  = m_agentSteering[index],
                deltaTime = dt,

                flowField     = m_flowFields[index],
                flowFieldSize = agentWorld.size,
            };

            return(moveJob.Schedule(m_transformAccess[index], gravityHandle));
        }