Render.ru

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

Limpopo

Пользователь сайта
Рейтинг
2
#1
Заняться скриптами заставила необходимость.
В сцене находиться около 100 боксов. Каждый случайным образом повёрнут по оси Z.
Задача:
попорядку (с Box01 по Box...) повернуть каждый бокс по часовой стрелке, чтобы он лёг горизонтально.
Возможно это очень просто, но не для меня.

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

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

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#3
Код:
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])
)
 

Limpopo

Пользователь сайта
Рейтинг
2
#4
Если повернут по Z то и так лежит горизонтально.
Нужно довернуть по оси Z по чсасовой до ближайшего прямого угла 0,90, 180, .. ?
Да, ошибся. Поворачивать нужно по y.

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

Вложения

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#5
Надеюсь у тебя Ну ОЧЕНЬ много избушек =) Те нещасные 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) 
)
 

Limpopo

Пользователь сайта
Рейтинг
2
#6
Да... Серьёзный получился код. Буду разбираться. Большой сенкс.
 
Сверху