internal SteeringBehaviours(MovingGameEntity movingEntity) { // _movingHelper = new MovingHelper(); _feelers = new List <Vector3>(); _actor = movingEntity; _taggedNeighbors = new List <MovingGameEntity>(); _taggedObstacles = new List <BaseGameEntity>(); }
private Vector3 Evade(MovingGameEntity pursuer) { /* Not necessary to include the check for facing direction this time */ Vector3 ToPursuer = pursuer.Position - _actor.Position; //the look-ahead time is proportional to the distance between the pursuer //and the evader; and is inversely proportional to the sum of the //agents' velocities var LookAheadTime = ToPursuer.Length() / (_actor.MaxSpeed + pursuer.MaxSpeed); //todo:provjera //now flee away from predicted future position of the pursuer return(Flee(pursuer.Position + pursuer.Velocity * LookAheadTime)); }
/// <summary> /// Prevents Overlaps with others moving entities /// </summary> public void EnforceNonPenetrationConstraint() { for (int i = _taggedNeighbors.Count - 1; i >= 0; i--) { MovingGameEntity movingEntity = _taggedNeighbors[i]; Vector3 toEntity = _actor.Position - movingEntity.Position; float distanceEntities = Vector3.Distance(_actor.Position, movingEntity.Position); float amountOfOverLap = _actor.BoundingSphere.Radius + movingEntity.BoundingSphere.Radius - distanceEntities; if (amountOfOverLap >= 0) { //move the entity a distance away equivalent to the amount of overlap. _actor.Position = _actor.Position + (toEntity / distanceEntities) * amountOfOverLap; } } }
private float TurnAroundTime(MovingGameEntity pAgent, Vector3 targetPos) { //determine the normalized vector to the target Vector3 toTarget = targetPos - pAgent.Position; toTarget.Normalize(); var dot = Vector3.Dot(pAgent.Rotation, toTarget); //change this value to get the desired behavior. The higher the max turn //rate of the vehicle, the higher this value should be. If the vehicle is //heading in the opposite direction to its target position then a value //of 0.5 means that this function will return a time of 1 second for the //vehicle to turn around. const float coefficient = 0.5f; //the dot product gives a value of 1 if the target is directly ahead and -1 //if it is directly behind. Subtracting 1 and multiplying by the negative of //the coefficient gives a positive value proportional to the rotational //displacement of the vehicle and target. return((dot - 1.0f) * -coefficient); }
private Vector3 Pursuit(MovingGameEntity evader) { //if the evader is ahead and facing the agent then we can just seek //for the evader's current position. Vector3 ToEvader = evader.Position - _actor.Position; var relativeHeading = Vector3.Dot(evader.Rotation, _actor.Rotation); if ((Vector3.Dot(ToEvader, _actor.Rotation) > 0) && (relativeHeading < -0.95)) //acos(0.95)=18 degs { return(Seek(evader.Position)); } //Not considered ahead so we predict where the evader will be. //the look-ahead time is proportional to the distance between the evader //and the pursuer; and is inversely proportional to the sum of the //agents' velocities var lookAheadTime = ToEvader.Length() / (_actor.MaxSpeed + evader.MaxSpeed); //todo:provjera lookAheadTime += TurnAroundTime(_actor, evader.Position); //todo:provjera //now seek to the predicted future position of the evader return(Seek(evader.Position + evader.Velocity * lookAheadTime)); }
/// <summary> /// Turns evade behaviour off /// </summary> /// <param name = "pursuer"></param> public void EvadeOff(MovingGameEntity pursuer) { _evadeOn = false; }
/// <summary> /// Turns evade behaviour on /// </summary> /// <param name = "pursuer">The entity witch we are evading</param> public void EvadeOn(MovingGameEntity pursuer) { _pursuer = pursuer; _evadeOn = true; }
/// <summary> /// Turns pursuit behaviour off /// </summary> /// <param name = "evader"></param> public void PursuitOff(MovingGameEntity evader) { _pursuitOn = false; }
/// <summary> /// Turns pursuit behaviour on /// </summary> /// <param name = "evader">The entity whitch we are pursuing</param> public void PursuitOn(MovingGameEntity evader) { _evader = evader; _pursuitOn = true; }