Render.ru
Поддержать

Поворот кости, но не её оси

Антон Шметелько (Tosyk)

Активный участник
Рейтинг
10
Нужно сделать скрипт который бы поворачивал выделенные кости на определённый угол, но не поворачивал бы ось.
Из разных источников мне удалось собрать несколько вариантов,
но все они вместе с объектом поворачивают и его ось.

Варианты:

$.boneEnable=false
toolMode.coordsys #local
maxops.pivotmode = #objectonly

rotate $ (angleaxis -90 [0,0,1])
$.boneEnable=false
toolMode.coordsys #local
maxops.pivotmode = #objectonly

currentMatrix = $.transform
preRotate currentMatrix (eulertoquat (eulerAngles 0 0 -90))
$.transform = currentMatrix
------------------------------------------------------
-- Set the given object's rotation to the given values
------------------------------------------------------

$.boneEnable=false
toolMode.coordsys #local
maxops.pivotmode = #objectonly

fn SetObjectRotation obj rx ry rz =
(
	-- Reset the object's transformation matrix so that 
	-- it only includes position and scale information. 
	-- Doing this clears out any previous object rotation.
	local translateMat = transMatrix obj.transform.pos
	local scaleMat = scaleMatrix obj.transform.scale
	obj.transform = scaleMat * translateMat
   
	-- Perform each axis rotation individually
	rotate obj (angleaxis rx [1,0,0])
	rotate obj (angleaxis ry [0,1,0])
	rotate obj (angleaxis rz [0,0,1])
)

-- Set currently selected Object's rotation to 80 50 100
SetObjectRotation selection[1] 0 0 -90
Важное уточнение: после или до поворота мне все эти кости нужно уменьшить на определённое значение, например так
$.width = 0.125
$.height = 0.125
$.length = 0.125
Пожалуйста подскажите решение.

igorznag

Мастер
Рейтинг
103
Нужно сделать скрипт который бы поворачивал выделенные кости на определённый угол, но не поворачивал бы ось.
Попробуй использовать модификатор XForm. Или он не подходит для решения этой задачи?
m=XForm();
m.gizmo.rotation=(eulertoquat (eulerAngles 0 0 -90)) 
addmodifier $ m

Антон Шметелько (Tosyk)

Активный участник
Рейтинг
10
спасибо за ответ,
но на костях не должно быть модификаторов.
как в последствии от него избавится?
не хочу просто чтобы с стеке у кости болтался модификатор

igorznag

Мастер
Рейтинг
103
Попробуй использовать функцию RotatePivotOnly, которая находится в главе Using Node Transform Properties.
fn RotatePivotOnly obj rotation= ( 
local rotValInv=inverse (rotation as quat)
animate off in coordsys local obj.rotation*=RotValInv
obj.objectoffsetrot*=RotValInv
obj.objectoffsetpos*=RotValInv
)

a_z=-90
for obj in $selection do
(
animate off in coordsys local rotate obj (eulerAngles 0 0 -a_z);
RotatePivotOnly obj (eulerAngles 0 0 a_z);
)

Антон Шметелько (Tosyk)

Активный участник
Рейтинг
10
igorznag, спасибо
отлично работает на выбранных объектах.
как раз начал копать в направлении углов эйлера
я так понимаю скрипт поворачивает сначала объект, а потом поворачивает обратно его пивот.
Сейчас буду пробывать привязывать регулировку углов к спинерам.

немного не по теме сопутствующий вопрос:
как таким же методом можно сделать realigntochild кости и чтобы ось оставалась на месте
использую код:

$.boneEnable=true				
for ra in selection do ra.realignBoneToChild ()
$.boneEnable=false
я так понимаю RotatePivotOnly уже не применим.

igorznag

Мастер
Рейтинг
103
Попробуй использовать функцию AlignPivotTo, которая находится в этой теме:Aligning only the pivot of an object using MAXScript. Сообщение 18.
(
fn AlignPivotTo Obj Trgt =
(
-- Get matrix from object
if classOf Trgt != matrix3 then Trgt = Trgt.transform

-- Store child transforms
local ChldTms = in coordSys Trgt ( for Chld in Obj.children collect Chld.transform )

-- Current offset transform matrix
local TmScale = scaleMatrix Obj.objectOffsetScale
local TmRot = Obj.objectOffsetRot as matrix3
local TmPos = transMatrix Obj.objectOffsetPos
local TmOffset = TmScale * TmRot * TmPos

-- New offset transform matrix
TmOffset *= obj.transform * inverse Trgt

-- Apply matrix
Obj.transform = Trgt

-- Restore offsets
Obj.objectOffsetPos = TmOffset.translation
Obj.objectOffsetRot = TmOffset.rotation
Obj.objectOffsetScale = TmOffset.scale

-- Restore child transforms
for i = 1 to Obj.children.count do Obj.children[i].transform = ChldTms[i] * inverse Trgt * Obj.transform
)

$.boneEnable=true 
for ra in selection do 
(
t=ra.transform
ra.realignBoneToChild(); 
AlignPivotTo ra t
)
$.boneEnable=false 
)

Антон Шметелько (Tosyk)

Активный участник
Рейтинг
10
Оно работает! Отлично! Спасибо.
Я ещё только учусь и мне было бы доволно сложно до этого додуматься так же быстро как мне это нужно.
После использования этого скрипта мне нужно протянуть кость то этого чайлда функцией

for b in selection do b.resetBoneStretch()
правильно ли будет подставить её в конец?

...
$.boneEnable=true 
for ra in selection do 
( 
t=ra.transform 
ra.realignBoneToChild(); 
ra.resetBoneStretch(); --вот эта
AlignPivotTo ra t  
) 
$.boneEnable=false
для меня это работает.
но правильно ли это с технической точки зрения?