코드를 더 짧고 가독성있게 만들 수 있습니다. 예를 들어,
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;
}
을 변경
int tNear = INT_MIN
에
int tNear = -2147000000
을 변경하고 변경
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;
}
을 그리고 이것은 하나의 문제를 보여준다 :
// std::max is built in
tNear = max(tNear, t1);
그런 다음 코드의 한 부분이된다. tNear
및 tFar
은 라인이 큐브와 교차하는 간격 인 t
값을 정의합니다. 테스트하는 각 좌표 (x, y 및 z)는 간격을 더 제한합니다. 그러나 코드 tFar = max(tFar, t1)
이 간격을 확장하고 있습니다. 그것을 tFar = min(tFar, t1)
으로 변경하십시오.
근본적으로, 이것은 축 정렬 입방 형으로 제한됩니다. 그러나이 코드는 나중에 더 복잡한 모양에 대한 빠른 히트 테스트로 유용 할 수 있습니다. 어쨌든, 일단 이것이 작동하면 좀 더 일반적인 것으로 만들 수 있습니다.
모든 볼록 다각형을 법선이 바깥 쪽을 향하게하여 무한 평면 세트로 정의 할 수 있습니다. 모든면의 "내부"에있는 점은 다각형 내부에 있습니다.
평면은 공간을 두 개의 절반으로 나눕니다. 정상 점이 "외부"이고 다른 반쪽이 "내부"인 반을 정의하십시오. 그러면 그 점에서 평면 방정식이 양수이면 점이 평면 외부에 있고, 값이 음수이면 평면 내부에, 값이 0 인 경우 평면에 점이 있습니다.
이것을 광선 추적하려면 광선/평면 교차를 결정하고 가장 가까운 것을 선택하십시오. 포인트가 얼굴 안에 있는지 확인하려면 (비행기가 무한하다는 것을 기억하십시오) 포인트가 다른 모든 비행기 안에 있는지 확인하십시오. 그렇지 않은 경우 가장 가까운 다음 교차로를 테스트하는 등의 작업을 수행합니다.
일단 이것이 작동하면 일반 교차로 및 모양의 차이 (예 :면 중 하나에서 반구형 들여 쓰기가있는 입방체)로이를 쉽게 확장 할 수 있습니다.
안녕하세요 Chris는 게시자가 도움을 요청하지 않도록하고 싶지 않지만 질문하기 전에 코드에 대한 온 전성 검사를 수행해야한다고 생각합니다. 예를 들어 상자 교차가 작동하지 않는 경우 테스트 상황에서 정답이 무엇인지 알 수 있습니다. 즉, (1,0,0)을 따라 이동하는 (1,0,0,0.5)의 광선과 교차하는 크기 (1,1,1)의 (0,0,0)에있는 모서리가있는 상자는 (0,0.5) , 0.5), 이런 종류의 일. 그런 다음 여기에 올 때 단지 증거 읽기 서비스로 사용하지 않고 조언을 얻을 수 있습니다. –