Вы можете сделать код намного короче и читабельнее. Например, изменить int tNear = -2147000000
к int tNear = INT_MIN
и изменить
if(t1 > t2)
{
float temp1 = t1;
t1 = t2;
t2 = temp1;
}
к
if(t1 > t2)
{
// std::swap is built-in
swap(t1, t2);
}
или лучше
// Define 'order' yourself
order(t1, t2);
и изменить
if(t1 > tNear)
{
tNear = t1;
}
к
// std::max is built in
tNear = max(tNear, t1);
Тогда один участок кода становится:
if ((ray.dir.x == 0) && (ray.start.x < Min.x) && (ray.start.x > Max.x))
{
//parallel
return false;
}
else
{
float t1 = (Min.x - ray.start.x)/ray.dir.x;
float t2 = (Max.x - ray.start.x)/ray.dir.x;
order(t1, t2);
tNear = max(tNear, t1);
tFar = max(tFar, t1);
if ((tNear > tFar) || (tFar < 0))
return false;
}
И это показывает одну проблему. tNear
и tFar
определяют интервал t
значений, в пределах которых линия пересекает куб. Каждая согласованная вами проверка (x, y и z) дополнительно ограничивает интервал. Однако код tFar = max(tFar, t1)
расширяет интервал. Измените его на tFar = min(tFar, t1)
.
Более принципиально это ограничивает вас выравненными по оси кубиками, хотя этот код может быть полезен позже как быстрый хит-тест для более сложных фигур. Во всяком случае, как только это будет работать, вы можете сделать его более общим.
Вы можете определить любой выпуклый многоугольник как множество бесконечных плоскостей с нормалями, обращенными наружу. Точка находится внутри многоугольника, если она «внутри» всех плоскостей.
Самолет разбивает пространство на две половины. Определите половину, к которой нормальные точки, как «снаружи», а другая половина - «внутри». Тогда точка находится вне плоскости, если плоское уравнение в этой точке положительно, внутри плоскости, если значение отрицательное и на плоскости, если значение равно нулю.
Чтобы проследить это, вы определяете пересечения лучей/плоскости и выбираете ближайший. Чтобы определить, находится ли эта точка внутри лица (помните, что плоскость бесконечна), вы проверяете, находится ли точка внутри всех других плоскостей. Если нет, проверьте ближайшее ближайшее пересечение и так далее.
Как только это работает, довольно легко распространить его на общие пересечения и разности форм (например, куб с полусферическим отступом на одной из граней).
Привет, Крис, я не хочу препятствовать вам размещать и получать помощь, но я думаю, вы должны выполнить некоторые проверки здравомыслия в своем коде, прежде чем задавать вопросы. Например, если пересечение ящиков не работает, тестовые ситуации вы знаете, какой будет правильный ответ. т.е. коробка с углом в (0,0,0) размера (1,1,1), пересекающаяся с лучом при (-1,0,5,0,5), движущимся вдоль (1,0,0), будет достигать отметки (0,0,5 , 0.5), такого рода вещи. Затем, когда вы приходите сюда, вы можете получить совет, а не просто использовать его в качестве службы проверки доказательств. –