Как выровнять объект по пути - PullRequest
2 голосов
/ 19 декабря 2010

Я анимирую объект по сплайновому пути в OpenGL. Я использую некоторый код, который я нашел для генерации сплайна. К сожалению, я еще не понимаю механику этого. Я хочу, чтобы мой объект выровнялся так, чтобы он соответствовал тангенсу пути, чтобы он выглядел так, как будто он следует пути.

Два вопроса.
Как мне найти вектор, касающийся пути в данной точке? Во-вторых, если этот вектор и вектор направлены вверх, как повернуть объект для выравнивания?

Вот мой сплайн-код.

public Spline(Vector Path[])
{
    ControlPoints = Path;

    // Flatten out the control points array.
    int len = ControlPoints.length;
    float[] controlsX = new float[len];
    float[] controlsY = new float[len];
    float[] controlsZ = new float[len];
    for (int i = 0; i < len; ++i)
    {
        controlsX[i] = ControlPoints[i].x;
        controlsY[i] = ControlPoints[i].y;
        controlsZ[i] = ControlPoints[i].z;
   }

    // Calculate the gamma values just once.
    final int n = ControlPoints.length - 1;
    float[] gamma = new float[n + 1];
    gamma[0] = 1.0f / 2.0f;
    for (int i = 1; i < n; ++i) gamma[i] = 1 / (4 - gamma[i - 1]);
    gamma[n] = 1 / (2 - gamma[n - 1]);

    // Calculate the cubic segments.
    cubicX = calcNaturalCubic(n, controlsX, gamma);
    cubicY = calcNaturalCubic(n, controlsY, gamma);
    cubicZ = calcNaturalCubic(n, controlsZ, gamma);
}

private Cubic[] calcNaturalCubic(int n, float[] x, float[] gamma)
{
    float[] delta = new float[n + 1];
    delta[0] = 3 * (x[1] - x[0]) * gamma[0];
    for (int i = 1; i < n; ++i)
    {
        delta[i] = (3 * (x[i + 1] - x[i - 1]) - delta[i - 1]) * gamma[i];
    }
    delta[n] = (3 * (x[n] - x[n - 1])-delta[n - 1]) * gamma[n];

    float[] D = new float[n + 1];
    D[n] = delta[n];
    for (int i = n - 1; i >= 0; --i)
    {
        D[i] = delta[i] - gamma[i] * D[i + 1];
    }

    // Calculate the cubic segments.
    Cubic[] C = new Cubic[n];
    for (int i = 0; i < n; i++) {
        final float a = x[i];
        final float b = D[i];
        final float c = 3 * (x[i + 1] - x[i]) - 2 * D[i] - D[i + 1];
        final float d = 2 * (x[i] - x[i + 1]) + D[i] + D[i + 1];
        C[i] = new Cubic(a, b, c, d);
    }
    return C;
}

final public Vector GetPoint(float Position)
{
    if(Position >= 1) { return ControlPoints[ControlPoints.length - 1]; }
    float position = Position * cubicX.length;
    int splineIndex = (int)Math.floor(position);
    float splinePosition = position - splineIndex;
    return new Vector(cubicX[splineIndex].eval(splinePosition), cubicY[splineIndex].eval(splinePosition), cubicZ[splineIndex].eval(splinePosition));
}

1 Ответ

0 голосов
/ 20 декабря 2010

Первый вопрос:
Если вы отслеживаете предыдущую позицию вашего объекта, а также новую позицию, вы можете узнать направление взгляда, не находя касательной сплайна, например, так:

facing = newPosition - previousPosition

Второй вопрос:
Вы можете использовать описанные здесь ответы для поворота объекта в определенном направлении: Какой самый простой способ выровнять ось Z с вектором?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...