2014년 3월 24일 월요일

스프링개량 스크립트 Ver0.8

--------------- 스프링 루트 구간 시작---------------------
createRootPoint = point()
createRootPoint.name = "SpringRoot"
createRootPoint.size = 3.0
createRootPoint.box = true
createRootPoint.cross = false
createRootPoint.wirecolor = (color 200 10 10)
addModifier createRootPoint (EmptyModifier ())
--------------- 스프링 루트 구간 끝---------------------

--------------- 스프링 본 구간 시작---------------------
createBone = Bonesys.createBone[0,0,0][1,0,0][0,0,1]
createBone.name = "SpringBone"
createBone.width = 1
createBone.height = 2
createBone.length = 3
--createBone.boxmode = on
createBone.parent = createRootPoint

createEndBone = Bonesys.createBone[3,0,0][4,0,0][0,0,1]
createEndBone.name = "SpringEndBone"
createEndBone.width = 1
createEndBone.height = 1
createEndBone.length = 1
--createBone.boxmode = on
createEndBone.parent = createBone
--------------- 스프링 본 구간 끝---------------------

--------------- 스프링 포인트 구간 시작---------------------
createSpringPoint = point()
createSpringPoint.name = "SpringPoint"
createSpringPoint.size = 2.0
createSpringPoint.box = false
createSpringPoint.cross = true
createSpringPoint.wirecolor = (color 200 10 10)
createSpringPoint.position = [createBone.length, 0, 0]
createSpringPoint.parent = createRootPoint
createSpringPoint.position.controller =  SpringPositionController()
--------------- 스프링 포인트 구간 끝---------------------

--------------- ExposeTm 구간 시작---------------------
createExpTm = ExposeTm ()
createExpTm.name = "SpringExpTm"
createExpTm.size = 2.0
createExpTm.wirecolor = (color 170 170 170)
createExpTm.parent = createRootPoint
createExpTm.exposeNode = createSpringPoint
createExpTm.useParent  = false
createExpTm.localReferenceNode = createRootPoint
--------------- ExposeTm 구간 끝---------------------

--------------- attrivutes 구간 시작---------------------
springCA = attributes springData
(
parameters main rollout:params
(
yAxisMin type:#float ui:yAxisMin_spi default:-45.0
yAxisMax type:#float ui:yAxisMax_spi default:45.0
zAxisMin type:#float ui:zAxisMin_spi default:-45.0
zAxisMax type:#float ui:zAxisMax_spi default:45.0
forceVal type:#float ui:force_spi default:1.0
editBone type:#integer ui:editBone_cb default:0
)


rollout params "Spring Parameters"
(
spinner yAxisMin_spi "Y-AxisMin " type:#float Range:[-90.0,-1.0,-45.0]
spinner yAxisMax_spi "Y-AxisMax " type:#float Range:[0.0,90.0,45.0]
spinner zAxisMin_spi "Z-AxisMin " type:#float Range:[-90.0,-1.0,-45.0]
spinner zAxisMax_spi "Z-AxisMax " type:#float Range:[0.0,90.0,45.0]
spinner force_spi "Force " type:#float Range:[-100.0,100.0,1.0]
checkbutton editBone_cb "EditBone" checked:false

on editBone_cb changed state do
(
createSpringPoint.position = createEndBone.position
createSpringPoint.rotation = createEndBone.Rotation
editBone_cb.checked = false
)
)
)

