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

Помогите со скриптом!

Тема в разделе "MAXScript", создана пользователем Limpopo, 12 май 2008.

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

    Limpopo Активный участник

    С нами с:
    24.09.2006
    Сообщения:
    4
    Симпатии:
    0
    Баллы:
    7
    Заняться скриптами заставила необходимость.
    В сцене находиться около 100 боксов. Каждый случайным образом повёрнут по оси Z.
    Задача:
    попорядку (с Box01 по Box...) повернуть каждый бокс по часовой стрелке, чтобы он лёг горизонтально.
    Возможно это очень просто, но не для меня.

    Я предполагаю такую последовательность действий:
    1. Создать цикл для прохода по всем боксам.
    2. В цикле у текущего бокса определить его ориентацию по оси z.
    3. Повернуть этот бокс на полученное значение.
    4. перейти к следующему боксу.

    Но как это оформить в скриптах - не знаю.
    С ними не работал никогда.
    А сейчас нужно срочно.
    Может кто-то подскажет?
    Спасибо.
     
  2. Savin Denis vip

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

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Если повернут по Z то и так лежит горизонтально.
    Нужно довернуть по оси Z по чсасовой до ближайшего прямого угла 0,90, 180, .. ?
     
  3. Savin Denis vip

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

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Код:
    align_angle = -180.
    threshold = 0.0005
    for obj in $selection do 
    (
    local r = ( in coordsys #world obj.rotation) as eulerAngles
    local a = - r.z
    if a < 0 do a = 360. + a
    local  b = if align_angle < 0 then (- mod a align_angle) else (align_angle - mod a align_angle)
    if abs (b) < threshold or abs (b - align_angle) < threshold  do b = 0 
    in coordsys (transmatrix obj.transform.pos)   rotate obj (angleaxis b [0,0,1])
    )
    
     
  4. Limpopo

    Limpopo Активный участник

    С нами с:
    24.09.2006
    Сообщения:
    4
    Симпатии:
    0
    Баллы:
    7
    Да, ошибся. Поворачивать нужно по y.

    Поптобовал скрипт - не получается.
    Поворачиваются непонятно как.
    Пробовал заменить z на y вообще ничего.
    Вот картинка - посмотри, пожалуйста, в чём же проблема.
    [​IMG]
     

    Вложения:

    • 707970.jpg
      707970.jpg
      Размер файла:
      10,4 КБ
      Просмотров:
      48
  5. Savin Denis vip

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

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Надеюсь у тебя Ну ОЧЕНЬ много избушек =) Те нещасные 100 боксов легче руками было довернуть.
    Теперь автоматом распознает активный вьюпорт (Top, Front, Left) и будет орентировать объекты в текушей плоскости.
    Советую оформить в виде кнопки, аналогично http://www.render.ru/forum/viewtopic.php?topic_id=119614

    align_angle - задает шаг в градусах до которого будет доворачивать:
    align_angle > 0 - по часовой стрелке
    align_angle < 0 - против часовой стрелке

    align_angle = 360 - разворачивает объекты осью X только на лево =>
    align_angle = 180 - разворачивает объекты осью X: => или <=
    align_angle = 90 - разворачивает объекты осью X: => или ^ или <= или V
    ....

    Код:
    viewportType = viewport.getType()
    axis = case viewportType of 
     (
    #view_top: #z 		-- Top
    #view_bottom: #z 	-- Bottom
    #view_right: #x 		-- Right
    #view_left: #x 		-- Left
    #view_front: #y 		-- Front
    #view_back: #y		-- Back
    default: #z
     )
    	 
    -- axis =  #z -- Work axis: [ #x | #y | #z] 
    
    align_angle = -180. 
    threshold = 0.0005 
    
    fn getNodeWorldAxisAngle obj  axis:#z objectAxis:#x = 
    (
    local obj_tm = obj.transform
    local vec_start = [1,0,0]
    
    local r = case objectAxis of ( #x:  obj_tm.row1; #y: obj_tm.row2; #z: obj_tm.row3; default:obj_tm.row2)
    local vec_objectZ = case axis of ( #x:  [-r.y,r.z,0]; #y: [r.x,r.z,0]; #z:[r.x,r.y,0]; default:[r.x,r.y,0])
    
    local angle1 = acos (dot (normalize vec_start ) (normalize vec_objectZ))
    if vec_objectZ.y < 0 do angle1 = 180 - ( angle1 - 180)
    if axis != #z then -angle1 else angle1
    )
    
    vAxis = case axis of ( #x:[1,0,0]; #y:[0,1,0]; #z:[0,0,1]; default:[0,0,1])
    undo on for obj in $selection do 
    ( 
    local a = getNodeWorldAxisAngle obj  axis:axis objectAxis:#x
    local b = if align_angle < 0 then (- mod a align_angle) else (align_angle - mod a align_angle) 
    if not (abs (b) < threshold or abs (b - align_angle) < threshold ) do 
    	in coordsys (transmatrix obj.transform.pos) rotate obj (angleaxis b vAxis) 
    ) 
     
  6. Limpopo

    Limpopo Активный участник

    С нами с:
    24.09.2006
    Сообщения:
    4
    Симпатии:
    0
    Баллы:
    7
    Да... Серьёзный получился код. Буду разбираться. Большой сенкс.
     
Модераторы: Savin Denis

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