Ray genRay: // make the generic ray // создаем базовый луч

xfrmRay(genRay.i nvTransf,r); // expensive // стоит дорого

if(IrayHitsSphereExtent(genRay.genSphereExtent)) return false:

…Do expensive full testing with the generic cylinder… II выполняем дорогостоящее полное тестирование // относительно базового цилиндра }

В листинге 14.13 показано, как тестирование экстента вводится внутрь метода hit() для случая конического цилиндра. Здесь приводится тестирование сферического экстента, причем тест выполняется как в мировых, так и в базовых координатах, чтобы показать, где появляется код тестирования. (Возмож14.9. Использование экстентов но, в реальном трассировщике луча будет применен только один из этих тестов.) Для того чтобы посмотреть, соударяется ли луч со сферическим экстентом, вызывается подпрограмма rayHitsSphereExtentO, и если соударения нет, то происходит «досрочный выход» из метода hitO. В первый раз эта подпрограмма вызывается с лучом в мировых координатах и тестирование производится с экстентом worl dSphereExtent. Если луч соударяется с этим экстентом, то луч подвергается обратному преобразованию. Затем подпрограмма вызывается вторично, чтобы посмотреть, соударяется ли базовый луч с базовым сферическим экстентом. Как и прежде, если луч проходит мимо, то осуществляется досрочный выход и тест пересечения с базовым цилиндром пропускается. Если мы почувствуем, что для конического цилиндра прямоугольные экстенты будут эффективнее, чем сферические, то мы можем заменить подпрограмму rayHitsSphereExtentO на rayHitsBoxExtentO. Мы могли бы даже поместить внутрь метода hitO оба теста экстентов, хотя это вероятнее всего привело бы к ненужным потерям в скорости.

Мы должны выбирать, какие тесты включать в каждый метод hitO для различных классов форм. В ряде случаев выбор очевиден: для объектов класса Sphere нет смысла выполнять тест со сферическим экстентом в базовых координатах. (Почему?) Вы никогда не будете выполнять также тест относительно прямоугольного экстента в базовых координатах для объектов класса Cube. Для класса Plane экстентов не существует, поэтому в метод Plane :: hit О не включается никаких тестов. Для класса Square построение экстента имеет смысл, однако здесь тест на пересечение настолько прост, что тест относительно экстента не принесет никакой выгоды. Напротив, объект класса Mesh содержит большое число ограничивающих плоскостей, и тест на пересечение с ним стоит дорого, поэтому тест относительно экстента может принести значительные выгоды.


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