ah = createRootPoint.modifiers[#'Attribute Holder']
CustAttributes.add  ah  springCA  #Unique BaseObject:false
--------------- attrivutes 구간 끝---------------------

---------------스프링본에 Rotation_Script_Controller추가 구간 시작------------------
createBone.rotation.controller = rotation_script()
createBone.rotation.controller.script = 
"
y = -(createExpTm.'local Position Z')
z = createExpTm.'local Position Y'
forc = createRootPoint.modifiers[#Attribute_Holder].springData.forceVal
yMinNum = createRootPoint.modifiers[#Attribute_Holder].springData.yAxisMin
yMaxNum = createRootPoint.modifiers[#Attribute_Holder].springData.yAxisMax
zMinNum = createRootPoint.modifiers[#Attribute_Holder].springData.zAxisMin
zMaxNum = createRootPoint.modifiers[#Attribute_Holder].springData.zAxisMax

y = y * forc
z = z * forc

if (y > yMaxNum) do y = yMaxNum

if (y < yMinNum) do y = yMinNum

if (z > zMaxNum) do z = zMaxNum

if (z < zMinNum) do z = zMinNum

rot = eulerAngles 0 y z

rot

"
---------------스프링본에 Rotation_Script_Controller추가 구간 끝------------------

=================================================================================

기존의 맥스 스프링의 경우 포스의 형태가 월드 축을 기준으로 적용되기 때문에 스프링 효과의 X, Y, Z 축을 셋팅하다고 해도 부모노드의 축이 변경된다면 셋팅값이 슬모가 없게 된다.

오토데스크사에서는 왜 이것을 그대로 두는지 모르겠다.
딱히 같은 기능을 하는 다른 명령도 없는데 말이다.

평소에도 가슴본 셋팅을 하면서 이것에 대해 뭔가 해결책이 있을것 이라고 생각했는데, 그간 제대로 고민해 본적은 없다. (물론 이것도 아직 완벽한 스크립트는 아니지만 ㅎㅎ)

이것에 대한 아이디어는 간단했다.
1 스프링 컨트롤러가 적용된 포인터의 Y, Z축의 이동값을 본의 회전값으로 전달한다.
2 회전되는 본의 Rotation Controller를 Script Controller로 특정 각도 이상 회전하지 못하게 한다.

글런데 알고 보니 이미 케릭터 페이셜 리깅에 이런 개념이 있었다. (난 페이셜 컨트롤러를 만들어 본적이 없었기 때문에 이런 간단한것도 몰랐다. ㅠ,.ㅠ)

구현을 해보니 큰 문제가 있었다.
1 이동거리가 회전값이다보니 노드의 크기가 차이가 나면 적용이 너무 작아지거나 너무 커진다.(2미터 짜리 캐릭터의 가슴 움직임 위치값과 20M짜리 캐릭터의 가슴 움직임 위치값은 당연히 차이가 있다)
2 한계 각도가 있기 때문에 한계각도를 넘으면 멈추는것이 당연하지만, 한계값을 넘어가면 스무스하게 멈추지를 못하고 딱 멈춰 버린다.

1번은 내가 수학을 잘한다면 자동으로 해결될 수 있게 할 수 있지만 나는 수학을 못한다. 그래서 공부를 할까 했는데 '낫 놓고 ㄱ자를 모른다.'는 속담이 뭔지 느낄수 있는 계기가 됐다.
그래서 받은값을 곱하기로 증폭하는 수치를 넣었다.(싸게 먹히니까!!!)
2번은 해결방법을 모르겠다.
적당한 함수를 찾아 보려했지만 구할 수가 없었다.
이 두개가 해결된다면 'Ver1.0'이 되겠지만 어쩔 수 없이 'Ver0.8'이다.
뭐 그래도 이정도면 훌륭하게 써먹을 수 있는 녀석이다.

생성되는 오브젝트는 다음과 같다.
SpringRoot - 최종부모이기 때문에 가슴에 이용한다면 바이패드의 Spine에 자식으로 링크를 걸면 된다. 셋팅옵션을 넣을 수 있는 'Attrribute Holder'가 포함된다.
SpringBone - 실제 흔들리는 결과 값을 표현하는 본
SpringEndBone - 본툴을 이용해 'SpringBone'본의 길이를 조정할때와 'SpringPoint'의 위치값을 위한 본
SpringPoint - 'SpringBone'의 흔들리는 가이드를 하는 스프링포인트
SpringExpTm - 'SpringPoint'의 위치값을 부모노드와 얼만큼 멀어지는지를 구하는 역활

생성된 모습에서 빨간 박스형 포인트를 선택하면모디파이어에서 다음과 같은 옵션을 볼 수 있다.

Y, Z - 축의 한계값 셋팅
Force - 가중치를 조정(0은 넣지 말자)
EditBone - 본툴로 본 사이즈를 조절한 후 누르면 스프링포인트위치가 정렬됨



사용법은
1 스크립트를 실행한다.
2 적당한 노드에 링크한다.(단독으로 테스트할때는 필요 없음)
3 메쉬나 오브젝트에 맞게 사이즈 조절한다.(스케일로는 하지는 말것)
4 본 길이가 변경되면 'EditBone'를 한번 누른다.
5 흔들릴 각도를 셋팅한다.
6 스프링포인트가 적당한 값을 갖도록 스프링 셋팅을 한다.
7 본이 스프링에 비슷하게 움직이도록 Force값을 적는다.(스프링포인트가 많이 흔들리는 프레임에서 적용하면 쉽다. 단 적용된값은 바로 표시되지 않으므로 이전프레임으로 갔다가 다시 원래 프레임으로 온다._
8 중간에 본길이를 조정한다면 스프링값이 적용되 않는 프레임(대부분 0프레임)에서 조정하자

언제 수정될지는 모르겠지만 큰 버그가 없는 이상 버전업은 없을것 같다.

2014년 3월 8일 토요일

Boy


Boy from Nlbo75 on Vimeo.

2008년에 작업한 타이페로라는 게임의 작업물이다. 캐쥬얼게임의 캐릭터로 이런저런 공부도 많이했고 애니메이션의 반응도 나쁘지 않았는데 결국 사장이 된게임. 회사를 나온 후에 들은 풍문으론 본전은 뽑았다는것 같다. 무료 툴인 버처덥으로 동영상들을 끼워 맞추려니 튀는 부분이 있다.

2014년 3월 3일 월요일

쫀득리깅


쫀득 from Nlbo75 on Vimeo.

예전에 잠시 진행했던 프로젝트의 캐릭터.
쫀득함을 살리고 파츠교환이 되는 캐릭터의 테스트 모션.
모델링은 다른 분이 작업하셨다.

이때부터 천둥벌거숭이가 리깅에대해 생각하게 된것 같다.
그래도 아직까지 미흡한 부분이 많은것 같다.

타란튤라 테스트


Tarantula from Nlbo75 on Vimeo.

모바일게임용 테스트 몹 타란튤라.
소녀와 다르게 상당히 리얼한 느낌이다.
바이패드 두개를 이어붙여서 실제로 필요없는 본이 꽤 들어있다.
작업한 바이패드 흉내내기 스크립트로 필요한 것만 뽑을 수 있도록 수정해야 할것 같다.
모델링은 다른분이 진행하셨다.

이 몹을 작업하면서 '바이패드 흉내내기 본' 작업을 생각했다.
모델링과 원화를 받고 리얼한느낌에 '보스몹이구나!' 하고 작업을 했는데
나중에 구현된것을 보니 쪼랩 몹이었다.ㅋㅋㅋㅋ
덕분에 애니메이션은 어느정도 덩치가 있는 몹으로 상정하고 작업을 했다.

소녀 테스트 모션


Girl from Nlbo75 on Vimeo.

모바일게임용 테스트 캐릭터.
개인적으론 손발이 작아서 수정을 해야 할것 같다.
(손발의 움직임이 잘 않보인다.)
또한 게임 캐릭터로서 개성이 약한 느낌이다.
모델링은 다른분이 작업하셨다.

테스트를 위해 작업된 모델링이기에 면의 수도 적고, 본의 수도 적기 때문에
표현의 한계가 있다.
색상또한 밝은 색이 대부분이고, 손이 작은 상태에서 옷과 색이 겹치며 동작이 확실히 보이지 않는 느낌이다.

개인적으론 '록맨'이나 '덴마'의 캐릭터같이 손발이 크고 선이 더 굵은 것이 모바일 화면에서 더 좋은 퀄리티를 낼수 있을것 같다.

나중에 여건이 된다면 유니티로 작업된 파일도 올리고 싶다.

2014년 2월 15일 토요일

오브젝트 회전값 구하기_애니키 기준

objName = ""
objFrame = ""
objRotEul = ""
objRotQut = ""
outputStr = ""
txtfilename = ""

selObjs = selection as array

hideByCategory.geometry = true
hideByCategory.helpers = true
hideByCategory.bones = true

if (selObjs.count !=0) then
(
txtfilename = (Filterstring maxFileName ".")[1]
pathFile = maxfilepath + "\\" + txtfilename + ".txt"
filestm = createFile pathFile

for i  = 1 to selObjs.count do
(
objName = selObjs[i].name
outputStr = outputStr + objName + "\n"

if (classof selObjs[i] == Biped_Object) then
(
for j =1 to (selObjs[i].controller.keys).count do
(
sliderTime = selObjs[i].controller.keys[j].time
objFrame = (selObjs[i].controller.keys[j].time) as string
objRotQut = (selObjs[i].transform.rotation) as string
objRotEul = ((selObjs[i].transform.rotation) as eulerAngles) as string

outputStr = outputStr + objFrame + "\t" + objRotEul + "\n"

if((selObjs[i].controller.keys).count == j)do outputStr = outputStr + "\n"
)
)
else
(
for j =1 to (selObjs[i].rotation.controller.keys).count do
(
sliderTime = selObjs[i].rotation.controller.keys[j].time
objFrame = (selObjs[i].rotation.controller.keys[j].time) as string
objRotQut = (selObjs[i].rotation.controller.value) as string
objRotEul = ((selObjs[i].rotation.controller.value) as eulerAngles) as string

outputStr = outputStr + objFrame + "\t" + objRotEul + "\n"

if((selObjs[i].rotation.controller.keys).count == j)do outputStr = outputStr + "\n"
)
)


)
format "%" outputStr to:filestm
close filestm
)
else
(
)

hideByCategory.geometry = false
hideByCategory.helpers = false
hideByCategory.bones = false

===============================================================================

바이패드 또는 그외의 오브젝트들의 애니메이션 키값을 순차 적으로 읽어 해당값의 로테이션 값을 저장하는 스크립트다.
조금더 다듬는다면 맥스파일의 애니메이션 회전값을 다른 맥스파일에 적용하는데 사용될 수있는 스크립트다.

만들게 된 계기가 있는데 다음과 같다.

몇달전에 모 카페에다가 맥스 스크립트를 외주하는것이 실효성이 있는가 하는 의견을 올린적이 있다.
본업은 애니메이션 이긴하지만 회사의 업무에 필요한 맥스 스크립트를 제작하면서, 모바일게임이나 인원수가 적은 업체에서는 스크립트를 작업 할 수 있는 사람을 구하기 힘들어 작업 시간을 줄일 수 있는 일을 줄이지 못해 어려움이 있을것 같다는 생각이 들었기 때문이다.

물론 본격적으로 맥스 스크립트를 공부하고 작업한것이 아니기 때문에 사람들의 답변이 궁금했었다.

그런데 뜬금없이 모 회사에서 스크립트 외주 요청이 들어왔었다.

결국에는 나의 잘못으로 외주 업무를 하지 못했지만, 내심 스크립트도 잘하면 외주를 할수 있는 하나의 업종이 될수 있겠구나 하는 생각이 들었다.

당시 모 회사에서 요청했던 기능을 간단하게 구현한 스크립트다.


결론은 스크립트 공부 열심히 하자!!!

바이패드 복사 본 만들기 ver1.1

bips = #()
bons = #()
boneName = ""
boundingBox = undefined
bipLength = undefined
bipwidth = undefined
bipheight = undefined
selObj = selection as array
objs = #()
rootBipName = ""
filterRootBipName = #()


cNameValue = "Bone"

fn changeName strs oldStr newStr =
(
findFlag = findstring strs oldStr
if (findFlag != undefined) do
(
changeStr = replace strs findFlag oldStr.count newStr
)
changeStr
)

for i = 1 to selObj.count do
(
if (classof selObj[i] == Biped_Object) do append objs selObj[i]
)


if objs.count == 0 then 
(
messagebox "바이패드 노드를 하나 이상 선택하세요."
)

else
(
filterRootBipName = filterstring objs[1].name " "



(execute("$'"+filterRootBipName[1] + "'")).transform.controller.figureMode = true
(execute("$'"+filterRootBipName[1] + "'")).transform.controller.trianglePelvis = false
(execute("$'"+filterRootBipName[1] + "'")).transform.controller.triangleNeck = true
rollout bipMirrbone "흉내 내기본 생성"
(
edittext newNameText "Bip 대신 넣을 이름" text:"Bone"
checkbox twistBon_chk "트위스트본사용" checked:false width:200
checkbox autoNeck_chk "자동본사용" checked:false width:200
Button start_btn  "실행"

on newNameText changed txt do
(
cNameValue = txt
)

on start_btn pressed do
(

for i = 1 to objs.count do
(
if((classof objs[i] == Biped_Object) and (objs[i].name != "Bip01 Footsteps")) do append bips objs[i]
)

clearSelection()

for i = 1 to bips.count do
(
boneName = bips[i].name

boneName = changeName boneName "Bip" cNameValue

boundingBox = nodeGetBoundingBox bips[i]bips[i].transform
bipLength = boundingBox[2].x
bipheight = boundingBox[2].y
bipwidth = boundingBox[2].z
madeBone = Bonesys.createBone[0,0,0][1,0,0][0,0,1]
madeBone.name = boneName
madeBone.width = bipWidth
madeBone.height = bipheight
madeBone.length = bipLength
madeBone.boxmode = on
madeBone.rotation = (inverse(biped.getTransform bips[i] #rotation))
madeBone.position = (bips[i].transform.pos)

if((autoNeck_chk.checked == true)and(matchPattern bips[i].name pattern:"*Neck" == true)) then
(
madeBone.rotation.controller= Orientation_Constraint()
madeBone.rotation.controller.appendTarget bips[i].parent 50.0
madeBone.rotation.controller.appendTarget bips[i].children[1] 50.0
)
else if((autoNeck_chk.checked == true)and(matchPattern bips[i].name pattern:"*Head" == true)) then
(
madeBone.rotation.controller= Orientation_Constraint()
madeBone.rotation.controller.appendTarget bips[i] 50.0

)
else
(
madeBone.position.controller = Position_Constraint() 
madeBone.position.controller.appendTarget bips[i] 50.0
madeBone.rotation.controller= Orientation_Constraint()
madeBone.rotation.controller.appendTarget bips[i] 50.0
)

append bons madeBone
)

for i = 1 to bips.count do
(
if(bips[i].parent != undefined) do
(
parentBip = bips[i].parent
boneName = parentBip.name

boneName = changeName boneName "Bip" cNameValue

bons[i].parent = execute("$'" + boneName + "'")
)
)

filterRootBoneName = filterstring boneName " "

if(twistBon_chk.checked == true) do
(
if((execute  ("$'" + filterRootBoneName[1] + " L Clavicle'") != undefined) and (execute  ("$'" + filterRootBoneName[1] + " L UpperArm'") != undefined) and (execute  ("$'" + filterRootBoneName[1] + " L Forearm'") != undefined)) do
(
-- 왼쪽 어께트위스트1 더미
Point_L_UpperArmTwist02 = point()
Point_L_UpperArmTwist02.name = "Point_L_UpperArmTwist02"
Point_L_UpperArmTwist02.size = 2.0
Point_L_UpperArmTwist02.box = false
Point_L_UpperArmTwist02.cross = true
Point_L_UpperArmTwist02.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " L UpperArm'")) #rotation))
Point_L_UpperArmTwist02.pos = ((execute("$'"+filterRootBipName[1] + " L UpperArm'")).transform.pos)
Point_L_UpperArmTwist02.parent =(execute  ("$'" +  filterRootBoneName[1] + " L Clavicle'"))
Point_L_UpperArmTwist02.pos.controller = Position_Expression()
Point_L_UpperArmTwist02.parent =  (execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'"))
Point_L_UpperArmTwist02.wirecolor = (color 10 10 10)

-- 왼쪽 어께트위스트2 더미
Point_L_UpperArmTwist01 = point()
Point_L_UpperArmTwist01.name = "Point_L_UpperArmTwist01"
Point_L_UpperArmTwist01.size = 2.0
Point_L_UpperArmTwist01.box = true
Point_L_UpperArmTwist01.cross = false
Point_L_UpperArmTwist01.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " L Clavicle'")) #rotation))
Point_L_UpperArmTwist01.pos = ((execute("$'"+filterRootBipName[1] + " L Clavicle'")).transform.pos)
Point_L_UpperArmTwist01.parent = (execute  ("$'" +  filterRootBoneName[1] + " L Clavicle'"))
Point_L_UpperArmTwist01.rotation.controller=LookAt_Constraint()
Point_L_UpperArmTwist01.rotation.controller.appendTarget $'Point_L_UpperArmTwist02' 50.0
Point_L_UpperArmTwist01.rotation.controller.viewline_length_abs = false
Point_L_UpperArmTwist01.rotation.controller.upnode_world = false
Point_L_UpperArmTwist01.rotation.controller.pickUpNode = (execute  ("$'" +  filterRootBoneName[1] + " L Clavicle'"))
Point_L_UpperArmTwist01.wirecolor = (color 10 10 10)

-- 왼쪽 어께 트위스트1,2 본
LUpperArmTwist01 = Bonesys.createBone[0,0,0][1,0,0][0,0,1]
LUpperArmTwist01.name =  filterRootBoneName[1] +" L UpperArmTwist01"
LUpperArmTwist01.width = ((execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")).width) * 0.8
LUpperArmTwist01.height = ((execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")).height) * 0.8
LUpperArmTwist01.length = ((execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")).length) / 4
LUpperArmTwist02 = Bonesys.createBone[(((execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")).length) / 4),0,0][1,0,0][0,0,1]
LUpperArmTwist02.name =  filterRootBoneName[1] + " L UpperArmTwist02"
LUpperArmTwist02.width = ((execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")).width) * 0.8
LUpperArmTwist02.height = ((execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")).height) * 0.8
LUpperArmTwist02.length = ((execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")).length) / 3
LUpperArmTwist02.parent = LUpperArmTwist01
LUpperArmTwist01.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " L UpperArm'")) #rotation))
LUpperArmTwist01.pos = ((execute("$'"+filterRootBipName[1] + " L UpperArm'")).transform.pos)
LUpperArmTwist01.parent = (execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'"))
LUpperArmTwist02.parent = (execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'"))
LUpperArmTwist01.rotation.controller=LookAt_Constraint()
LUpperArmTwist01.rotation.controller.appendTarget (execute  ("$'" +  filterRootBoneName[1] + " L Forearm'"))  50.0
LUpperArmTwist01.rotation.controller.viewline_length_abs = false
LUpperArmTwist01.rotation.controller.upnode_world = false
LUpperArmTwist01.rotation.controller.pickUpNode = Point_L_UpperArmTwist01
LUpperArmTwist01.wirecolor = (color 10 10 10)
LUpperArmTwist01.boxmode = on

LUpperArmTwist02.rotation.controller=Orientation_Constraint()
LUpperArmTwist02.rotation.controller.appendTarget LUpperArmTwist01 60.0
LUpperArmTwist02.rotation.controller.appendTarget (execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")) 40.0
LUpperArmTwist02.wirecolor = (color 10 10 10)
LUpperArmTwist02.boxmode = on
)

if((execute  ("$'" +  filterRootBoneName[1] + " R Clavicle'") != undefined) and (execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'") != undefined) and (execute  ("$'" +  filterRootBoneName[1] + " R Forearm'") != undefined)) do
(
-- 오른쪽 어께트위스트1 더미
Point_R_UpperArmTwist02 = point()
Point_R_UpperArmTwist02.name = "Point_R_UpperArmTwist02"
Point_R_UpperArmTwist02.size = 2.0
Point_R_UpperArmTwist02.box = false
Point_R_UpperArmTwist02.cross = true
Point_R_UpperArmTwist02.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " R UpperArm'")) #rotation))
Point_R_UpperArmTwist02.pos = ((execute("$'"+filterRootBipName[1] + " R UpperArm'")).transform.pos)
Point_R_UpperArmTwist02.parent =(execute  ("$'" +  filterRootBoneName[1] + " R Clavicle'"))
Point_R_UpperArmTwist02.pos.controller = Position_Expression()
Point_R_UpperArmTwist02.parent =  (execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'"))
Point_R_UpperArmTwist02.wirecolor = (color 10 10 10)

-- 오른쪽 어께트위스트2 더미
Point_R_UpperArmTwist01 = point()
Point_R_UpperArmTwist01.name = "Point_R_UpperArmTwist01"
Point_R_UpperArmTwist01.size = 2.0
Point_R_UpperArmTwist01.box = true
Point_R_UpperArmTwist01.cross = false
Point_R_UpperArmTwist01.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " R Clavicle'")) #rotation))
Point_R_UpperArmTwist01.pos = ((execute("$'"+filterRootBipName[1] + " R Clavicle'")).transform.pos)
Point_R_UpperArmTwist01.parent = (execute  ("$'" +  filterRootBoneName[1] + " R Clavicle'"))
Point_R_UpperArmTwist01.rotation.controller=LookAt_Constraint()
Point_R_UpperArmTwist01.rotation.controller.appendTarget $'Point_R_UpperArmTwist02' 50.0
Point_R_UpperArmTwist01.rotation.controller.viewline_length_abs = false
Point_R_UpperArmTwist01.rotation.controller.upnode_world = false
Point_R_UpperArmTwist01.rotation.controller.pickUpNode = (execute  ("$'" +  filterRootBoneName[1] + " R Clavicle'"))
Point_R_UpperArmTwist01.wirecolor = (color 10 10 10)

-- 오른쪽 어께 트위스트1,2 본
RUpperArmTwist01 = Bonesys.createBone[0,0,0][1,0,0][0,0,1]
RUpperArmTwist01.name =  filterRootBoneName[1] +" R UpperArmTwist01"
RUpperArmTwist01.width = ((execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'")).width) * 0.8
RUpperArmTwist01.height = ((execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'")).height) * 0.8
RUpperArmTwist01.length = ((execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'")).length) / 4
RUpperArmTwist02 = Bonesys.createBone[(((execute  ("$'" +  filterRootBoneName[1] + " L UpperArm'")).length) / 4),0,0][1,0,0][0,0,1]
RUpperArmTwist02.name =  filterRootBoneName[1] + " R UpperArmTwist02"
RUpperArmTwist02.width = ((execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'")).width) * 0.8
RUpperArmTwist02.height = ((execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'")).height) * 0.8
RUpperArmTwist02.length = ((execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'")).length) / 4
RUpperArmTwist02.parent = RUpperArmTwist01
RUpperArmTwist01.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " R UpperArm'")) #rotation))
RUpperArmTwist01.pos = ((execute("$'"+filterRootBipName[1] + " R UpperArm'")).transform.pos)
RUpperArmTwist01.parent = (execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'"))
RUpperArmTwist02.parent = (execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'"))
RUpperArmTwist01.rotation.controller=LookAt_Constraint()
RUpperArmTwist01.rotation.controller.appendTarget (execute  ("$'" +  filterRootBoneName[1] + " R Forearm'"))  50.0
RUpperArmTwist01.rotation.controller.viewline_length_abs = false
RUpperArmTwist01.rotation.controller.upnode_world = false
RUpperArmTwist01.rotation.controller.pickUpNode = Point_R_UpperArmTwist01
RUpperArmTwist01.wirecolor = (color 10 10 10)
RUpperArmTwist01.boxmode = on

RUpperArmTwist02.rotation.controller=Orientation_Constraint()
RUpperArmTwist02.rotation.controller.appendTarget RUpperArmTwist01 60.0
RUpperArmTwist02.rotation.controller.appendTarget (execute  ("$'" + filterRootBoneName[1] + " R UpperArm'")) 40.0
RUpperArmTwist02.wirecolor = (color 10 10 10)
RUpperArmTwist02.boxmode = on
)

if((execute  ("$'" +  filterRootBoneName[1] + " L Forearm'") != undefined) and (execute  ("$'" +  filterRootBoneName[1] + " L Hand'") != undefined)) do
(
-- 왼쪽 손목 트위스트 본
L_ForearmTwist = Bonesys.createBone[0,0,0][1,0,0][0,0,1]
L_ForearmTwist.name =  filterRootBoneName[1] + " L_ForearmTwist"
L_ForearmTwist.width = ((execute  ("$'" +  filterRootBoneName[1] + " L Forearm'")).width) * 0.8
L_ForearmTwist.height = ((execute  ("$'" +  filterRootBoneName[1] + " L Forearm'")).height) * 0.8
L_ForearmTwist.length = ((execute  ("$'" +  filterRootBoneName[1] + " L Forearm'")).length) / 4
L_ForearmTwist.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " L Forearm'")) #rotation))
L_ForearmTwist.pos = ((execute("$'"+filterRootBipName[1] + " L Forearm'")).transform.pos)
coordsys local move L_ForearmTwist [((execute  ("$'" + filterRootBoneName[1] + " L UpperArm'")).length) - (((execute  ("$'" + filterRootBoneName[1] + " L UpperArm'")).length) / 4),0,0]
L_ForearmTwist.parent = (execute  ("$'" +  filterRootBoneName[1] + " L Forearm'"))
L_ForearmTwist.rotation.controller=LookAt_Constraint()
L_ForearmTwist.rotation.controller.appendTarget (execute  ("$'" +  filterRootBoneName[1] + " L Hand'")) 50.0
L_ForearmTwist.rotation.controller.viewline_length_abs = false
L_ForearmTwist.rotation.controller.upnode_world = false
L_ForearmTwist.rotation.controller.pickUpNode = (execute  ("$'" +  filterRootBoneName[1] + " L Hand'"))
L_ForearmTwist.wirecolor = (color 10 10 10)
L_ForearmTwist.boxmode = on
)

if((execute  ("$'" +  filterRootBoneName[1] + " R Forearm'") != undefined) and (execute  ("$'" +  filterRootBoneName[1] + " R Hand'") != undefined)) do
(
-- 오른쪽 손목 트위스트 본
R_ForearmTwist = Bonesys.createBone[0,0,0][1,0,0][0,0,1]
R_ForearmTwist.name =  filterRootBoneName[1] + " R_ForearmTwist"
R_ForearmTwist.width = ((execute  ("$'" +  filterRootBoneName[1] + " R Forearm'")).width) * 0.8
R_ForearmTwist.height = ((execute  ("$'" +  filterRootBoneName[1] + " R Forearm'")).height) * 0.8
R_ForearmTwist.length = ((execute  ("$'" +  filterRootBoneName[1] + " R Forearm'")).length) / 4
R_ForearmTwist.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " R Forearm'")) #rotation))
R_ForearmTwist.pos = ((execute("$'"+filterRootBipName[1] + " R Forearm'")).transform.pos)
coordsys local move R_ForearmTwist [((execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'")).length) - (((execute  ("$'" +  filterRootBoneName[1] + " R UpperArm'")).length) / 4),0,0]
R_ForearmTwist.parent = (execute  ("$'" +  filterRootBoneName[1] + " R Forearm'"))
R_ForearmTwist.rotation.controller=LookAt_Constraint()
R_ForearmTwist.rotation.controller.appendTarget (execute  ("$'" +  filterRootBoneName[1] + " R Hand'")) 50.0
R_ForearmTwist.rotation.controller.viewline_length_abs = false
R_ForearmTwist.rotation.controller.upnode_world = false
R_ForearmTwist.rotation.controller.pickUpNode = (execute  ("$'" +  filterRootBoneName[1] + " R Hand'"))
R_ForearmTwist.wirecolor = (color 10 10 10)
R_ForearmTwist.boxmode = on
)

if(((execute  ("$'" +  filterRootBoneName[1] + " L Thigh'")) != undefined) and ((execute  ("$'" +  filterRootBoneName[1] + " L Calf'")) != undefined)) do
(
-- 왼쪽 허벅지 트위스트 ExposeTM
ExposeTransformL = ExposeTransform()
ExposeTransformL.name = "ExposeTransform L"
ExposeTransformL.size = 1.5
ExposeTransformL.box = true
ExposeTransformL.cross = false
ExposeTransformL.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " L Thigh'")) #rotation))
ExposeTransformL.pos = ((execute("$'"+filterRootBipName[1] + " L Thigh'")).transform.pos)
ExposeTransformL.parent = (execute  ("$'" +  filterRootBoneName[1] + " L Thigh'"))
ExposeTransformL.exposeNode = (execute  ("$'" +  filterRootBoneName[1] + " L Calf'"))
ExposeTransformL.useParent = false
ExposeTransformL.localReferenceNode  = (execute  ("$'" +  filterRootBoneName[1] + " Pelvis'"))
ExposeTransformL.wirecolor = (color 10 10 10)

-- 왼쪽 허벅지 트위스트 더미
PointLThigh = point()
PointLThigh.name =  filterRootBoneName[1] + " Point L Thigh"
PointLThigh.size = 1.0
PointLThigh.box = false
PointLThigh.cross = true
PointLThigh.pos = ((execute("$'"+filterRootBipName[1] + " Pelvis'")).transform.pos)
coordsys local move PointLThigh [10,0,0]
PointLThigh.parent = (execute  ("$'" +  filterRootBoneName[1] + " Pelvis'"))
reactContL = PointLThigh.pos.controller = Position_reactor()
PointLThigh.wirecolor = (color 10 10 10)

-- 왼쪽 허벅지 트위스트 본
L_ThighTwist = Bonesys.createBone[0,0,0][1,0,0][0,0,1]
L_ThighTwist.name =  filterRootBoneName[1] + " L_ThighTwist"
L_ThighTwist.width = ((execute  ("$'" +  filterRootBoneName[1] + " L Thigh'")).width) * 0.8
L_ThighTwist.height = ((execute  ("$'" +  filterRootBoneName[1] + " L Thigh'")).height) * 0.8
L_ThighTwist.length = ((execute  ("$'" +  filterRootBoneName[1] + " L Thigh'")).length) / 4
L_ThighTwist.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " L Thigh'")) #rotation))
L_ThighTwist.pos = ((execute("$'"+filterRootBipName[1] + " L Thigh'")).transform.pos)
L_ThighTwist.parent = (execute  ("$'" +  filterRootBoneName[1] + " L Thigh'"))
L_ThighTwist.rotation.controller=LookAt_Constraint()
L_ThighTwist.rotation.controller.appendTarget  (execute  ("$'" +  filterRootBoneName[1] + " L Calf'")) 50.0
L_ThighTwist.rotation.controller.viewline_length_abs = false
L_ThighTwist.rotation.controller.upnode_world = false
L_ThighTwist.rotation.controller.pickUpNode = (execute  ("$'" +  filterRootBoneName[1] + " Point L Thigh'"))
L_ThighTwist.rotation.controller.upnode_ctrl = 0
L_ThighTwist.rotation.controller.StoUP_axisFlip = true
L_ThighTwist.wirecolor = (color 10 10 10)
L_ThighTwist.boxmode = on

reactContL.reactTo $'ExposeTransform L'.localPosition.controller
)

if(((execute  ("$'" +  filterRootBoneName[1] + " R Thigh'")) != undefined) and ((execute  ("$'" +  filterRootBoneName[1] + " R Calf'")) != undefined)) do
(
-- 오른쪽 허벅지 트위스트 ExposeTM
ExposeTransformR = ExposeTransform()
ExposeTransformR.name = "ExposeTransform R"
ExposeTransformR.size = 1.5
ExposeTransformR.box = true
ExposeTransformR.cross = false
ExposeTransformR.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " R Thigh'")) #rotation))
ExposeTransformR.pos = ((execute("$'"+filterRootBipName[1] + " R Thigh'")).transform.pos)
ExposeTransformR.parent = (execute  ("$'" +  filterRootBoneName[1] + " R Thigh'"))
ExposeTransformR.exposeNode = (execute  ("$'" +  filterRootBoneName[1] + " R Calf'"))
ExposeTransformR.useParent = false
ExposeTransformR.localReferenceNode  = (execute  ("$'" +  filterRootBoneName[1] + " Pelvis'"))
ExposeTransformR.wirecolor = (color 10 10 10)

-- 오른쪽 허벅지 트위스트 더미
PointRThigh = point()
PointRThigh.name =  filterRootBoneName[1] + " Point R Thigh"
PointRThigh.size = 1.0
PointRThigh.box = false
PointRThigh.cross = true
PointRThigh.pos = ((execute("$'"+filterRootBipName[1] + " Pelvis'")).transform.pos)
coordsys local move PointRThigh [-10,0,0]
PointRThigh.parent = ((execute  ("$'" +  filterRootBoneName[1] + " Pelvis'")))
reactContR = PointRThigh.pos.controller = Position_reactor()
PointRThigh.wirecolor = (color 10 10 10)

-- 오른쪽 허벅지 트위스트 본
R_ThighTwist = Bonesys.createBone[0,0,0][1,0,0][0,0,1]
R_ThighTwist.name =  filterRootBoneName[1] + " R_ThighTwist"
R_ThighTwist.width = ((execute  ("$'" +  filterRootBoneName[1] + " R Thigh'")).width) * 0.8
R_ThighTwist.height = ((execute  ("$'" +  filterRootBoneName[1] + " R Thigh'")).height) * 0.8
R_ThighTwist.length = ((execute  ("$'" +  filterRootBoneName[1] + " R Thigh'")).length) / 4
R_ThighTwist.rotation = (inverse(biped.getTransform (execute("$'"+filterRootBipName[1] + " R Thigh'")) #rotation))
R_ThighTwist.pos = ((execute("$'"+filterRootBipName[1] + " R Thigh'")).transform.pos)
R_ThighTwist.parent = (execute  ("$'" +  filterRootBoneName[1] + " R Thigh'"))
R_ThighTwist.rotation.controller=LookAt_Constraint()
R_ThighTwist.rotation.controller.appendTarget  (execute  ("$'" +  filterRootBoneName[1] + " R Calf'")) 50.0
R_ThighTwist.rotation.controller.viewline_length_abs = false
R_ThighTwist.rotation.controller.upnode_world = false
R_ThighTwist.rotation.controller.pickUpNode = (execute  ("$'" +  filterRootBoneName[1] + " Point R Thigh'"))
R_ThighTwist.rotation.controller.upnode_ctrl = 0
R_ThighTwist.wirecolor = (color 10 10 10)
R_ThighTwist.boxmode = on

reactContR.reactTo $'ExposeTransform R'.localPosition.controller
)
)
select bons
destroydialog bipMirrbone
)
)
createdialog bipMirrbone
)
================================================================================

아는 동생의 집에서 이 스크립트를 사용했는데 문제가 발생했다.
확인해 본 결과 종전의 맥스버전에서는 당연히 바이패드가 'Bip01'로 지정이 되는데
2012, 2013버전에서는 'Bip001'로 변경된것이다.
허거덩~~~~
물론 바이패드 이름을 'Bip01'로 변경해주면 되지만 그건 그거 나름대로 스크립트 작업자로서 거부감이 들어서 수정작업을 했다.
수정을 하면서 보니 트위스트 본에도 문제가 있다는것을 알았다.
조금더 확인 한다음에 올릴걸~~ㅠ,.ㅠ

아무튼 수정하여 올린다.