14.5. Организация трассировщика луча в приложении

true, если происходит легитимное соударение, и fal se в противном случае. Если соударение имеет место, то метод строит полную запись пересечении, в которой описываются все соударения с рассматриваемым объектом, и помещает эту запись в inter. Затем метод getFirstHitO сравнивает (первое положительное) время соударения в inter со временем в best, записи с «наилучшим соударением на данный момент». Если обнаружилось более раннее время соударения, то данные из inter копируются в best. Начальное значение best.numHits равно нулю, так что первое реальное соударение будет учтено при просмотре pObj списка объектов.

Отметим, что метод getFirstHitO перекладывает тяжесть вычисления пересечений лучей на подпрограмму hit( ), имеющуюся для каждого объекта. Для каждого типа объектов мы разработаем свой метод hit(). В целях эффективности следует использовать знание о форме базового объекта. Это является прекрасным примером использования полиморфизма для упрощения кода и увеличения его устойчивости и эффективности. Подпрограмма hit О является виртуальным методом класса GeomObj, порождающего все имеющиеся классы Shape.

Работа метода hit() данного класса состоит в том, чтобы принять луч, построить запись пересечений и загрузить в эту запись все детали пересечений луча с объектом. Ниже мы разработаем метод hit( ) для сферы и посмотрим, что в него входит.

14.5.1. Подпрограмма для вычисления пересечений луча со сферой Листинг 14.6. Метод hit() для класса Sphere

boo! Sphere:: hit(Ray &r. Intersections inter) {

Ray genRay: // need to make the generic ray // необходимо создать базовый луч

xfrmRay(genRay.invTransf.г):

double А. В. С: А - dot3D(genRay.dir, genRay.dir): В - dot3D(genRay.start, genRay.dir): С - dot3D(genRay.start, genRay.start) - 1.0:

double discrim - В * В - A * С:

if(discrim < 0.0) // ray misses // луч проходит мимо

return false:

int num = 0: // the # of hits so far // число соударений на данный момент

double discRoot - sqrt(discrim):

⇐ Предыдущая| |Следующая ⇒