Войти
ПрограммированиеФорумГрафика

Рисование bounding box (2 стр)

Страницы: 1 2
#15
22:37, 9 авг. 2019

MrShoor
> А как ты для своего варианта делаешь проверку "точка в кубе или нет"? Или
> "пересекает луч куб или нет"?
Пока не сделал. Есть где почитать?


#16
22:41, 9 авг. 2019

eDmk
> Пока не сделал. Есть где почитать?
Точка в кубе или нет:
google Point in AABB
Пересекает луч куб или нет:
google Ray AABB intersection

#17
22:49, 9 авг. 2019

MrShoor
Просто в кубе за 3 сравнения делается или за 1 для сферы. Это я знаю.
Я думал про повернутый куб. Тут уже сложнее.

#18
22:54, 9 авг. 2019

eDmk
> Я думал про повернутый куб. Тут уже сложнее.
Если ты хранишь повернутый куб как: AABB + transform, то чтобы сделать проверку - тебе нужно применить обратный трансформ к лучу/точке. Если у тебя transform матрица сорежит только поворот + перенос, то обратный трансформ становится элементарным.

#19
(Правка: 23:01) 22:59, 9 авг. 2019

Вот если кому надо ray box intersection

struct Ray {
    float3 Origin;
    float3 Direction;
    float Min;
    float Max;
};

struct Intersection {
    float3 Position;
    float3 Normal;
    float  Near;
    float  Far;
    bool   IsValid;
};

struct AABB {
    float3 Min;
    float3 Max;
};
Intersection IntersectAABB(Ray ray, AABB aabb) {

    Intersection intersect;
    intersect.IsValid = false;
    intersect.Position = 0.0f;
    intersect.Normal = 0.0f;
    intersect.Near = 0.0f;
    intersect.Far = FLT_MAX;

    const float3 invR = rcp(ray.Direction);
    const float3 bot = invR * (aabb.Min - ray.Origin);
    const float3 top = invR * (aabb.Max - ray.Origin);
    const float3 tmin = min(top, bot);
    const float3 tmax = max(top, bot);

    const float largestMin = max(max(tmin.x, tmin.y), max(tmin.x, tmin.z));
    const float largestMax = min(min(tmax.x, tmax.y), min(tmax.x, tmax.z));

    if (largestMax < largestMin)
        return intersect;

    intersect.Near = largestMin > 0.0f ? largestMin : 0.0f;
    intersect.Far = largestMax;

    if (intersect.Near < ray.Min || intersect.Near > ray.Max)
        return intersect;

    intersect.IsValid = true;
    intersect.Position = ray.Origin + ray.Direction * intersect.Near;
    
    [unroll]
    for (int i = 0; i < 3; i++) {
        if (intersect.Position[i] <= aabb.Min[i] + M_EPSILON)
            intersect.Normal[i] = -1.0f;

        if (intersect.Position[i] >= aabb.Max[i] - M_EPSILON)
            intersect.Normal[i] = 1.0f;
    }

    return intersect;
}

   Ray transformRay = { mul(FrameBuffer.InvWorldMatrix, float4(ray.Origin, 1.0)).xyz, mul((float3x3)FrameBuffer.InvNormalMatrix, ray.Direction), 0.0, FLT_MAX};
   Intersection intersect = IntersectAABB(transformRay, desc.AABB);

#20
(Правка: 23:24) 23:22, 9 авг. 2019

eDmk
> Я думал про повернутый куб. Тут уже сложнее.
Трансформируешь точку или луч инверсионной матрицей повернутого куба и пересекаешь как с обычным неповернутым aabb.

upd. выше тоже самое уже написали.

Страницы: 1 2
ПрограммированиеФорумГрафика