Множество простых игровых 3D движков используют список 3D моделей при рендеринге каждого фрейма (кадра). В этих простых движках надо создать 3D модель (или загрузить с диска) и затем вставить ее в список моделей для рендеринга. Модель не видима для рендеринга до тех пор, пока не вставлена в этот список.
Panda3D немного сложнее. Вместо представления списка объектов рендеру она представляет дерево объектов. Объект не видим рендеру пока он не вставлен в дерево.
Дерево состоит из объектов класса PandaNode. Это основной суперкласс для всех остальных классов:ModelNode, GeomNode, LightNode и т.д. В этом мануале мы будем обращаться к объектам как к простым узлам. Корневой (root) узел дерева это узел называемый рендер (render). (Примечание: могут быть дополнительные корневые узлы для специального назначения, как например render2d для 2D объектов)
Дерево таких объектов в Panda3D называется граф сцены (scene graph).
Что надо знать об иерархии графа сцены.
Вот наиболее важные вещи, которые надо знать об иерархической структуре графа сцены:
1. Вы должны контролировать, где находится и где появится ваш объект. Когда вы вставляете объект в дерево, вы указываете куда его вставить. Вы можете перемещаться по дереву. Вы можете создать как очень "ветвистое" дерево там и очень простое.
2. Положение объектов указывается относительно их родительских узлов в дереве. Например, если у вас есть модель шляпы, вам может понадобиться указать что она всегда находится на пять юнитов над 3D моделью головы. Вставляйте шляпу как дочерний узел головы и устанавливайте положение шляпы в (0,0,5).
3. Когда модели выстроены в дерево, любые атрибуты рендеринга, которые вы присвоили узлу будут распостранятся на его дочерние элементы-узлы. Например, если вы укажите что указанный узел надо отображать в тумане, то его дочерние узлы также будут отображены в тумане пока вы отдельно вручную не измените это на дочернем узле.
4. Panda3D создает границы-боксы для каждого узла в дереве. Хорошо организованная иерархия может значительно увеличить скорость работы игры и избежать ошибок. Если границы узла дерева не пересекаются с другими, то нет нужды проверять это у его дочерних элементов.
Новички обычно создают свои деревья полностью плоскими - все вставляется прямо за узлом рендера. Это нормально для начального изучения. Когда-нибудь у вас появится причина чтобы добавить немного больше глубины вашей иерархии. Однако не стоит этим злоупотреблять, если для этого нет достаточных причин.
NodePaths
Есть класс-помощник NodePath - это очень маленький объект, содержащий указатель-ссылку на узел и некоторую административную информацию. Сейчас вы можете игнорировать эту информацию, она будет объяснена позже в мануале. Проектировщики задумывали NodePath как обработчик для узла. Любые функции, которые создают узел возвращают NodePath, который ссылается на новый узел.
NodePath не просто указатель-ссылка на узел; он "обрабатывает" узел. Концептуально различий нет. Однако есть определенные функции API, которые ожидают, что вы передадите им NodePath, а есть другие функции, которым надо представлять указатель на узел. В этом и есть небольшое отличие и вы должны его запомнить.
Вы можете преобразовать NodePath в обычный указатель в любое время с помощью nodePath.node(). Однако нет никакого однозначного способа для обратного преобразования. Это важно: иногда вам нужен будет NodePath, а не указатель. Когда вы передаете параметры, следует по-возможности использовать NodePath, а не обычные указатели. В вызываемой функции всегда можно преобразовать NodePath, если понадобится.
Методы NodePath и методы узлов (Node).
Есть множество методов, которые используют NodePath, которые можно применять к узлам любого типа. Специальные типы узлов, такие как LODNodes и камеры Cameras (например) представляют дополнительные методы, которые доступны только для узлов этого типа, которые можно использовать только с узлами этого типа. Вот несколько примеров:
# NODEPATH METHODS:
myNodePath.setPos(x,y,z)
myNodePath.setColor(banana)
# LODNODE METHODS:
myNodePath.node().addSwitch(1000, 100)
myNodePath.node().setCenter(Point3(0, 5, 0))
# CAMERA NODE METHODS:
myNodePath.node().setLens(PerspectiveLens())
myNodePath.node().getCameraMask()
Всегда помните: когда вы вызываете методы NodePath, вы на самом деле исполняете операцию над узлом, на который ссылается NodePath.
В примере выше мы вызываем метод узла сначала конвертируя NodePath в узел, а затем уже вызываем метод узла. Это рекомендуемый стиль.
Комментариев нет:
Отправить комментарий