[Closed] Rotation of one object relative to another
Hello . I’m trying to rotate one object relative to another. But it’s not like it doesn’t work so that when the slider changes, it’s smooth.
In 1 case, I managed to make it rotate, but there it constantly adds value when the slider changes.
In 2 cases, I managed to make a smooth rotation, but for some reason it rotates relative to 0 coordinates.
Help solve the problem.
try (destroydialog Transformer) catch()
rollout Transformer "Transformer" width:200
(
local nodeRoot
local originTM = #()
local nodeArray = #()
group "Position: "
(
dotNetControl pos_x "System.Windows.Forms.TrackBar" pos:[6,26] width:188 height:25
dotNetControl pos_y "System.Windows.Forms.TrackBar" pos:[6,53] width:188 height:25
dotNetControl pos_z "System.Windows.Forms.TrackBar" pos:[6,80] width:188 height:25
)
group "Position: "
(
dotNetControl rot_x "System.Windows.Forms.TrackBar" pos:[6,138] width:188 height:25
dotNetControl rot_y "System.Windows.Forms.TrackBar" pos:[6,165] width:188 height:25
dotNetControl rot_z "System.Windows.Forms.TrackBar" pos:[6,192] width:188 height:25
)
button hold_tm_bt "Hold Transform" width:190
button reset_tm_bt "Zero Offset" width:190
fn transform_Relatively nodeArray node_root rot_x:0 rot_y:0 rot_z:0 =
(
local obj_Trans = #()
if nodeArr.count > 0 do
(
for i = 1 to nodeArr.count do
(
offset_rot = (eulerangles rot_x rot_y rot_z)
node_trans = nodeArray[i].transform
in coordsys (transmatrix node_root.transform.pos) nodeArray[i].rotation *= offset_rot
)
)
)
on rot_z MouseUp do
(
print "UP"
)
on rot_z ValueChanged val do
(
nodeArray = selection as array
Transform_Relatively nodeArray nodeRoot rot_x:rot_x.value rot_y:rot_y.value rot_z:rot_z.value
)
on hold_tm_bt pressed do if isvalidnode (node = selection[1]) do
(
nodeArray = selection as array
Transform_Relatively nodeArray nodeRoot rot_x:rot_x.value rot_y:rot_y.value rot_z:rot_y.value
)
on reset_tm_bt pressed do
(
nodeRoot = selection[1]
)
)
createdialog Transformer
try (destroydialog Transformer) catch()
struct ANIM_DATA (bone_name, bone_transform)
rollout Transformer "Transformer" width:200
(
local nodeRoot
local originTM = #()
local nodeArray = #()
group "Position: "
(
dotNetControl pos_x "System.Windows.Forms.TrackBar" pos:[6,26] width:188 height:25
dotNetControl pos_y "System.Windows.Forms.TrackBar" pos:[6,53] width:188 height:25
dotNetControl pos_z "System.Windows.Forms.TrackBar" pos:[6,80] width:188 height:25
)
group "Position: "
(
dotNetControl rot_x "System.Windows.Forms.TrackBar" pos:[6,138] width:188 height:25
dotNetControl rot_y "System.Windows.Forms.TrackBar" pos:[6,165] width:188 height:25
dotNetControl rot_z "System.Windows.Forms.TrackBar" pos:[6,192] width:188 height:25
)
button hold_tm_bt "Hold Transform" width:190
button reset_tm_bt "Zero Offset" width:190
fn transform_Relatively nodeArray originTM node_root rot_x:0 rot_y:0 rot_z:0 =
(
local obj_Trans = #()
if nodeArray.count > 0 do
(
for i = 1 to nodeArray.count do
(
offset_rot = (eulerangles rot_x rot_y rot_z) as matrix3
node_trans = originTM[i]
in coordsys (transmatrix node_root.transform.pos) node_trans *= offset_rot
--in coordsys node_root ( node_trans *= offset_rot )
append obj_Trans ( ANIM_DATA nodeArray[i].name node_trans )
)
)
for data in obj_Trans do
(
obj = getNodeByName data.bone_name
if obj == undefined do continue
--add world transform
obj.transform = data.bone_transform
)
)
on rot_z MouseDown do
(
originTM = #()
if isvalidnode (node = selection[1]) do
(
nodeArray = mcBiped.sort_NodeByHeirarchy()
for i = 1 to nodeArr.count do
(
append originTM nodeArray[i].transform
)
)
)
on rot_z MouseUp do
(
originTM = #()
nodeArray = mcBiped.sort_NodeByHeirarchy()
for i = 1 to nodeArr.count do
(
append originTM nodeArray[i].transform
)
rot_z.value = 0
)
on rot_z ValueChanged val do
(
Transform_Relatively nodeArray originTM nodeRoot rot_x:rot_x.value rot_y:rot_y.value rot_z:rot_z.value
)
on hold_tm_bt pressed do if isvalidnode (node = selection[1]) do
(
nodeArray = mcBiped.sort_NodeByHeirarchy()
originTM = #()
nodeArray = mcBiped.sort_NodeByHeirarchy()
for i = 1 to nodeArr.count do
(
append originTM nodeArray[i].transform
)
Transform_Relatively nodeArray originTM nodeRoot rot_x:rot_x.value rot_y:rot_y.value rot_z:45
)
on reset_tm_bt pressed do
(
nodeRoot = selection[1]
)
)
createdialog Transformer
try(destroydialog RelativeTransformRol) catch()
deleteAllChangeHandlers id:#my_relative_transform
rollout RelativeTransformRol "Relative Transform" width:261
(
local coordsys_node = coordsys_node
group "Coordsys Node: "
(
pickbutton pick_coordsys_bt "< Pick Coordsys Node >" width:242 autodisplay:on align:#left offset:[-4,2] filter:isvalidnode \
tooltip:"Pick a node to be used as a coordsys"
)
label emp_00 height:4
local xrot_control = bezier_float()
local yrot_control = bezier_float()
local zrot_control = bezier_float()
local xpos_control = bezier_float()
local ypos_control = bezier_float()
local zpos_control = bezier_float()
group "Rotation: "
(
slider x_rot_sl "" type:#float range:[-360,360,0] ticks:0 width:180 align:#left offset:[-4,2] across:2
spinner x_rot_sp "" type:#float range:[-360,360,0] fieldwidth:60 align:#right offset:[4,4]
slider y_rot_sl "" type:#float range:[-360,360,0] ticks:0 width:180 align:#left offset:[-4,2] across:2
spinner y_rot_sp "" type:#float range:[-360,360,0] fieldwidth:60 align:#right offset:[4,4]
slider z_rot_sl "" type:#float range:[-360,360,0] ticks:0 width:180 align:#left offset:[-4,2] across:2
spinner z_rot_sp "" type:#float range:[-360,360,0] fieldwidth:60 align:#right offset:[4,4]
)
label emp_01 height:0
group "Position: "
(
slider x_pos_sl "" type:#float range:[0,100,0] ticks:0 width:180 align:#left offset:[-4,2] across:2
spinner x_pos_sp "" type:#float range:[0,100,0] fieldwidth:60 align:#right offset:[4,4]
slider y_pos_sl "" type:#float range:[0,100,0] ticks:0 width:180 align:#left offset:[-4,2] across:2
spinner y_pos_sp "" type:#float range:[0,100,0] fieldwidth:60 align:#right offset:[4,4]
slider z_pos_sl "" type:#float range:[0,100,0] ticks:0 width:180 align:#left offset:[-4,2] across:2
spinner z_pos_sp "" type:#float range:[0,100,0] fieldwidth:60 align:#right offset:[4,4]
)
button update_transform_bt "Update" width:119 align:#left offset:[-4,8] across:2 \
tooltip:"Update Transform"
button reset_zero_bt "Zero Transform" width:119 align:#right offset:[4,8] \
tooltip:"Zero Transform"
label info_lb "info..." width:172 align:#left offset:[-4,6]
fn updateRelativeTransform = if isvalidnode coordsys_node do
(
tm = copy coordsys_node.transform
prerotateX tm xrot_control.value
prerotateY tm yrot_control.value
prerotateZ tm zrot_control.value
pretranslate tm [xpos_control.value, ypos_control.value, zpos_control.value]
nodes = for node in selection where node != coordsys_node collect node
if nodes.count do nodes.transform = tm
)
on pick_coordsys_bt picked obj do
(
if isvalidnode obj do
(
coordsys_node = obj
when transform coordsys_node change id:#my_relative_transform do updateRelativeTransform()
updateRelativeTransform()
redrawviews()
)
)
on pick_coordsys_bt rightclick do
(
if isvalidnode (node = selection[1]) do
(
pick_coordsys_bt.object = coordsys_node = node
when transform coordsys_node change id:#my_relative_transform do updateRelativeTransform()
updateRelativeTransform()
redrawviews()
)
)
on update_transform_bt pressed do
(
updateRelativeTransform()
redrawviews()
)
on reset_zero_bt pressed do undo "Zero Transform" on
(
xrot_control.value = yrot_control.value = zrot_control.value = 0
xpos_control.value = ypos_control.value = zpos_control.value = 0
updateRelativeTransform()
redrawviews()
)
local tm_controls = #(xrot_control, yrot_control, zrot_control, xpos_control, ypos_control, zpos_control)
on RelativeTransformRol open do
(
deleteAllChangeHandlers id:#my_relative_transform
)
on RelativeTransformRol open do
(
x_rot_sl.controller = x_rot_sp.controller = xrot_control
y_rot_sl.controller = y_rot_sp.controller = yrot_control
z_rot_sl.controller = z_rot_sp.controller = zrot_control
x_pos_sl.controller = x_pos_sp.controller = xpos_control
y_pos_sl.controller = y_pos_sp.controller = ypos_control
z_pos_sl.controller = z_pos_sp.controller = zpos_control
when geometry tm_controls change id:#my_relative_transform do updateRelativeTransform()
if isvalidnode coordsys_node do
(
pick_coordsys_bt.object = coordsys_node
when transform coordsys_node change id:#my_relative_transform do updateRelativeTransform()
)
updateRelativeTransform()
redrawviews()
)
)
createdialog RelativeTransformRol escapeEnable:true
the most complicated part is to organize the right UI and parameter notifications. I would probably do it using a CustAttribute(s).
denisT thanks for the hint. I completely forgot about – prerotateX.
I modified it a little here, as I needed the selected objects to retain their original transform relative to the pivot point. And after changing the slider, it returned back to 0 and the offset transformation was saved.
If you can optimize it a little, I’ll be glad to see it. Thanks in advance.
try (destroydialog Transformer) catch()
rollout Transformer "Transformer by denisT" width:200
(
local nodeRoot
local originTM = #()
local rootTM = #()
local offsetTM = #()
local nodeArray = #()
group "Rotation Offset "
(
dotNetControl rot_x "System.Windows.Forms.TrackBar" pos:[6,26] width:188 height:25
dotNetControl rot_y "System.Windows.Forms.TrackBar" pos:[6,53] width:188 height:25
dotNetControl rot_z "System.Windows.Forms.TrackBar" pos:[6,80] width:188 height:25
)
button hold_tm_bt "Hold Transform" width:190
button reset_tm_bt "Zero Offset" width:190
fn get_Origin_pos =
(
originTM = #()
if isvalidnode (node = selection[1]) do
(
nodeArray = selection as array
for i = 1 to nodeArray.count do
(
offsetTM = in coordsys nodeRoot nodeArray[i].pos
rootTM = in coordsys nodeRoot nodeArray[i].rotation
append originTM #(offsetTM, rootTM)
)
)
)
fn transform_Relatively nodeArray originTM node_root rot_x:0 rot_y:0 rot_z:0 =
(
for i = 1 to nodeArray.count where nodeArray[i] != node_root do
(
tm = copy node_root.transform
prerotateX tm rot_x
prerotateY tm rot_y
prerotateZ tm rot_z
pretranslate tm originTM[i][1]
nodeArray[i].transform = tm
nodeArray[i].rotation *= originTM[i][2]
nodeArray[i].position = tm.position
)
)
on rot_z MouseDown do
(
print "Down"
get_Origin_pos()
)
on rot_z MouseUp do
(
print "UP"
get_Origin_pos()
rot_z.value = 0
)
on rot_z ValueChanged val do if isvalidnode (node = selection[1]) do
(
nodeArray = selection as array
transform_Relatively nodeArray originTM nodeRoot rot_x:rot_x.value rot_y:rot_y.value rot_z:rot_z.value
)
on hold_tm_bt pressed do if isvalidnode (node = selection[1]) do
(
rot_z.value = 0
)
on reset_tm_bt pressed do
(
with redraw off
(
--delete objects
--Rot = dummy name:#target pos:(random -[10,10,10] [10,10,10]) dir:(random -[1,1,1] [1,1,1]) isselected:on
nodeRoot = selection[1]
)
--rot_x.value = rot_y.value = rot_z.value = pos_x.value = pos_y.value = pos_z.value = 0
--transformNode()
)
on Transformer open do
(
rot_z.Maximum = 360
rot_z.Minimum = -360
rot_z.Value = 0
)
)
createdialog Transformer