Beispiel #1
0
    void FixedUpdate()
    {
        //Algorithm based on
        //http://www.cs.toronto.edu/~dt/siggraph97-course/cwr87/
        //http://www.red3d.com/cwr/boids/

        //Bird is affected by 3 base forses:
        // cohesion
        // separation + collisionAvoidance
        // alignmentForce

        var sepForce = new BoidTools.SeparationForce(sts);
        var collAvoid = new BoidTools.CollisionAvoidanceForce( sts, sepForce.Calc(sts.OptDistance) );

        //Geometric center of visible birds
        var centeroid = Vector3.zero;

        var collisionAvoidance = Vector3.zero;
        var avgSpeed = Vector3.zero;
        var neighbourCount = 0;

        //Store it as an optimization
        var direction = transform.rotation * Vector3.forward;
        var curPos = transform.position;

        foreach( var vis in Physics.OverlapSphere(curPos, sts.ViewRadius) )
        {
          var visPos = vis.transform.position;
          Boid boid;
          ITrigger trigger;

          if( (boid = vis.GetComponent<Boid>()) != null ) //Birds processing
          {
        Vector3 separationForce;

        if( !sepForce.Calc(curPos, visPos, out separationForce) )
          continue;

        collisionAvoidance += separationForce;
        ++neighbourCount;
        centeroid += visPos;
        avgSpeed += boid.velocity;
          }
          else if( (trigger = vis.GetInterface<ITrigger>()) != null )
          {
        if( GetComponent<Collider>().bounds.Intersects(vis.bounds) )
          trigger.OnTouch(this);
          }
          else //Obstacles processing
          {
        BoidTools.CollisionAvoidanceForce.Force force;
        if( collAvoid.Calc(curPos, direction, vis, out force) )
        {
          collisionAvoidance += force.dir;

          if( dbgSts.enableDrawing && dbgSts.obstaclesAvoidanceDraw )
            Drawer.DrawRay( force.pos, force.dir, dbgSts.obstaclesAvoidanceColor );
        }
          }
        }

        if( neighbourCount > 0 )
        {
          //Cohesion force. It makes united formula with BoidTools.SeparationForce
          centeroid = centeroid / neighbourCount - curPos;

          //Spherical shape of flock looks unnatural, so let's scale it along y axis
          centeroid.y *= sts.VerticalPriority;

          //Difference between current bird speed and average speed of visible birds
          avgSpeed = avgSpeed / neighbourCount - velocity;
        }

        var positionForce = (1.0f - sts.AligmentForcePart) * sts.SpeedMultipliyer * (centeroid + collisionAvoidance);
        var alignmentForce = sts.AligmentForcePart * avgSpeed / Time.deltaTime;
        var attractionForce = CalculateAttractionForce( sts, curPos, velocity );
        var totalForce = sts.TotalForceMultipliyer * ( positionForce + alignmentForce + attractionForce );

        var newVelocity = (1 - sts.Inertness) * (totalForce * Time.deltaTime) + sts.Inertness * velocity;

        velocity = CalcNewVelocity( sts.MinSpeed, velocity, newVelocity, direction );

        var rotation = CalcRotation( sts.InclineFactor, velocity, totalForce );

        if( MathTools.IsValid(rotation) )
          gameObject.transform.rotation = rotation;

        /////////////////////////////////////////////////////////////
        // Debug drawing
        /////////////////////////////////////////////////////////////
        if( dbgSts.enableDrawing )
        {
          if( dbgSts.velocityDraw )
        Drawer.DrawRay( curPos, velocity, dbgSts.velocityColor );

          if( dbgSts.positionForceDraw )
        Drawer.DrawRay( curPos, positionForce, dbgSts.positionForceColor );

          if( dbgSts.alignmentForceDraw )
        Drawer.DrawRay( curPos, alignmentForce, dbgSts.alignmentForceColor );

          if( dbgSts.cohesionForceDraw )
        Drawer.DrawRay( curPos, centeroid, dbgSts.cohesionForceColor );

          if( dbgSts.collisionsAvoidanceForceDraw )
        Drawer.DrawRay( curPos, collisionAvoidance, dbgSts.collisionsAvoidanceForceColor );

          if( dbgSts.attractionForceDraw )
        Drawer.DrawRay( curPos, attractionForce, dbgSts.attractionForceColor );

          if( dbgSts.totalForceDraw )
        Drawer.DrawRay( curPos, totalForce, dbgSts.totalForceColor );
        }
    }
