212 lines
5.8 KiB
Plaintext
Executable File
212 lines
5.8 KiB
Plaintext
Executable File
|
|
rollout RsModelToolAlignRoll "Align Object" width:300
|
|
(
|
|
hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Modelling_Toolkit#Align_Object" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255)
|
|
|
|
local storedItem
|
|
group "Store/Restore Transforms:"
|
|
(
|
|
button btnStoreXform "Store" across:3 align:#left tooltip:"Remember selected object's transforms:\nUse to revert changes after aligning"
|
|
label lblStoredXform "" offset:[-4,4]
|
|
button btnRestoreXform "Restore" align:#right enabled:false tooltip:"Apply stored transforms back onto object"
|
|
)
|
|
|
|
group "Align Object-Edge To Axis:"
|
|
(
|
|
button btnAlignObj "Align:" width:52 height:30 across:5 offset:[0,7] align:#left tooltip:"Rotate selected object around chosen axis, to align selected edge to another axis"
|
|
|
|
label lblRot "Rotate in:" align:#right offset:[16,14]
|
|
radiobuttons btnsRotAxis "" labels:#("X","Y","Z") columns:1 default:3 align:#left offset:[20,0]
|
|
|
|
label lblAlign "Align Edge to:" align:#right offset:[22,14]
|
|
radiobuttons btnAlignX "" labels:#("X") pos:[lblAlign.pos.x + 72, btnsRotAxis.pos.y]
|
|
radiobuttons btnAlignY "" labels:#("Y") pos:(btnAlignX.pos + [0, 15])
|
|
radiobuttons btnAlignZ "" labels:#("Z") pos:(btnAlignY.pos + [0, 15])
|
|
)
|
|
local alignCtrls = #(btnAlignX, btnAlignY, btnAlignZ)
|
|
|
|
fn RsAlignObjToEdge obj rotAxis:3 alignAxis:1 =
|
|
(
|
|
local otherAxis = ((#{1..3} - #{rotAxis, alignAxis}) as array)[1]
|
|
/*
|
|
local axises = #("X","Y","Z")
|
|
format "Rotate:%,% Align:%,% Other:%,% %\n" rotAxis axises[rotAxis] alignAxis axises[alignAxis] otherAxis axises[otherAxis] edgeVec
|
|
*/
|
|
local selType = RsGetSubObjLevelName()
|
|
|
|
if (selType != #edge) do
|
|
(
|
|
messageBox "Non-edge selection!\n\nPlease select an edge on a mesh/poly object" title:"Error: Non-edge selection"
|
|
return false
|
|
)
|
|
|
|
if (isKindOf obj objectSet) do (obj = obj[1])
|
|
|
|
local objXform = obj.transform
|
|
|
|
local objMesh = copy obj.mesh
|
|
|
|
local edgeSel = getEdgeSelection objMesh
|
|
|
|
if (edgeSel.numberSet == 0) do
|
|
(
|
|
messageBox "Empty selection:\n\nPlease select an edge" title:"Error: Nothing selected"
|
|
return false
|
|
)
|
|
|
|
local verts = #{}
|
|
for edgeNum in edgeSel while (verts.numberSet < 2) do
|
|
(
|
|
verts += meshOp.getVertsUsingEdge objMesh edgeNum
|
|
)
|
|
|
|
if (verts.numberSet != 2) do
|
|
(
|
|
messageBox "Multiple edges selected!\n\nPlease select just one edge" title:"Error: Too many selected"
|
|
return false
|
|
)
|
|
|
|
-- Get edge-vert positions, transformed to world-space:
|
|
local vertPosList = for vertNum in verts collect
|
|
(
|
|
((getVert objMesh vertNum) * objXform) --- objXform.pos
|
|
)
|
|
|
|
--for pos in vertPosList do (point pos:pos)
|
|
|
|
local edgeVec = normalize (vertPosList[1] - vertPosList[2])
|
|
edgeVec[rotAxis] = 0
|
|
|
|
-- Stop processing if edge-vector is already aligned:
|
|
if (close_enough edgeVec[otherAxis] 0 10) do
|
|
(
|
|
return false
|
|
)
|
|
|
|
-- Vector to align to:
|
|
local alignVec = [0,0,0]
|
|
alignVec[alignAxis] = 1
|
|
/*
|
|
Tape pos:vertPosList[1] target:(targetObject pos:(vertPosList[1] + (10 * edgeVec)))
|
|
Tape pos:vertPosList[1] target:(targetObject pos:(vertPosList[1] + (5 * alignVec)))
|
|
*/
|
|
local angleAxes = #(alignAxis, otherAxis)
|
|
sort angleAxes
|
|
|
|
-- Find angle between vectors:
|
|
local vecAngle = (atan2 alignVec[angleAxes[2]] alignVec[angleAxes[1]]) - (atan2 edgeVec[angleAxes[2]] edgeVec[angleAxes[1]])
|
|
|
|
-- Correct direction for y-axis rotation:
|
|
if (rotAxis == 2) do
|
|
(
|
|
vecAngle *= -1
|
|
)
|
|
|
|
-- Always rotate less than 90 degrees:
|
|
local rotAngle = vecAngle
|
|
local angleSign = if (vecAngle < 0) then 1 else -1
|
|
if (abs vecAngle) > 90 do
|
|
(
|
|
rotAngle += (angleSign * 180)
|
|
)
|
|
|
|
--format "% -> % : % (%)\n" edgeVec alignVec vecAngle rotAngle
|
|
|
|
local changeRot = (eulerAngles 0 0 0)
|
|
case rotAxis of
|
|
(
|
|
1:(changeRot.x = rotAngle)
|
|
2:(changeRot.y = rotAngle)
|
|
3:(changeRot.z = rotAngle)
|
|
)
|
|
|
|
in coordSys world rotate obj changeRot
|
|
)
|
|
|
|
fn setViewAxis num =
|
|
(
|
|
local enabledAligns = #{1..3}
|
|
enabledAligns -= #{num}
|
|
|
|
-- Disable view-axis as align-option:
|
|
for alignNum = 1 to 3 do
|
|
(
|
|
alignCtrls[alignNum].enabled = enabledAligns[alignNum]
|
|
alignCtrls[alignNum].state = 0
|
|
)
|
|
|
|
-- Set first enabled axis state:
|
|
alignCtrls[(enabledAligns as array)[1]].state = 1
|
|
)
|
|
|
|
fn setAlignAxis num =
|
|
(
|
|
for alignNum = 1 to 3 where (alignNum != num) do
|
|
(
|
|
alignCtrls[alignNum].state = 0
|
|
)
|
|
)
|
|
|
|
on btnsRotAxis changed val do (setViewAxis val)
|
|
on btnAlignX changed val do (setAlignAxis 1)
|
|
on btnAlignY changed val do (setAlignAxis 2)
|
|
on btnAlignZ changed val do (setAlignAxis 3)
|
|
|
|
on btnAlignObj pressed do
|
|
(
|
|
local rotAxis = btnsRotAxis.state
|
|
|
|
local alignAxis = case of
|
|
(
|
|
(btnAlignX.state == 1):1
|
|
(btnAlignY.state == 1):2
|
|
(btnAlignZ.state == 1):3
|
|
)
|
|
|
|
undo "rotate object edge to axis" on
|
|
(
|
|
RsAlignObjToEdge selection rotAxis:rotAxis alignAxis:alignAxis
|
|
)
|
|
)
|
|
|
|
on btnStoreXform pressed do
|
|
(
|
|
if (selection.count != 1) then
|
|
(
|
|
storedItem = undefined
|
|
lblStoredXform.text = ""
|
|
btnRestoreXform.enabled = false
|
|
)
|
|
else
|
|
(
|
|
local obj = selection[1]
|
|
storedItem = datapair obj:obj transform:obj.transform
|
|
lblStoredXform.text = obj.name
|
|
btnRestoreXform.enabled = true
|
|
)
|
|
)
|
|
|
|
on btnRestoreXform pressed do
|
|
(
|
|
if (storedItem != undefined) and (isValidNode storedItem.obj) then
|
|
(
|
|
storedItem.obj.transform = storedItem.transform
|
|
)
|
|
else
|
|
(
|
|
btnRestoreXform.enabled = false
|
|
storedItem = undefined
|
|
)
|
|
)
|
|
|
|
on RsModelToolAlignRoll open do
|
|
(
|
|
setViewAxis btnsRotAxis.state
|
|
)
|
|
|
|
on RsModelToolAlignRoll rolledUp down do
|
|
(
|
|
RsSettingWrite "RsModelToolAlignRoll" "rollup" (not down)
|
|
)
|
|
)
|