1. Пользоваться форумом на планшетах и телефонах стало удобнее благодаря Tapatalk

Интересные примеры Script & Expression controller

Тема в разделе "MAXScript", создана пользователем Savin Denis, 24 дек 2009.

Модераторы: Savin Denis
  1. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    В этой ветке предлагаю делиться своими любимы скрипт контроллерами или экспрешн(Expression). (Чтобы было понятно о чем речь, на мой взгляд правильней будет произносить как экспрешн, а не выражения.)



    Для новичков поясню - скрипт контроллеры являясь более гибким инструментом чем многим знакомые Wire-контроллеры, позволяют легко организовывать сложные параметрические поведенческие взаимосвязи между анимироваными элементами сцены.

    Еще проще анимируя например параметр или объект мы можем заставить другой объект допустим выписывать восьмерки или махать крыльями или еще что-то столь полезное.

    В общем это та самая волшебная дубинка котороя избавит аниматора от рутинной работы, или просто от работы =)
    То чем должен владеть каждый кто занимается сетапом сцены или персонажей.

    Теперь об оформлении:
    • Минимальная рабочая версия 3dsmax. (или на которой тестировалось)
      Должно быть описание, что делает контроллер.
      Код контроллера с комментариями поясняющими принцип работы.
      Обязательно указать тип контроллера - куда вешается.
      Обязательно указать от каких объектов, контроллеров, параметров есть зависимость. Указать их тип.
      Инструкция как использовать.

    Поскольку речь об анимации анимированые гифы, и Yotube ролики поясняющие работу контроллеров приветствуются.

    PS.
    Поскольку ветка организованна по просьбе пользователя sylka с него и начнем =).
     
  2. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Зарезервировал
     
  3. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Зарезервировал
     
  4. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Зарезервировал
     
  5. sylka

    sylka Пользователь сайта

    С нами с:
    13.02.2006
    Сообщения:
    21
    Симпатии:
    0
    Баллы:
    2
    скрипт контроллер привязывающий движение объекта раба к точке объекта хозяина

    работает во всех версиях

    ограничение: объект хозяин должен быть обязательно editable poly (по крайней мере в данной конфигурации експрешена :) )

    настройка :

    1) выбрать объект хозяин
    2) выделить необходимую точку если параллельно открыть maxscript listener в верхней половине его при выделении точки появится строчка с указывающая на номер номер вершины. можно еще узнать с помощью команды polyop.getvert $ ввев ее в нижней половине maxscript listener . То ,что )) как мне нравится )) будет написано синеньким в нижней половине будет искомым номером вершины :)
    4) выбираем объект раб, ставим во вкладке motion выбираем positon controller => position script
    5) в свитке скриптконтроллера назначаем variable с именем ctrobj которой в качестве node назначаем наш обект хозяин

    формула:

    pos = polyop.getvert ctrobj 7

    ** 7 - вписана здесь для наглядности примера, а в вашем случае найденная вами вершина

    собственно все))

    Поскольку учу скрипты недавно, для себя я написал функции для полезных в моих задачах моментов, есть желание в будущем создать свиток который будет содержать компоненты сэтапа для часто используемых и полезных выражений

    мне кажется что с описанием я переборщил... ), что не все умеют работать со скриптами
    я постарался дать исчерпывающий ответ, 3 месяца назад сам толком ничего не понимал :)
    to Savin Denis или же лучше в предложенном вами виде выкладывать ?впринципе кому надо тот поймет ,тут всетаки главное идея , только с коментариями вот так например:

    Код:
    faceAttach = 2 -- number of master object face 
    
    obj = convertToPoly (Box())  -- editable poly master
    objslave = Box() -- editable poly slave
    
    ctrl = transform_script() -- Controller:Transform_Script
    objslave.transform.controller = ctrl -- add Transform_Script  to slave object
    
    ------------------------------------script in expression controller----------------------------- 
    ctrl.addNode "obj" obj 
    fv = polyop.getFaceVerts obj faceAttach
    txt = "p1 = polyop.getvert obj " + fv[1] as string + "\n"
    txt += "p2 = polyop.getvert obj " + fv[2] as string + "\n"
    txt += "p3 = polyop.getvert obj " + fv[3] as string + "\n"
    txt += "v1 = normalize (p2-p1)\n"
    txt += "v2 = normalize (p3-p1)\n"
    txt += "nv1 = normalize (cross v1 v2)\n"
    txt += "nv2 = normalize(cross nv1 v1)\n"
    txt += "matrix3 v1 nv2 nv1 ((p1+p2+p3)/3)"
    -------------------------------------------------------------------------------------------------------
    ctrl.setExpression txt -- execute  
    Коментарий Savin Denis:

    Поскольку похоже описание ты привел к какой то своей модификации этого скрипта, то позволю себе прокомментировать этот код:
    Версия 3dsmax: От max8
    Описание: Скрипт автоматически привязывает любой объект к указанному полигону другого полигонального объекта.
    Использование: Просто запустить скрипт на чистой сцене, все остальное сделает сам. В качестве примера создаст два бокса которые и свяжет.
    Параметры:
    • obj Объект к которому привяжет. Должен быть EditablePoly !
      objslave Объект который нужно привязать.
      faceAttach Номер фейса к которому произойдет привязка.

    Тема в которой можно обсудить.
     
  6. sylka

    sylka Пользователь сайта

    С нами с:
    13.02.2006
    Сообщения:
    21
    Симпатии:
    0
    Баллы:
    2
    блин (( хотел кой чего подправить в тексте но уже поздно, если чего не так не судите строго) время уже позднее да и объяснять я не особо честно говоря умею

    пример в первом посте тоже рабочий только он привязывает все трансформации (код написан Savin Denis) к объекту мастеру

    если надо только вращение для копмплекта так сказать оставить, пишите подправлю и дополню в следующих постах, или кто знает и кому не лень дополните и запостите сами
     
  7. Chebu

    Chebu Знаток

    С нами с:
    23.10.2005
    Сообщения:
    141
    Симпатии:
    0
    Баллы:
    60
    Название: parentConstraint

    Для тех, кому не хватает функциональности link constraint в max до 2010 версии (в частности, совершать любые действия с ключами, как то: копировать, перемещать, удалять и пр.)

    Предназначение:
    Данный скрипт позволяет создать для объекта определённый список парентов и менять ID парента, за которым объект следует в данный момент. Ключи смены ID можно перемещать, копировать, удалять и т.п.

    Использование:
    выделяем объект, запускаем скрипт.
    в стек модификаторов объекта добавится модификатор attribute holder в качестве контрольной панели. В нём мы видим список парентов (редактируемый кнопками add и delete), а также ID текущего парента. 0 - объект привязан к миру, 1 - к первому паренту в списке, 2 - ко второму и т.п.

    ID текущего парента можно анимировать, ОБЯЗАТЕЛЬНО делать ключи типа stepped (перед анимацией параметра можно выставить default in/out tangents for new keys на stepped - кнопка рядом с setkey)

    Ограничения скрипта, примечания:
    1) на 0 кадре объект, на котором висит данный скриптконтроллер, ДОЛЖЕН быть привязан к миру.
    2) данный объект невозможно перемещать/вращать/масштабировать вручную (т.к. нет лист-контроллера для контроллера transform) - легко обходится таким образом: вешаем данный скриптконтроллер на даммик, а целевой объект вяжем за даммик.


    надеюсь, кому-нибудь пригодится) лично я от использования link constraint теперь отказался вообще.

    скрипт:
    Код:
    if (selection.count == 1) do
    (
    
    fn deleteAllDefs sel = 
    (
    	attrs = custAttributes.getDefs sel
    	if (attrs != undefined) do
    	for i = 1 to attrs.count do
    	(
    		custattributes.delete sel 1
    	)
    )
    
    def = attributes pconstr
    (
    	parameters pconstr_params 
    	(
    		pID type:#integer animatable:true default:0
    		p type:#nodeTab animatable:false tabsizevariable:true
    		initTransform type:#matrix3 animatable:false			
    	)
    )
    
    contr = transform_script()
    deletealldefs contr
    custattributes.add contr def
    contr.pid.controller = bezier_float()
    contr.script = 
    "
    	fn getTransformAtTime t = 
    	(
    		c = this.pid.controller
    		sortKeys c
    		PrevKeys = #()
    		for key in c.keys do
    		(
    			if(key.time <= t) do append prevKeys key.time
    		)
    
    		tr = this.initTransform
    		offset = matrix3 1
    		prevID = 0
    		currID = 0
    		for key in prevKeys do
    		(		
    			at time (key-1)
    			(
    				prevID = this.pID
    			)
    			
    			at time (key)
    			(
    				currID = this.pID
    				if (prevID != 0) then
    				(		
    					tr = offset * (this.p[prevID].transform)
    				)
    				if ( currID != 0 ) then
    				(
    					offset = tr * inverse(this.p[currID].transform)
    				)
    				else offset = matrix3 1
    			)
    		)
    		
    		if (currID != 0) then tr = offset * (this.p[currID].transform)
    		
    		tr
    	)
    
    getTransformAtTime currentTime
    
    "
    
    at time 0
    (
    	contr.initTransform = $.transform
    	$.transform.controller = contr
    )
    
    
    attrDef = attributes pconstr
    (
    	parameters pconstrParams rollout:params
    	(
    		pID type:#integer animateble:true default:0 ui:spn1
    		pcontr type:#maxobject
    	)	
    	
    	rollout params "pConstr_params" width:183 height:196
    	(
    		listbox lbx1 "parents list" pos:[6,4] width:171 height:9
    		button btn6 "remove" pos:[96,148] width:71 height:16
    		
    		pickbutton btn12 "add" pos:[15,148] width:71 height:16
    		spinner spn1 "active parent ID" pos:[36,177] width:110 height:16 type:#integer
    		
    		fn updatelist = 
    		(
    			arrNames = #()
    			for obj in pcontr.p do
    			(
    				append arrNames obj.name
    			)
    			lbx1.items = arrNames
    		)
    		
    		
    		
    		on params open do
    		(
    			updatelist()
    		)
    		on btn6 pressed do
    		(
    			if(lbx1.selection>0) do
    			(
    				if(lbx1.selection <= pcontr.p.count) do 
    				(
    					pcontr.deleteVariable (pcontr.p[lbx1.selection].name+"_var")
    					deleteItem pcontr.p lbx1.selection
    				)
    			)
    			
    			updatelist()
    		)
    		on btn12 picked obj do
    		(
    			appendifunique pcontr.p obj
    			pcontr.addnode (obj.name+"_var") obj
    			updatelist()
    		)
    		on spn1 changed val do
    		(
    			if (val < 0) do spn1.value = 0
    			if (val > pcontr.p.count) do spn1.value = pcontr.p.count
    		)
    	)
    )
    
    attrholder = emptymodifier()
    custAttributes.add attrholder attrDef
    
    attrholder.pid.controller = contr.pid.controller
    attrholder.pcontr = contr
    
    addmodifier $ attrholder
    )
    
     
  8. Арт.К

    Арт.К Активный участник

    С нами с:
    25.10.2008
    Сообщения:
    162
    Симпатии:
    10
    Баллы:
    15
    Полезная тема. Однако, прошу простить за вопрос по другому поводу, но, возможно, здесь кто-то знает решение следующей проблемы. После апдейта объекта в сцене (посредством импорта и т,л.) сохраняются привязки через линк и через /Position Constraint/, а также через /Orientation Constraint/, но не сохраняются привязки через /Wire parameters/, а также через /Float Expression/. То есть необходимо заново вносить эти связи. Вопрос - есть ли возможность (как-то указать условия) чтоб эти связи сохранялись?
    Или, подошел бы вариант, когда бы можно было задействовать один из указанных типов связи (/Wire parameters/ или /Float Expression/) для прилинкованого объекта. То есть, чтоб объект "C" считывал (посредством /Wire parameters/ или /Float Expression/) параметры перемещения с объекта "D" который прилинкован к третьему объекту. Поскольку указаные привязки не воспринимают перемещения прилинкованого объекта, в отличии от таких привязок, как /Position Constraint/ и т.д. Возможно тоже можно как-то указать условия, чтоб параметры считывались?
     
  9. Арт.К

    Арт.К Активный участник

    С нами с:
    25.10.2008
    Сообщения:
    162
    Симпатии:
    10
    Баллы:
    15
    Всем спасибо, вопрос предыдущего сообщения уже не актуален. Решение подсказано пользователем в другой теме.
     
Модераторы: Savin Denis

Поделиться этой страницей