OrcaLine getOrcaLine(MotionModelSwedish buddy, float time, float dt)
    {
        Vector3 relPos     = buddy.getPosition() - getPosition();
        Vector3 relVel     = getVelocity() - buddy.getVelocity();
        float   combRadius = buddy.getRadius() + getRadius();

        OrcaLine orcaline = new OrcaLine();
        Vector3  u;

        Vector3 w           = relVel - (relPos / time);
        float   decBoundary = Vector3.Dot(w, relPos);

        if (relPos.sqrMagnitude > Mathf.Pow(combRadius, 2))
        {
            if (!(decBoundary < 0.0f && Mathf.Pow(decBoundary, 2) > Mathf.Pow(combRadius, 2) * w.sqrMagnitude))
            {
                // Legs
                float distance = Mathf.Sqrt(relPos.sqrMagnitude - Mathf.Pow(combRadius, 2));

                if (Vector3.Cross(relPos, w).y < 0.0f)
                {
                    orcaline.direction = new Vector3(relPos.x * distance - relPos.z * combRadius, 0.0f, relPos.x * combRadius + relPos.z * distance) / relPos.sqrMagnitude;
                }
                else
                {
                    orcaline.direction = -new Vector3(relPos.x * distance + relPos.z * combRadius, 0.0f, -relPos.x * combRadius + relPos.z * distance) / relPos.sqrMagnitude;
                }
                float uLen = Vector3.Dot(relVel, orcaline.direction);
                u = uLen * orcaline.direction - relVel;
            }
            else
            {
                Vector3 wNorm = w.normalized;
                orcaline.direction = new Vector3(wNorm.z, 0.0f, -wNorm.x);
                u = ((combRadius / time) - w.magnitude) * wNorm;
            }
        }

        else
        {
            w = relVel - (relPos / dt);
            Vector3 wNorm = w.normalized;
            orcaline.direction = new Vector3(wNorm.z, 0.0f, -wNorm.x);
            u = ((combRadius / dt) - w.magnitude) * wNorm;
        }
        orcaline.point = getVelocity() + 0.5f * u;

        //Debug.DrawLine(getPosition() + orcaline.point - (Vector3.Cross(Vector3.up, orcaline.direction)).normalized * vMax, getPosition() + orcaline.point + (Vector3.Cross(Vector3.up, orcaline.direction)).normalized * vMax, Color.blue, Time.deltaTime);
        //Debug.DrawLine(getPosition() + orcaline.point, getPosition() + orcaline.point + orcaline.direction, Color.blue, Time.deltaTime);

        return(orcaline);
    }
Exemple #2
0
    // Use this for initialization
    public static void linearProgram3(List <OrcaLine> lines, int numObstLines, int beginLine, float radius, ref Vector3 result)
    {
        float RVO_EPSILON = 0.00001f;
        float distance    = 0.0f;

        for (int i = beginLine; i < lines.Count; ++i)
        {
            if (Vector3.Cross(lines[i].direction, lines[i].point - result).y < distance)
            {
                /* Result does not satisfy constraint of line i. */
                List <OrcaLine> projLines = new List <OrcaLine>();
                for (int ii = 0; ii < numObstLines; ++ii)
                {
                    projLines.Add(lines[ii]);
                }

                for (int j = numObstLines; j < i; ++j)
                {
                    OrcaLine line = new OrcaLine();

                    float determinant = -Vector3.Cross(lines[i].direction, lines[j].direction).y;

                    if (Mathf.Abs(determinant) <= RVO_EPSILON)
                    {
                        /* Line i and line j are parallel. */
                        if (Vector3.Dot(lines[i].direction, lines[j].direction) > 0.0f)
                        {
                            /* Line i and line j point in the same direction. */
                            continue;
                        }
                        else
                        {
                            /* Line i and line j point in opposite direction. */
                            line.point = 0.5f * (lines[i].point + lines[j].point);
                        }
                    }
                    else
                    {
                        line.point = lines[i].point + (-Vector3.Cross(lines[j].direction, lines[i].point - lines[j].point).y / determinant) * lines[i].direction;
                    }

                    line.direction = (lines[j].direction - lines[i].direction).normalized;
                    projLines.Add(line);
                }

                Vector2 tempResult = result;
                if (false)//linearProgram2(projLines, radius, new Vector2(-lines[i].direction.y(), lines[i].direction.x()), true, ref result) < projLines.Count)
                {
                    /*
                     * This should in principle not happen. The result is by
                     * definition already in the feasible region of this
                     * linear program. If it fails, it is due to small
                     * floating point error, and the current result is kept.
                     */
                    result = tempResult;
                }

                distance = -Vector3.Cross(lines[i].direction, lines[i].point - result).y;
            }
        }
    }