Преобразование однострочного векторного (массива) присвоения в классический массив, перевод C ++ в C - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь преобразовать алгоритм Moller Trumbore, как видно здесь .

Цель этого кода - найти точку пересечения вектора с треугольником, и это также вернуть точку текстуры U и V.

Но я застрял с этой строкой:

Vector uvHit = uvVectors[0] * u + uvVectors[1] * v + uvVectors[2] * (1 - u - v);

Кого также можно увидеть как:

*uvHit = u * uvVectors[0] + v * uvVectors[1] + (1 - u - v) * uvVectors[2];

вот мой код:

typedef float vec_t;
typedef vec_t vec3_t[3];

qboolean GetIntersection(vec3_t rayOrigin, vec3_t rayDirection, float hitDistance, vec3_t *uv)
{
vec3_t pvec;
float det = 0.0f;
vec3_t tvec;
vec3_t qvec;
vec3_t uvHit;

// begin calculating determinant - also used to calculate U parameter
CrossProduct(rayDirection, edge2, pvec);

// if determinant is near zero, ray lies in plane of triangle
det = DotProduct(edge1, pvec);

const float EPSILON = 0.000001f;

if ((det > -EPSILON) && (det < EPSILON))
    return qfalse;

float inv_det = 1.0f / det;

// calculate distance from vertex 0 to ray origin
tvec = rayOrigin - verts[0];

// calculate U parameter and test bounds
u = DotProduct(tvec, pvec) * inv_det;


if ((u < 0.0f) || (u > 1.0f))
    return false;

// prepare to test V parameter
CrossProduct(tvec, edge1, qvec);

// calculate V parameter and test bounds
float v = DotProduct(rayDirection, qvec) * inv_det;

if ((v < 0.0f) || (u + v > 1.0f))
    return false;

Vector uvHit = uvVectors[0] * u + uvVectors[1] * v + uvVectors[2] * (1 - u - v);// This is the line I don't understand 

uv[0] = uvHit[0];
uv[1] = uvHit[1];
uv[2] = 0;

// calculate t, ray intersects triangle
hitDistance = DotProduct(edge2, qvec) * inv_det;

// only allow intersections in the forward ray direction
return hitDistance >= 0.0f;
}

1 Ответ

0 голосов
/ 28 апреля 2020

Вы вычисляете точку в треугольнике из ее вершин, представленных как Vector uvVectors[3], и ее барицентри c координаты u, v и w == 1 - u - v.

В коде C ++ вы ' Как показано, Vector, вероятно, является классом или структурой. Оператор умножения * был перегружен, в данном случае для умножения вектора на скаляр:

Vector uvHit = uvVectors[0] * u + uvVectors[1] * v + uvVectors[2] * (1 - u - v);

В C вы не можете перегрузить операторы, поэтому вы должны написать это Расчет явно. Давайте предположим, что ваш вектор является вектором в трехмерном пространстве:

typedef struct Vector Vector;

struct Vector {
    double x, y, z;
};

Тогда ваше умножение выглядит так, когда вы инициализируете вектор:

Vector uvHit = {
    uvVectors[0].x * u + uvVectors[1].x * v + uvVectors[2].x * (1 - u - v),
    uvVectors[0].y * u + uvVectors[1].y * v + uvVectors[2].y * (1 - u - v),
    uvVectors[0].z * u + uvVectors[1].z * v + uvVectors[2].z * (1 - u - v)
};

или так, когда вы присваиваете его значения позже:

uvHit.x = uvVectors[0].x * u + uvVectors[1].x * v + uvVectors[2].x * (1 - u - v);
uvHit.y = uvVectors[0].y * u + uvVectors[1].y * v + uvVectors[2].y * (1 - u - v);
uvHit.z = uvVectors[0].z * u + uvVectors[1].z * v + uvVectors[2].z * (1 - u - v);
...