Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="forceToApply">basic force</param>
        /// <param name="basicVelocity">basic Velocity</param>
        /// <returns></returns>
        protected TSVector ApplyForce(FP deltaTime, TSVector desiredDirection, TSVector basicVelocity, TSVector pos, List <IAgentBehaviour> agents, bool bUsePreForce, bool bSkipStatic)//
        {
            // isTminStaticAgent = false;
            int      count         = agents.Count;
            TSVector boidsVelocity = TSVector.zero;
            //TSVector forceToApply = TSVector.zero;
            TSVector forceToApply   = TSVector.zero;
            TSVector avoidObstacle  = TSVector.zero;
            FP       mAvoidObstacle = FP.Zero;

            if (IsBoisTypeActive(EBoidsActiveType.terrainSeperation) && false)
            {
                avoidObstacle = Boids.BoidsBehaviourAvoidObstacle(pos, _behaviour.map, basicVelocity);
                //desiredDirection = (desiredDirection + dir * S_terrainSepFactor);
                //if(desiredDirection!=TSVector.zero)
                //{
                //    desiredDirection = desiredDirection.normalized;
                //}
                avoidObstacle = CustomMath.Normalize(avoidObstacle, out mAvoidObstacle);
            }
            if (desiredDirection != TSVector.zero)
            {
                desiredDirection = CustomMath.Normalize(desiredDirection);
                forceToApply    += Boids.SteerTowards(_behaviour, desiredDirection, basicVelocity);
            }
            if (mAvoidObstacle > FP.Zero)
            {
                forceToApply += Boids.SteerTowards(_behaviour, avoidObstacle, basicVelocity);
            }
            if (PathFindingManager.c_useAvoidUnit)
            {
                if (IsBoisTypeActive(EBoidsActiveType.avoidUnit))
                {
                    TSVector avoidVector = SteerForUnitAvoidance.GetDesiredSteering(_behaviour);
                    TSVector force       = TSVector.ClampMagnitude(avoidVector / deltaTime * _behaviour.baseData.invMass, _behaviour.baseData.maxForce);
                    forceToApply += force;
                }
                //else if (IsBoisTypeActive(EBoidsActiveType.collisionAvoidance))
                //{
                // //   bool isTminStaticAgent = false;
                //    forceToApply += CustomMath.TSVec2ToVec(ForceBasedAgent.computeForces(_behaviour, basicVelocity,out isTminStaticAgent));
                //}
            }

            if (_activeBoids > 0 && !bUsePreForce &&
                (IsBoisTypeActive(EBoidsActiveType.seperation) || IsBoisTypeActive(EBoidsActiveType.cohesion) ||
                 IsBoisTypeActive(EBoidsActiveType.alignment)))
            {
                // int count =(i%3== _updateStart)? this.neighbours.Count:0;//_group._thiss
                TSVector totalForce          = TSVector.zero;
                TSVector averageHeading      = TSVector.zero;
                TSVector centerOfMass        = TSVector.zero;
                int      neighboursCountSep  = 0;
                int      neighboursCountAlig = 0;
                int      neighboursCountCoh  = 0;
                FP       radius = _behaviour.colliderRadius * 4;
                FP       sepSqr = radius * radius;//
                FP       nrSqr  = _behaviour.baseData.neighbourRadiusSqr * FP.EN2 * 25;
                for (int j = 0; j < count; j++)
                {
                    IAgentBehaviour a = agents[j];// _behaviour.neighbours
                    if (IsBoisTypeActive(EBoidsActiveType.seperation))
                    {
                        Boids.BoidsBehaviourSeparation(_behaviour, a, sepSqr, ref totalForce, ref neighboursCountSep, bSkipStatic);
                    }
                    if (IsBoisTypeActive(EBoidsActiveType.alignment))
                    {
                        Boids.BoidsBehaviourAlignment(_behaviour, a, nrSqr, ref averageHeading, ref neighboursCountAlig);
                    }
                    if (IsBoisTypeActive(EBoidsActiveType.cohesion))
                    {
                        Boids.BoidsBehaviourCohesion(_behaviour, a, nrSqr, ref centerOfMass, ref neighboursCountCoh);
                    }
                    if (a.enabled && a.agent == null) //the ally neighbour has a target,
                                                      //cause this agent change type to atar type targeted to the same target
                    {
                        PathFindingAgentBehaviour agent = _behaviour as PathFindingAgentBehaviour;
                        if (agent.AgentType == EAgentType.flowFiled)
                        {
                            TSVector target         = (a as PathFindingAgentBehaviour).targetPos;
                            bool     isDefaultTaget = target == a.baseData.defaultTargetPos;
                            if (target != TSVector.MaxValue && target != TSVector.MinValue && !isDefaultTaget)
                            {
                                agent.stopMoving = false;
                                agent._hasNeighbourTargetedDefaultPos = true;
                                target.y = 0;
                                agent.SetNewTargetPos(target, true);
                            }
                            if (!isDefaultTaget)
                            {
                                agent.preVelocity = TSVector.zero;
                                forceToApply      = TSVector.zero;
                                // agent.velocity = TSVector.zero;
                                // agent.ChangeAgentType(EAgentType.astar);
                                return(forceToApply);
                            }
                        }
                    }
                }

                if (count > 0)
                {
                    TSVector sep = TSVector.zero;
                    if (totalForce != TSVector.zero)
                    {
                        //totalForce.Multiply(agent.maxForce / neighboursCount)
                        sep = totalForce * (_behaviour.baseData.maxForce) / neighboursCountSep;
                        //sep=Boids.SteerTowards(_behaviour, sep, basicVelocity);
                        //
                        FP lenSqr = sep.sqrMagnitude;
                        if (lenSqr > _behaviour.baseData.maxForceSqr)
                        {
                            FP fval = _behaviour.baseData.maxForce / TSMath.Sqrt(lenSqr);
                            sep = sep * fval;
                        }
                    }
                    TSVector avh = TSVector.zero;
                    if (averageHeading != TSVector.zero) //average heading
                    {
                        averageHeading = averageHeading / (neighboursCountAlig);
                        avh            = Boids.SteerTowards(_behaviour, CustomMath.Normalize(averageHeading), basicVelocity);
                    }
                    //average position
                    TSVector coh = TSVector.zero;
                    if (centerOfMass != TSVector.zero)// seek that position
                    {
                        centerOfMass = centerOfMass + _behaviour.position;
                        neighboursCountCoh++;
                        centerOfMass = centerOfMass / neighboursCountCoh;
                        coh          = Boids.BoidsBehaviourSeek(_behaviour, basicVelocity, centerOfMass);
                    }
                    _preBoidsForce = sep * S_seperationFactor + avh * S_alignmentFactor + coh * S_cohesionFactor;
                    forceToApply  += _preBoidsForce;
                    if (PathFindingManager.DEBUG)
                    {
#if UNITY_5_5_OR_NEWER && !MULTI_THREAD
                        if (FP.Abs(forceToApply.x) > GridMap.SCALE * 1000 || FP.Abs(forceToApply.z) > GridMap.SCALE * 1000)
                        {
                            UnityEngine.Debug.LogError("forceToApply error!");
                        }
#endif
                    }
                }
            }
            else if (bUsePreForce)
            {
                forceToApply += _preBoidsForce;
            }

            if (forceToApply != TSVector.zero)
            {
                if (TSMath.Abs(forceToApply.x) > _behaviour.baseData.maxForce ||
                    TSMath.Abs(forceToApply.z) > _behaviour.baseData.maxForce)
                //FP lengthSquared = forceToApply.sqrMagnitude;
                //if (lengthSquared > _behaviour.baseData.maxForceSqr)//&& _activeBoids!=(byte)EBoidsActiveType.seperation)
                {
                    forceToApply = forceToApply * FP.EN3;
                    forceToApply = _behaviour.baseData.maxForce * forceToApply.normalized;
                }
                return(forceToApply * _behaviour.baseData.invMass);//
            }
            return(forceToApply);
        }