Esempio n. 1
0
        /// <summary>
        /// Calculates the required force to separate the two agents
        /// </summary>
        public void ApplyCollisionForce(int i, SpatialMapData target)
        {
            // calculate the distance bewteen the two agents
            float3 direction = agents[i].position - target.position;

            direction.y = 0; // clamp the y-axis to create a 2D force

            // exit if the agents are within the minimum distance
            // this helps prevent excessive collision forces
            float distance = math.length(direction);

            if (distance <= minDistance)
            {
                return;
            }

            // calculate the mass difference between the two agents
            float mass      = movementConfigs[movement[i]].mass;
            float massRatio = target.mass / mass;

            // calcuate the collision force for this agent and skip
            // if it does not exceed the minForce, creating a deadband
            float combinedRadius = collision.radius + target.radius;
            float penetration    = combinedRadius / distance;
            float forceScale     = penetration * massRatio;

            if (forceScale <= minForce)
            {
                return;
            }

            // apply the collision to this agents steering force
            direction    = math.normalizesafe(direction, float3.zero);
            steering[i] += direction * forceScale;
        }
Esempio n. 2
0
        public void Execute(int i, TransformAccess transform)
        {
            AgentBehaviors mask = AgentBehaviors.Active;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            float mass   = movementConfigs[movement[i]].mass;
            int3  grid   = GridPosition(transform.position);
            int3  bucket = new int3(
                grid.x / size.x,
                grid.y / size.y,
                grid.z / size.z
                );

            Agents.AgentKinematics agent = agents[i];
            agent.position = transform.position;
            agents[i]      = agent;

            SpatialMapData data = new SpatialMapData();

            data.position = transform.position;
            data.height   = collision.height;
            data.radius   = collision.radius;
            data.mass     = mass;

            spatialMap.Add(bucket, data);
        }
Esempio n. 3
0
        /// <summary>
        /// Checks if there is a collision between two agents
        /// using their collision radius and height
        /// </summary>
        public bool Collision(AgentKinematics self, SpatialMapData target)
        {
            // skip if the target agent is the same as the source agent
            if (self.position.Equals(target.position))
            {
                return(false);
            }

            // find the distance between the two agents
            // clamp y-axis to test 2D circle intersection

            float3 delta  = self.position - target.position;
            float  deltaY = delta.y;

            delta.y = 0;

            // use the combined radius of the two agents to
            // test if their collision radius intersect

            float distance        = math.length(delta);
            float radius          = collision.radius + target.radius;
            bool  intersectCircle = distance <= radius;

            // compare the two agent's height and offset for collisions
            // use delta Y to test that the agents are colliding with each other

            bool intersectHeight;

            if (deltaY >= 0) // target is above the agent
            {
                intersectHeight = deltaY - collision.height < 0;
            }
            else // target is below the agent
            {
                intersectHeight = -deltaY - target.height < 0;
            }

            // agents must be intersecting the 2D circle
            // and height to be considered a collision
            return(intersectCircle && intersectHeight);
        }