public int AddAgent(GameObject agentGameObject)
    {
        rvoGameObject.Add(agentGameObject);
        agentPosition.Add(RVOWithUnity.Vec3ToVec2(agentGameObject.transform.position));
        RVOAgent rvoAgent = agentGameObject.GetComponent <RVOAgent>();

        if (rvoAgent.isPlayer == false)
        {
            return(Simulator.Instance.addAgent(RVOWithUnity.Vec3ToVec2(agentGameObject.transform.position)));
        }
        else
        {
            return(Simulator.Instance.addAgent(RVOWithUnity.Vec3ToVec2(agentGameObject.transform.position),
                                               neighborDist,
                                               maxNeighbor,
                                               rvoAgent.timeHorizon,
                                               timeHorizonObst,
                                               rvoAgent.radius,
                                               rvoAgent.maxSpeed,
                                               new RVO.Vector2(0.0f, 0.0f),
                                               rvoAgent.acceleration,
                                               rvoAgent.angularSpeed,
                                               rvoAgent.minSpeedToTurn

                                               ));
        }
    }
    void Awake()
    {
        BoxCollider[]     boxColliders = GameObject.Find("Ground").GetComponentsInChildren <BoxCollider>();
        CapsuleCollider[] cylinders    = GameObject.Find("Ground").GetComponentsInChildren <CapsuleCollider>();
        for (int i = 0; i < boxColliders.Length; i++)
        {
            Vector2         position  = RVOWithUnity.Vec3ToVec2(boxColliders[i].transform.position);
            float           angle     = boxColliders[i].transform.rotation.eulerAngles.y * Mathf.Deg2Rad;
            float           sizeX     = boxColliders[i].transform.lossyScale.x * 0.5f;
            float           sizeZ     = boxColliders[i].transform.lossyScale.z * 0.5f;
            Vector2         right     = new Vector2(Mathf.Sin(angle), Mathf.Cos(angle));
            Vector2         left      = new Vector2(-Mathf.Sin(angle), -Mathf.Cos(angle));
            Vector2         up        = new Vector2(-Mathf.Cos(angle), Mathf.Sin(angle));
            Vector2         down      = new Vector2(Mathf.Cos(angle), -Mathf.Sin(angle));
            Vector2         rightUp   = position + right * sizeZ + up * sizeX;
            Vector2         rightDown = position + right * sizeZ + down * sizeX;
            Vector2         leftUp    = position + left * sizeZ + up * sizeX;
            Vector2         leftDown  = position + left * sizeZ + down * sizeX;
            IList <Vector2> obstacle  = new List <Vector2>();
            obstacle.Add(rightUp);
            obstacle.Add(leftUp);
            obstacle.Add(leftDown);
            obstacle.Add(rightDown);

            /* Debug.Log(boxColliders[i].gameObject.name.ToString() + "::" +
             *  rightUp.ToString() + " " +
             *  leftUp.ToString() + " " +
             *  leftDown.ToString() + " " +
             *  rightDown.ToString()
             *   ); */
            Simulator.Instance.addObstacle(obstacle);
        }
        for (int i = 0; i < cylinders.Length; i++)
        {
            float           size     = cylinders[i].transform.lossyScale.x * 0.5413f;
            Vector2         position = RVOWithUnity.Vec3ToVec2(cylinders[i].transform.position);
            float           angle    = 360.0f / 8.0f;
            float           nowAngle = 360.0f - angle / 2.0f;
            IList <Vector2> obstacle = new List <Vector2>();
            //Debug.Log(cylinders[i].gameObject.name.ToString() + "::");
            for (int j = 0; j < 8; j++)
            {
                float   nowAngleRad = nowAngle * Mathf.Deg2Rad;
                Vector2 point       = new Vector2(Mathf.Sin(nowAngleRad), Mathf.Cos(nowAngleRad));
                point = position + point * size;
                obstacle.Add(point);
                nowAngle -= angle;
                //Debug.Log(point);
            }
            Simulator.Instance.addObstacle(obstacle);
        }
    }
    void FixedUpdate()
    {
        int agentAmount = Simulator.Instance.getNumAgents();

        for (int i = 0; i < agentAmount; i++)
        {
            Vector2  agentVec2    = Simulator.Instance.getAgentPosition(i);
            Vector2  station      = rvoGameObject[i].GetComponent <RVOAgent>().GetStation();
            RVOAgent agent        = rvoGameObject[i].GetComponent <RVOAgent>();
            Vector2  prefVelocity = RVOWithUnity.CalcPrefVelocity(agentVec2, station, agent);
            Simulator.Instance.setAgentPrefVelocity(i, prefVelocity);
        }
        Simulator.Instance.doStep();
    }
 public Vector2 GetStation()
 {
     return(RVOWithUnity.Vec3ToVec2(station));
 }
    void Update()
    {
        if (isOk && agentIndex != -1)
        {
            /* dist */
            transform.position = RVOWithUnity.Vec2ToVec3(Simulator.Instance.getAgentPosition(agentIndex));
            /* turn */
            if (RVOMath.abs(Simulator.Instance.getAgentVelocity(agentIndex)) > 0.0f)
            {
                Vector3 direction = RVOWithUnity.Vec2ToVec3(Simulator.Instance.getAgentVelocity(agentIndex));
                float   angle     = Vector3.Angle(Vector3.right, direction);
                if (Vector3.Cross(Vector3.right, direction).y < 0)
                {
                    angle = 360 - angle;
                }
                transform.rotation = Quaternion.Euler(new Vector3(transform.rotation.x, angle, transform.rotation.z));
            }

            if (!isStop)
            {
                /* Velocity */
                velocity     = Simulator.Instance.getAgentVelocity(agentIndex);
                velocityVec3 = RVOWithUnity.Vec2ToVec3(velocity);
                speed        = RVOMath.abs(velocity);
                /* Update Station */
                station = pathNodes[nowNode];
                Vector2 stationVector2      = RVOWithUnity.Vec3ToVec2(station);
                Vector2 transformVector2    = RVOWithUnity.Vec3ToVec2(transform.position);
                Vector2 distVector2         = stationVector2 - transformVector2;
                Vector2 lastStationVector2  = RVOWithUnity.Vec3ToVec2(pathNodes[nowNode - 1]);
                Vector2 lastToNowNormalize  = RVOMath.normalize(stationVector2 - lastStationVector2);
                Vector2 verticalDistVector2 = new Vector2(-lastToNowNormalize.y_, lastToNowNormalize.x_);

                //turnDist = (speed / angularSpeed) / changeStation;
                if (RVOWithUnity.isTwoSide(verticalDistVector2, distVector2, lastToNowNormalize))
                {
                    nowNode++;
                    slowStationNum = Mathf.Max(0, slowStationNum - 1);
                    //Debug.Log(RVOWithUnity.Vec3ToVec2(pathNodes[nowNode]));
                    if (nowNode > pathNodes.Count - 1)
                    {
                        isStop    = true;
                        prefSpeed = 0.0f;
                    }
                    else
                    {
                        station = pathNodes[nowNode];
                    }
                    if (slowStationNum == 0)
                    {
                        prefSpeed = maxSpeed;
                    }
                }
                else
                {
                    float slowDist = Mathf.Abs(speed * speed - minSpeedToTurn * minSpeedToTurn) / (acceleration * slowStation * 2);
                    if (RVOMath.abs(distVector2) >= slowDist && slowStationNum == 0)
                    {
                        prefSpeed = maxSpeed;
                    }
                    if (RVOMath.abs(distVector2) < slowDist)
                    {
                        /* Calc the slowScale */
                        if (nowNode + 1 > pathNodes.Count - 1)
                        {
                            prefSpeed = minSpeedToTurn;
                            turnDist  = 0.1f;
                        }
                        else
                        {
                            int     nextTurnNode  = nowNode + 1;
                            Vector2 nextStation   = RVOWithUnity.Vec3ToVec2(pathNodes[nextTurnNode]);
                            Vector2 lastStation   = stationVector2;
                            Vector2 nextDirection = nextStation - lastStation;
                            float   turnAngleDist = Vector3.Angle(velocityVec3, RVOWithUnity.Vec2ToVec3(nextDirection));
                            if (nowNode + 1 <= pathNodes.Count - 1 && slowStationNum == 0)
                            {
                                slowStationNum++;
                                float turnAngle = turnAngleDist;
                                //if (gameObject.name == "boat")
                                //  Debug.Log(lastStation + "/|/" + nextStation  + "/|/" + speed * ignoreStepFactor);
                                while (RVOMath.abs(nextDirection) < speed * ignoreStepFactor && nextTurnNode + 1 <= pathNodes.Count - 1)
                                {
                                    nextTurnNode++;
                                    slowStationNum++;
                                    lastStation = nextStation;
                                    nextStation = RVOWithUnity.Vec3ToVec2(pathNodes[nextTurnNode]);
                                    Vector2 lastDirection = nextDirection;
                                    nextDirection = nextStation - lastStation;
                                    //Debug.Log(nextStation + " " + lastStation);
                                    turnAngle += Vector3.Angle(RVOWithUnity.Vec2ToVec3(lastDirection), RVOWithUnity.Vec2ToVec3(nextDirection));
                                }
                                prefSpeed = minSpeedToTurn + (maxSpeed - minSpeedToTurn) * Mathf.Max(turningFactor - turnAngle, turningFactor / 10.0f) / turningFactor;
                            }
                            turnDist = Mathf.Tan(turnAngleDist * Mathf.Deg2Rad / 2) * (prefSpeed * prefSpeed / angularSpeed) / 200.0f;
                        }
                    }
                    if (RVOMath.abs(distVector2) < turnDist)
                    {
                        nowNode++;
                        slowStationNum = Mathf.Max(0, slowStationNum - 1);
                        if (nowNode > pathNodes.Count - 1)
                        {
                            isStop    = true;
                            prefSpeed = 0.0f;
                        }
                        else
                        {
                            station = pathNodes[nowNode];
                        }
                    }
                }
            }
        }
    }