Опрос
Что такое, по вашему мнению, «демократия»?
Манипуляторы
Maya предлагает немало различных способов настройки и изменения атрибутов заданного узла. Наиболее широко используется такоз средство установки значения атрибута, как редактор Attribute Editor. Но для некоторых узлов есть и более наглядные инструменты решения этой задачи. Благодаря использованию манипуляторов пользователи могут зримо модифицировать конкретное множество атрибутов. В зависимости от типа атрибута такой подход может быть интуитивно более понятным, нежели использование Attribute Editor или иных методов. 4.7.1. Модуль Basicl_ocator2 Чтобы на деле увидеть простой пример работы манипуляторов, скомпилируйте и загрузите подключаемый модуль BasicLocator2. Данный модуль расширяет возможности узла-локатора, созданного в предыдущем примере, и содержит манипуляторы для всех своих собственных атрибутов: xWtdth, zWidth и dispType. Эти манипуляторы показаны на рис. 4.27. 1. Откройте рабочую среду BasicLocator2. 2. Скомпилируйте ее и загрузите полученный модуль BasicLocator2.mil в среде Maya. 3. Выберите пункт меню File | New Scene. 4. В редакторе Script Editor выполните следующую команду: createNode basicLocator; Узел basicLocator будет создан и выведен на экран. 5. Выберите на панели окна просмотра пункт View | Frame Selection (Вид I Показать выделенные объекты) или нажмите клавишу f. 6. Откройте редактор Attribute Editor. Редактор откроется, и вы увидите, как изменяются значения атрибутов. 7. Выберите пункт меню Modify | Transformation Tools | Show Manipulator Tool (Изменить Инструменты преобразования Показать манипуляторы) или нажмите клавишу t Манипуляторы, которыми обладает локатор, будут показаны на экране. Если манипуляторы не видны, убедитесь в том, что вы выбрали узел basicLocator 1, а не его родительский узел преобразования transform!. 8. Щелкните по значку-окружности рядом со словом Туре (Тип). Атрибут локатора dispType будет увеличен на единицу. 9. Щелкните по этому значку еще раз. Теперь локатор изображается в виде окружности. 10. Перетащите точку рядом с меткой X Width. Атрибут локатора xWidth обновится. Обратите внимание, что. когда вы управляете манипулятором, значение атрибута в Attribute Editor изменяется. Узел-манипулятор можно описать и для любого другого узла Dependency Graph. В данном примере нами был описан узел-локатор basicLocator и соответствующий узел-манипулятор basicLocatorManip. Узел-манипулятор - это особый узел, создаваемый, когда пользователь выделяет узел и, выбрав режим Show Manipulator Tool, запрашивает инструмент управления им. В этот момент Maya порождает экземпляр узла-манипулятора. Затем этот узел создает ряд базовых манипуляторов, с которыми взаимодействует пользователь. Узелманипулятор прикрепляет эти базовые манипуляторы к редактируемому узлу, поэтому изменение одного из манипуляторов, к примеру, буксировка точки, приводит к смене значения атрибута узла. Когда пользователь покидает режим Show Manipulator Tool, узе л-манипулятор автоматически удаляется. Узелманипулятор не может отображаться ни в одном из окон Maya (Hypergraph, Outliner и т. д.) и не позволяет редактировать собственные атрибуты. В сущности, он представляет собой временный рабочий узел, который существует лишь в период выделения узла, редактируемого с помощью манипулятора. Создать узел-манипулятор вне инструмента Show Manipulator Tool или пользовательского контекста невозможно. Узел-манипулятор можно считать контейнером базовых манипуляторов. Базовый манипулятор - это один из методов изменения атрибутов, предварительно описанных в среде Maya. В данном примере манипулятор baseLocatorManip содержит три базовых манипулятора: манипуляторы расстояния для атрибутов xWidth и zWidth и манипулятор состояния для атрибута dispType. В настоящее время Maya поддерживает десять разных базовых манипуляторов. 1. FreePointManip 2. DirectionManip 3. DistanceManip 4. PointOnCurveManip 5. PointOnSurfaceManip 6. DiscManip 7. CircleSweepManip 8. ToggleManip 9. StateManip 10. Curve SegmentManip Полное описание каждого базового манипулятора приведено в справочной документации Maya, посвященной классам. Описывать свои собственные базовые манипуляторы запрещено, поэтому создавайте более сложные манипуляторы на основе серии базовых. Такие базовые манипуляторы будут именоваться потомками главного узла-манипулятора. В числе основных этапов создания узла-манипулятора - порождение нового класса от MPxManipContamer. Далее в узел добавляется ряд дочерних базовых манипуляторов. Эти потомки связываются с конкретным атрибутом целевого узла, которым будет оперировать манипулятор. Можно описать как простую связь между дочерним манипулятором и связанным с ним атрибутом, так и более сложную. Для описания подобной связи предназначены функции преобразования. Они описывают механизм передачи информации от манипулятора к атрибуту и обратно. Модуль: BasicLocator2 Файл: BasicLocator. cpp Прежде чем переходить к рассмотрению деталей организации узламанипулятора, нужно слегка изменить первоначальный узел-локатор, чтобы сообщить Maya о том, что теперь с этим локатором связан узел-манипулятор. Maya поддерживает внутреннюю таблицу всех узлов и узлов-манипуляторов, которые с ними связаны. В конце функции initialize вызовите статическую функцию addToManipConnectTable с идентификатором того узла, который теперь располагает манипулятором. MStatus BasicLocator: :initialize() MPxManipContainer: :addToManipConnectTable( const_castДеформаторы Деформаторы не только просты в концептуальном понимании, их также легко реализовать. Деформатором называется узел, который принимает на вход серию точек и переставляет их на новое место. Деформатор не может добавить или удалить точку, он вправе лишь изменить ее положение в пространстве. Для этого может использоваться любой метод передвижения точек. Такой метод может быть простым, как, например, сдвиг на заданное расстояние, или сложным, как определение нового положения точек с привлечением имитационного моделирования из гидродинамики. Деформатор может опериронать широким спектром геометрических примитивов. На элементарном уровне он способен модифицировать точки решеток, управляющие вершины и вершины многоугольников. 4.8.1. Модуль SwirlDeformer Рассмотрим подробно пример деформатора SwirlDeformer. Подключаемый модуль создает узел-де форматор скручивания, который изменяет форму объекта, вращая его вершины с учетом их удаленности от центра воронки. Также вы сможете задавать начальную и конечную границу вращения, между которыми происходит скручивание. На рис. 4.28 показано, что произойдет с объектом после работы над ним деформатора SwirlDeformer. 1. Откройте рабочую среду SwirlDeformer. 2. Скомпилируйте ее и загрузите полученный модуль SwirlDeformer. mil в среде Maya. 3. Откройте сцену Swirl. ma. 4. Выделите объект nurbsPlanel. 5. В редакторе Script Editor выполните следующую команду: deformer - type swirl; Под воздействием деформатора скручивания форма NURBS-плоскости станет иной. Обратите внимание: скручивание не деформ]-фует объект целиком. Это происходит потому, что конечная граница, переданная деформатору скручивания, меньше ширины объекта, 6. Отобразите окно Channel Box. 7. Щелкните по элементу swirll в разделе INPUTS. На экране будут показаны все три основных параметра: Envelope (Огибающая), Start Dist (Начальная граница), End Dist (Конечная граница). 8. Установите атрибут Envelope равным 0.5. Вращение уже выражено не так сильно. Вы можете в диалоговом режиме изменять значение Envelope и наблюдать увеличение и уменьшение интенсивности скручивания. 9. Верните атрибут Envelope в 1.0. 10. Установите атрибут End Dist равным 2.0. Теперь скручивание затрагивает меньшую область поверхности. Поэкспериментируйте, изменяя Start Dist и End Dist, и посмотрите, как эти атрибуты влияют на характер скручивания. 11. Установите Start Dist равным 0.0 и End Dist равным 3.0. Кроме общих параметров огибающей и границ, вы можете задать степень влияния деформатора на отдельные вершины. Это дсстигается изменением весовых коэффициентов. 12. Нажмите клавишу F8, чтобы перейти на уровень Control Vertex (Управляющие вершины) NURBS-плоскости. 13. Выделите несколько вершин, лежащих недалеко от центра плоскости. 14. Выберите пункт главного меню Window | General Editors Component Editor... (Окно 1 Универсальные редакторы Редактор компонентов...). 15. Щелкните по вкладке Weighted Deformers (Взвешеннее деформаторы). 16. Перейдите к столбцу swirll, чтобы выделить несколько вершин для редактирования. 17. Переместите бегунок значения в нижней части окна. Веса выделенных вершин изменятся, в результате чего влияние деформатора скручивания уменьшится или увеличится в зависимости от установленных значений. Создавая собственный деформатор, вы автоматически получаете от Maya некоторые атрибуты. Атрибут envelope - общий для всех деформаторов. Он описывает степень деформации, прикладываемой к объекту. Модуль: SwirlDeformer Файл: SwirlDeformer. h Класс SwirlDeformer создается на основе класса MPxDeformerNode. class SwirlDeformer : public MPxDeformerNode public: static void *creator(); static MStatus initializeC); Главное отличие деформатора от прочих узлов заключается в наличии в его составе функции deform и отсутствии в нем функции compute. Функция compute по-прежнему существует, однако она реализована в порождающем классе. Если вам не требуется выполнять никаких специальных вычислений, лучше всего просто реализовать функцию deform, оставив функцию compute в сфере ответственности базового класса. Подробности, касающиеся функции deform, описаны в следующем разделе. virtual MStatus deform( MDataBlock &block, MltGeometry &iter, const MMatrix &mat, unsigned int multilndex ); Опишем атрибуты начальной и конечной границы скручивания. Атрибут envelope наследуется от класса MPxDeformerNode. private:, // Атрибуты static MObject startDist; static MObject endDist; Модуль: SwirlDeformer Файл: SwirlDeformer. cpp Основная функция, требующая реализации в деформаторе, - это функция deform. Именно функция deform на деле выполняет деформацию геометрического объекта. Ей передается MDataBlock, который содержит блок данных узла деформации. Это тот самый блок данных, который обычно передается вам в функции compute. Второй параметр MItGeometry - итератор, позволяющий обойти все точки геометрического объекта. Итератор может организовать цикл по точкам многих различных типов, включая управляющие вершины, точки решеток, вершины сеток и т. д. Он уже настроен на обход точек лишь того типа, которые должны быть модифицированы деформатором. Третий параметр localToWorld типа MMatrix - матрица преобразования локального пространства в мировое. Точки при передаче их деформатору находятся в локальном пространстве узла геометрии. При необходимости деформации в мировом пространстве просто преобразуйте их при помощи этой матрицы. После деформации, однако важно вернуть эти точки в локальное пространство, воспользовавшись матрицей, обратной по отношению к localToWorld. Последний параметр - это geomlndex. Деформатор способен изменять форму множества геометрических узлов, а также множества компонентов единственного узла геометрии. Посредством geomlndex Maya отслеживает деформируемые вами фрагменты геометрии. MStatus SwirlDeformer::deform( MDataBlock& block, MItGeometry &iter, const MMatrix &localToWorld, unsigned int geomlndex ) MStatus stat; Из памяти считывается атрибут envelope. MDataHandle envOata = block. inputValue( envelope ); float env = envData. asFloatC); Если значение envelope равно О, деформация никак не повлияет на геометрию, поэтому функция может сразу же заканчивать свою работу. if( env == 0.0 ) return MS::kSuccess; Далее считываются атрибуты начальной и конечной границы скручивания. MDataHandle startDistHnd = block. inputValue( startDist ); double startDist = startDistHnd. asDouble(); MDataHandle endDistHnd = block. inputValue( endDist ); double endDist = endDistHnd. asDouble(); Для обхода и деформации всех точек деформатор будет использовать итератор геометрии типа MItGeometry. for( iter. reset(); ! iter. isDoneQ; iter. next() ) Каждая точка может иметь свой собственный, связанный с ней весовой коэффициент. Этот вес определяется при помощи функции weightValue класса MPxDeformerNode. weight = weightValueC block, geomlndex, iter. indexC) ); Если точка не имеет веса, то деформатор на нее не повлияет и эту точку можно пропустить. if( weight == 0.0f ) continue; Производится считывание текущей точки, pt = iter. positionf); Рассчитывается длина перпендикуляра, опущенного из этой точки на ось у. dist = sqrt( p t . x * p t . x + pt. z * pt. z ); Если точка лежит ближе к центру вращения, чем начальная граница, или дальше от центра вращения, чем конечная граница, деформатор не окажет на эту точку никакого влияния. if( dist< startdist || dist >EndDist ) continue; Чем ближе к центру деформатора лежит точка, тем сильнее она вращается. Результат вычисления силы этого вращения заносится в переменную distFactor. Ее значение лежит в диапазоне от 0 до 1. distFactor = 1 - ((dist - startDist) / (endDist - startDist)); Затем определяется угол вращения точки. Он является результатом масштабирования distFactor с учетом значения envelope и веса weight конкретной точки. Полученное произведение умножается на числовое значение полного оборота, выраженное в радианах. ang = distFactor * H_PI * 2.0 * env * weight; Если вращение отсутствует, точка будет пропущена. if( ang == 0.0 ) continue; Выполняется поворот точки вокруг оси у на угол ang. cosAng = cos( ang ); sinAng = sin( ang ); x = pt. x * cosAng - pt. z * sinAng; pt. z = pt. x * sinAng + pt. z * cosAng; pt. x = x; Наконец, точка обновляется и занимает новое положение после деформации. iter. setPosition( pt ); return stat; В дополнение к тем атрибутам, которые унаследованы от базового класса, у зе л - де форматор имеет и два новых: startDist и endDist. Функция initialize описывает эти атрибуты и вводит их в состав узла. MStatus SwirlDeformer: :initialize() MFnUnitAttribute unitFn; startDist = unitFn. create( "startDist", "sd", MFnUnitAttribute: :kDistance ); unitFn. setDefault( MDistance( 0.0, MDistance: :uiUnit() ) ); unitFn. setMin( HDistancef 0.0, MDistance: :uiUnit() ) ); unitFn. setKeyable( true ); endDist = unitFn. create( "endDist", "ed", MFnUnitAttribute: :kDistance ); unitFn. setDefault( MDistance( 3.0, MDistance: :uiUnit( ) ) ); unitFn. setMinC MDistancef 0.0, MDistance::uiUnit() ) ); unitFn. setKeyable( true ); addAttributef startDist ); addAttributeC endDist ); attributeAffects( startDist, outputGeom ); attributeAffects( endDist, outputGeom ); return MS::kSuccess; Модуль: SwirlDeformer Файл: PluginMain. cpp Единственным несущественным изменением функции initializePlugiri является то, что при регистрации узла-деформатора должен быть задан тип MPxNode::kDeformerNode. stat = plugin. registerNode( SwirlDeformer: :typeName,. SwirlDeformer::typeld, SwirlDeformer::creator, SwirlDeformer:;initialize, MPxNode::kDeformerNode ); Процесс отмены регистрации в функции uninitializePlugin ничем не отличается от аналогичного процесса для других узлов.
Поиск
В закладку
Авторизация
Погода