Beispiel #2
0
    void FixedUpdate()
    {
        //Algorithm based on
        //http://www.cs.toronto.edu/~dt/siggraph97-course/cwr87/
        //http://www.red3d.com/cwr/boids/

        //Bird is affected by 3 base forses:
        // cohesion
        // separation + collisionAvoidance
        // alignmentForce

        var sepForce  = new BoidTools.SeparationForce(sts);
        var collAvoid = new BoidTools.CollisionAvoidanceForce(sts, sepForce.Calc(sts.OptDistance));

        //Geometric center of visible birds
        var centeroid = Vector3.zero;

        var collisionAvoidance = Vector3.zero;
        var avgSpeed           = Vector3.zero;
        var neighbourCount     = 0;

        //Store it as an optimization
        var direction = transform.rotation * Vector3.forward;
        var curPos    = transform.position;

        foreach (var vis in Physics.OverlapSphere(curPos, sts.ViewRadius))
        {
            var      visPos = vis.transform.position;
            Boid     boid;
            ITrigger trigger;

            if ((boid = vis.GetComponent <Boid>()) != null) //Birds processing
            {
                Vector3 separationForce;

                if (!sepForce.Calc(curPos, visPos, out separationForce))
                {
                    continue;
                }

                collisionAvoidance += separationForce;
                ++neighbourCount;
                centeroid += visPos;
                avgSpeed  += boid.velocity;
            }
            else if ((trigger = vis.GetInterface <ITrigger>()) != null)
            {
                if (collider.bounds.Intersects(vis.bounds))
                {
                    trigger.OnTouch(this);
                }
            }
            else //Obstacles processing
            {
                BoidTools.CollisionAvoidanceForce.Force force;
                if (collAvoid.Calc(curPos, direction, vis, out force))
                {
                    collisionAvoidance += force.dir;

                    if (dbgSts.enableDrawing && dbgSts.obstaclesAvoidanceDraw)
                    {
                        Drawer.DrawRay(force.pos, force.dir, dbgSts.obstaclesAvoidanceColor);
                    }
                }
            }
        }

        if (neighbourCount > 0)
        {
            //Cohesion force. It makes united formula with BoidTools.SeparationForce
            centeroid = centeroid / neighbourCount - curPos;

            //Spherical shape of flock looks unnatural, so let's scale it along y axis
            centeroid.y *= sts.VerticalPriority;

            //Difference between current bird speed and average speed of visible birds
            avgSpeed = avgSpeed / neighbourCount - velocity;
        }

        var positionForce   = (1.0f - sts.AligmentForcePart) * sts.SpeedMultipliyer * (centeroid + collisionAvoidance);
        var alignmentForce  = sts.AligmentForcePart * avgSpeed / Time.deltaTime;
        var attractionForce = CalculateAttractionForce(sts, curPos, velocity);
        var totalForce      = sts.TotalForceMultipliyer * (positionForce + alignmentForce + attractionForce);

        var newVelocity = (1 - sts.Inertness) * (totalForce * Time.deltaTime) + sts.Inertness * velocity;

        velocity = CalcNewVelocity(sts.MinSpeed, velocity, newVelocity, direction);

        var rotation = CalcRotation(sts.InclineFactor, velocity, totalForce);

        if (MathTools.IsValid(rotation))
        {
            gameObject.transform.rotation = rotation;
        }

        /////////////////////////////////////////////////////////////
        // Debug drawing
        /////////////////////////////////////////////////////////////
        if (dbgSts.enableDrawing)
        {
            if (dbgSts.velocityDraw)
            {
                Drawer.DrawRay(curPos, velocity, dbgSts.velocityColor);
            }

            if (dbgSts.positionForceDraw)
            {
                Drawer.DrawRay(curPos, positionForce, dbgSts.positionForceColor);
            }

            if (dbgSts.alignmentForceDraw)
            {
                Drawer.DrawRay(curPos, alignmentForce, dbgSts.alignmentForceColor);
            }

            if (dbgSts.cohesionForceDraw)
            {
                Drawer.DrawRay(curPos, centeroid, dbgSts.cohesionForceColor);
            }

            if (dbgSts.collisionsAvoidanceForceDraw)
            {
                Drawer.DrawRay(curPos, collisionAvoidance, dbgSts.collisionsAvoidanceForceColor);
            }

            if (dbgSts.attractionForceDraw)
            {
                Drawer.DrawRay(curPos, attractionForce, dbgSts.attractionForceColor);
            }

            if (dbgSts.totalForceDraw)
            {
                Drawer.DrawRay(curPos, totalForce, dbgSts.totalForceColor);
            }
        }
    }