Рис. 14.9. Множественные соударения с объектом, некоторые из них происходят при отрицательных значениях времени Информация о каждом соударении хранится в записи типа Hitlnfo: class Hitlnfo {
// data for each hit with a surface // данные о каждом соударении с поверхностью public:
double hitTime: // the hit time // время соударения
GeomObj* hitObject; // the object hit // объект соударения
boo! isEntering:
Введение в трассировку лучей
// is the ray entering or exiting?
// луч входит в обьект или выходит из него?
int surface: // which surface is hit? // с какой поверхностью происходит соударение?
Point3 hitPoint: // hit point // точка соударения
Vector3 hitNormal: // normal at hit point // нормаль в точке соударения
… other fields and methods … II другие поля и методы }: Запись соударений содержит несколько полей, описывающих соударение: время соударения, указатель на объект, с которым происходит соударение, информация о том, входит луч в объект при соударении или выходит из него, расположение точки соударения и нормальный вектор к поверхности в этой точке. Все эти поля будут важны для нас на различных этапах процесса трассировки луча.
Листинг 14.5. Метод getFirstHiK)
void Scene:: getFirstHit(Ray& ray. Intersections best) {
Intersection inter: // make intersection record // создаем запись пересечений
best.numHits - 0: //no hits yet // пока соударений нет
for(Geom0bj* pObj - obj: pObj !- NULL: pObj - p0bj->next) {
// test each object in the scene // проверяем каждый объект на сцене
if(!pObj->hit(ray. inter)) // does the ray hit pObj? // соударяется ли луч с объектом pObj?
continue: // miss: test the next object // соударения нет: проверяем следующий объект
if (best.numHits - 0 || // best has no hits yet // в best пока нет соударений
inter.hit[0].hitTime < best.hit[0].hitTime) best.set(inter): // copy inter into best // копируем inter в best }
}
В листинге 14.5 приведена подпрограмма getFirstHitO. Она просматривает весь список объектов (начиная с obj, указателя на первый объект в этом списке - см. класс Scene в приложении В) и проверяет, происходит ли соударение луча с каждым объектом. Для этого используется собственный метод hi t() каждого из объектов, который мы рассмотрим в следующем разделе. Каждый метод hitO возвращает