Blender по-русски
Panda3D по-русски

суббота, 24 января 2009 г.

Управление графом сцены

Графы сцены по-умолчанию

По-умолчанию автоматически создается два различных графа сцены, когда вы стартуете Panda3D. Эти графы имеют каждый свой корневой узел — render и render2d.
Чаще всего вы используете render — это вершина отдельной 3D сцены. Когда вы помещаете объект в игровой мир вам нужно сделать его потомком render (или другого узла, который все равно имеет своим предком render).
Вы будете использовать render2d для создания 2D элементов интерфейса (GUI), таких как текст или кнопки, которые вы захотите отображать на экране, например заголовок. Все что размещено в дереве render2d будет отрисовываться поверх 3D сцены, так как если бы рисовалось прямо на стекле экрана.
Координатная система render2d устанавливается так, что совпадает с вводом с мыши, нижний левый угол экран имеет координаты (-1,0,-1) а верхний правый (1,0,1). Так как это квадратная система координат, а экран обычно не квадратный, объекты прикрепленные к render2d могут отображаться растянутыми. По этой причине Panda3D также определяет дочерний узел для render2d, который называется aspect2d, который применяет масштабирование для корректировки неквадратного вывода render2d. Чаще всего вы будете прикреплять GUI элементы к aspect2d а не к render2d.

Координатная система aspect2d по-умолчанию масштабируется так, что ось x имеет диапазон [-ratio,ratio], а y имеет диапазон [-1,1], где ratio это размер_экрана_по_оси_х поделенное на размер_экрана_по_оси_y (в обычном случае ширина экрана больше его высоты).

В конце вы можете увидеть ссылки на еще один из высокоуровневых узлов называемый hidden. Это просто одиночный узел, который не имеет никаких свойств отображения и все объекты, прикрепленные к этому узлу также не будут отображаться. Старый Panda3D код использует этот узел, чтобы удалить узел из графа сцены render. Однако в новых версиях это больше не нужно и не рекомендуется использовать его для новых программ, лучший путь для удаления узла из графа render это вызвать nodePath.detachNode().

Загрузка моделей
Вы можете загрузить модель из файла, используя Panda синтаксис для имени файла, загрузить egg или bam файл. Во многих примерах расширение файла не указано — в этом случае Panda будет искать файл с расширением .egg или .bam.

myNodePath = loader.loadModel('my/path/to/models/myMode.egg')

Когда вы первый раз вызываете loadModel() для отдельного узла, эта модель считывается и сохраняется в таблице памяти и при следующих вызовах просто копируется из таблицы вместо повторного чтения из файла.

Вышеуказанный метод применяется для загрузки статических моделей, для анимированных моделей смотрите главу Загрузка Актеров и Анимаций.

Смена родителей для узлов и моделей
Одна из наиболее частых действий с графом сцены это смена родительских узлов для выбранных. Вам нужно будет сделать это по-крайней мере один раз после загрузки модели, чтобы вставить ее в render для просмотра:

myModel.reparentTo(render)

А чтобы удалить его:

myModel.detachNode()

Чтобы полностью удалить nodePath из графа сцены и памяти надо вызвать removeNode, это действие освобождает память и удаляет узел, освобождая место в памяти. Используйте это действие только когда вам больше действительно не нужен этот узел:

myNodePath.removeNode()

Когда вы станете более опытным с операциями над графом, вы заметите что можете создавать все более и более продвинутые графы сцены и можете манипулировать моделью по вашему желанию. Иногда может понадобится создавать пустые узлы для этого, например для группировки нескольких моделей вместе.
dummyNode = render.attachNewNode('Dummy Node Name')
myModel.reparentTo(dummyNode)
myOtherModel.reparentTo(dummyNode)

Так как узел наследует свое положение в пространстве от родительского узла, то когда вы прикрепляете его к другому родителю графа мы можете нечаяно изменить его положение в игровом мире. Если вам нужно избежать этой ситуации вы можете использовать специальные варианты reparentTo():

myModel.wrtReparentTo(newParent)

Префикс wrt означает «with respect to» (с уважением к). Это специальный метод работает как reparentTo(), за исключением того, что он автоматически пересчитывает его локальные транформации над myModel для компенсирования изменений при преобразовании к новому родителю, так чтобы узел оказался в той же позиции относительно игрового мира.

Помните, что расчет преобразования, который делает wrtReparentTo() выполняется над числами с плавающей точкой и может иметь погрешность. Это значит, что если вы будете использовать wrtReparentTo() непрерывно, тысячу раз над одним и тем же узлом, то эта погрешность может аккумулироваться и вместо 1 у вас будет например 0.99999.
Начинающие слишком часто используют этот метод, не следует использовать wrtReparentTo() пока для этого не будет значимой причины.

Комментариев нет:

Отправить комментарий