Friday, October 22, 2010

Ribbon :Part1:

" Ribbon "
    การทำ Ribbon นั้นมีไว้เพื่อเป็นการช่วยให้ animator นั้นสามารถจัดโพสของแขนหรือขาเพื่อให้ได้ silhouette ได้ตามที่ต้องการหรือเอาไว้แก้ไข shape หรือ Pose ของตัวละครเราได้เราลองไปดูการทำ Ribbon กันเลยดีกว่า

ขั้นแรกเลยเราจะทำการสร้าง Nurbs Plans ขึ้นมาก่อนในที่นี้้เราจะใส่ค่าดังนี้
     - Rotate X = 90
     - Scale Z = 5
ใน makeNurbPlane1
     - PatchesU = 1
     - PatchesV = 5



หลังจากนั้นจะ Freeze Transformation แล้วก็ Delete History แล้วตั่งชื่อ "Test_rbbnelemIIILFT_nrb" แล้วเราจะสร้าง Curve ขึ้นมาโดยไปที่ Option Box ของ CV Curve Tool แล้วเลือก 3 Cubic
แล้วสร้างให้อยู่กลางแผ่น Nurbs จากบนลงล่างให้พอดีแล้วให้ไปที่ Rebuilt Curve
โดยเลือก " Number of Spans = 5 "ก็จะได้ Curve CV ที่อยู่ตรงเส้นพอด
แล้วก็ตั่งชื่อเป็น "Test_rbbnelemIIILFT_crv"



ทีนี้เราจะมาหาความยาว Curve นี้โดยการสร้าง CurveInfo โดยเลือก Curve แล้วไปพิมพ์ใน mel Boxว่า"arclen -ch 1"แล้วตั่งชื่อ Nodeนี้ว่า"Test_rbbnelemStretchIIILFT_crvinfo"ซึ่งเอาไว้สามารถดู Arclenght ของ Curve นี้ได้ จากนั้นเลือก Nurbs แล้ว add attribute ตามนี้
    - arclen
    - divider
    - squash
เสร็จแล้วจะ Group เข้าไว้ด้วยกันแล้วตั่งชื่อ "Test_rbbnelemStillAllIIILFT_grp"
ต่อมาผมจะทำ Group เปล่าขึ้นมาเพื่อเอาไวให้มันเกาะอยู่กับ Nurbs สร้างและตั่งชื่อตามนี้

    - Test_rbbnelem1IIILFT_folicle
    - Test_rbbnelem2IIILFT_folicle
    - Test_rbbnelem3IIILFT_folicle
    - Test_rbbnelem4IIILFT_folicle
    - Test_rbbnelem5IIILFT_folicle

แล้ว Group รวมกันทั้งหมดและตั่งชื่อ "Test_rbbnelemIIILFT_folicleGrp"
ในการที่เราจะทำให้มันเกาะกับ Nurbs นั้นในวิธีนี้เราจะใช้ Node pointOnSurface การที่ใช้ Node นี้มันจะช่วยแก้ปัญหาเรื่องการ Flip ได้มากการสร้างให้ไปที่ Mel Box แล้วพิมพิ์ว่า "createNode pointOnSurfaceInfo" มา 5Node แล้วตั่งชื่อตามนี้

    - Test_rbbnelem1IIILFT_foliclePosi
    - Test_rbbnelem2IIILFT_foliclePosi
    - Test_rbbnelem3IIILFT_foliclePosi
    - Test_rbbnelem4IIILFT_foliclePosi
    - Test_rbbnelem5IIILFT_foliclePosi

เมื่อได้ Node มาครบแล้วจะทำการ Connect เพื่อให้ได้ตำแหน่งบน Nurbs โดยเราจะconnect
.worldSpace ของ Nurbs ไปเข้าที่ .inputSurface ของ pointOnSurface แต่ละอันวิธีนี้สามารถทำได้จาก Connection Editior หรือ Script Editor ได้
ถ้าใช้ Script Editor จะมีวิธีดังนี้

connectAttr -f Test_rbbnelem1IIILFT_nrbShape.worldSpace[0] Test_rbbnelem1IIILFT_foliclePosi.inputSurface;
connectAttr -f Test_rbbnelem2IIILFT_nrbShape.worldSpace[0] Test_rbbnelem2IIILFT_foliclePosi.inputSurface;
connectAttr -f Test_rbbnelem3IIILFT_nrbShape.worldSpace[0] Test_rbbnelem3IIILFT_foliclePosi.inputSurface;
connectAttr -f Test_rbbnelem4IIILFT_nrbShape.worldSpace[0] Test_rbbnelem4IIILFT_foliclePosi.inputSurface;
connectAttr -f Test_rbbnelem5IIILFT_nrbShape.worldSpace[0] Test_rbbnelem5IIILFT_foliclePosi.inputSurface;

จากนั้นเราจะเอาค่าของ .position ของ pointOnSurface มาconnectเข้า .translate ของ Test_rbbnelem#IIILFT_folicle ของแต่ละอัน

connectAttr -f Test_rbbnelem1IIILFT_foliclePosi.position Test_rbbnelem1IIILFT_folicle.translate;
connectAttr -f Test_rbbnelem2IIILFT_foliclePosi.position Test_rbbnelem2IIILFT_folicle.translate;
connectAttr -f Test_rbbnelem3IIILFT_foliclePosi.position Test_rbbnelem3IIILFT_folicle.translate;
connectAttr -f Test_rbbnelem4IIILFT_foliclePosi.position Test_rbbnelem4IIILFT_folicle.translate;
connectAttr -f Test_rbbnelem5IIILFT_foliclePosi.position Test_rbbnelem5IIILFT_folicle.translate;

หลังจาก Connect .translate ไปแล้วให้ไปเลือก pointOnSurface มาปรับตำแหน่งตามต้องการโดยไปแก้ใน
attribute Editor โดยแก้ที่ค่า Parameter  U = 0.5 กับ V=ตำแหน่งที่เราต้องการ เราสามารถดูตำแหน่งได้จาก
Group ที่เรา connect .translate เข้าไปแล้วไปเลือก Display > Transfoem Display > Local Rotationn Axesโดยค่า Parameter จะได้แบบนี้

- Test_rbbnelem1IIILFT_foliclePosi [U = 0.5 , V = 0.1]
- Test_rbbnelem2IIILFT_foliclePosi [U = 0.5 , V = 0.3]
- Test_rbbnelem3IIILFT_foliclePosi [U = 0.5 , V = 0.5]
- Test_rbbnelem4IIILFT_foliclePosi [U = 0.5 , V = 0.7]
- Test_rbbnelem5IIILFT_foliclePosi [U = 0.5 , V = 0.9]

เมื่อเสร็จแล้วทีนี้เราจะมาสร้าง Node aimConstraint ขึ้นมา Node นี้มีไว้เพื่อ
พิมพิ์ใน mel box "createNode aimConstraint"

เข้าไปที่ attribute Editor ของ aim แต่ละnodeแล้วให้เปลี่ยนค่า
Aim Vector    0     0    1
Up Vector     0     1    0
แล้วตั่งชื่อตามนี้
    - Test_rbbnelem1IIILFT_folicleAim
    - Test_rbbnelem2IIILFT_folicleAim
    - Test_rbbnelem3IIILFT_folicleAim
    - Test_rbbnelem4IIILFT_folicleAim
    - Test_rbbnelem5IIILFT_folicleAim

เริ่มจากเราจะ connect ค่า .tangentV จาก foliclePosi ไปconnectกับ .worldSpace ของ folicleAim

connectAttr -f Test_rbbnelem1IIILFT_foliclePosi.tangentV Test_rbbnelem1IIILFT_folicleAim.WorldUpVector;
connectAttr -f Test_rbbnelem2IIILFT_foliclePosi.tangentV Test_rbbnelem2IIILFT_folicleAim.worldUpVector;
connectAttr -f Test_rbbnelem3IIILFT_foliclePosi.tangentV Test_rbbnelem3IIILFT_folicleAim.worldUpVector;
connectAttr -f Test_rbbnelem4IIILFT_foliclePosi.tangentV Test_rbbnelem4IIILFT_folicleAim.worldUpVector;
connectAttr -f Test_rbbnelem5IIILFT_foliclePosi.tangentV Test_rbbnelem5IIILFT_folicleAim.worldUpVector;

แล้วก็ connect ค่า .normal ไปยัง .target[0].targetTranslate ซึ่งจะใช้ connection Editor ทำไม่ได้ต้องแบบนี้

connectAttr -f Test_rbbnelem1IIILFT_foliclePosi.normal Test_rbbnelem1IIILFT_folicleAim.target[0].targetTranslate;
connectAttr -f Test_rbbnelem2IIILFT_foliclePosi.normal Test_rbbnelem2IIILFT_folicleAim.target[0].targetTranslate;
connectAttr -f Test_rbbnelem3IIILFT_foliclePosi.normal Test_rbbnelem3IIILFT_folicleAim.target[0].targetTranslate;
connectAttr -f Test_rbbnelem4IIILFT_foliclePosi.normal Test_rbbnelem4IIILFT_folicleAim.target[0].targetTranslate;
connectAttr -f Test_rbbnelem5IIILFT_foliclePosi.normal Test_rbbnelem5IIILFT_folicleAim.target[0].targetTranslate;

สุดท้ายเราจะ connect .constraintRotate[x,y,z] ของ FolicleAim ไปยัง .rotate[x,y,z] ของ folicle

connectAttr -f Test_rbbnelem1IIILFT_folicleAim.constraintRotateX Test_rbbnelem1IIILFT_folicle.rotateX;
connectAttr -f Test_rbbnelem1IIILFT_folicleAim.constraintRotateY Test_rbbnelem1IIILFT_folicle.rotateY;
connectAttr -f Test_rbbnelem1IIILFT_folicleAim.constraintRotateZ Test_rbbnelem1IIILFT_folicle.rotateZ;

connectAttr -f Test_rbbnelem2IIILFT_folicleAim.constraintRotateX Test_rbbnelem2IIILFT_folicle.rotateX;
connectAttr -f Test_rbbnelem2IIILFT_folicleAim.constraintRotateY Test_rbbnelem2IIILFT_folicle.rotateY;
connectAttr -f Test_rbbnelem2IIILFT_folicleAim.constraintRotateZ Test_rbbnelem2IIILFT_folicle.rotateZ;

connectAttr -f Test_rbbnelem3IIILFT_folicleAim.constraintRotateX Test_rbbnelem3IIILFT_folicle.rotateX;
connectAttr -f Test_rbbnelem3IIILFT_folicleAim.constraintRotateY Test_rbbnelem3IIILFT_folicle.rotateY;
connectAttr -f Test_rbbnelem3IIILFT_folicleAim.constraintRotateZ Test_rbbnelem3IIILFT_folicle.rotateZ;

connectAttr -f Test_rbbnelem4IIILFT_folicleAim.constraintRotateX Test_rbbnelem4IIILFT_folicle.rotateX;
connectAttr -f Test_rbbnelem4IIILFT_folicleAim.constraintRotateY Test_rbbnelem4IIILFT_folicle.rotateY;
connectAttr -f Test_rbbnelem4IIILFT_folicleAim.constraintRotateZ Test_rbbnelem4IIILFT_folicle.rotateZ;

connectAttr -f Test_rbbnelem5IIILFT_folicleAim.constraintRotateX Test_rbbnelem5IIILFT_folicle.rotateX;
connectAttr -f Test_rbbnelem5IIILFT_folicleAim.constraintRotateY Test_rbbnelem5IIILFT_folicle.rotateY;
connectAttr -f Test_rbbnelem5IIILFT_folicleAim.constraintRotateZ Test_rbbnelem5IIILFT_folicle.rotateZ;

เป็นการเสร็จในขั้นตอนนี้ก่อน
(อย่าลืม Parent Test_rbbnelem1IIILFT_folicleAim เข้าไปไว้ใน Test_rbbnelem1IIILFT_folicle ของแต่ละอัน)

เริ่มกันต่อเลยหล้งจากที่ทำตามขั้นต้นมาแล้วเราจะทำการสร้าง joint + Control ขึ้นมาและตั่งชื่อตามนี้
- สร้าง Joint แล้วทำการ Group ของแต่ละ joint และตั่งชื่อตามนี้ให้พิมพิ์ใน mel box "createNode joint"

    - Test_rbbnelem1JntIIILFT_grp
        - Test_rbbnelem1IIILFT_jnt
    - Test_rbbnelem2JntIIILFT_grp
        - Test_rbbnelem2IIILFT_jnt
    - Test_rbbnelem3JntIIILFT_grp
        - Test_rbbnelem3IIILFT_jnt
    - Test_rbbnelem4JntIIILFT_grp
        - Test_rbbnelem4IIILFT_jnt
    - Test_rbbnelem5JntIIILFT_grp
        - Test_rbbnelem5IIILFT_jnt

แล้ว Group รวมกันแล้วตั่งชื่อ "Test_rbbnelemJntAllIIILFT_grp"
- สร้าง Control มา6อันมี [Circle = 5, square = 1 ] และตั่งชื่อตามนี้

    - "square"
    - Test_rbbnelemMidCtrlIIILFT_zG
        - Test_rbbnelemMidIIILFT_ctrl

    - "circle"
    - Test_rbbnelem1CTRLIIILFT_zG
        - Test_rbbnelem1IIILFT_ctrl
    - Test_rbbnelem2CTRLIIILFT_zG
        - Test_rbbnelem2IIILFT_ctrl
    - Test_rbbnelem3CTRLIIILFT_zG
        - Test_rbbnelem3IIILFT_ctrl
    - Test_rbbnelem4CTRLIIILFT_zG
        - Test_rbbnelem4IIILFT_ctrl
    - Test_rbbnelem5CTRLIIILFT_zG
        - Test_rbbnelem5IIILFT_ctrl

แล้ว add attribute "Squash" ให้กับcontrolด้วย
แล้ว Group รวมกันแล้วตั่งชื่อ "Test_rbbnelemCTRLAllIIILFT_grp"

เมื่อเรามีทั้ง joint แล้ว control แล้วก็ให้เราทำการย้ายตำแหน่งไปไว้ทีเดียวกับ pointOnSurfaceโดยเลือก Test_rbbnelem#IIILFT_folicle ก่อนแล้วเลือก Test_rbbnelem#JntIIILFT_grp
แล้วก็ใช้ Point Constrain กับ Orient Constraint ซึ่งจะได้ตามแบบนแล้วให้เรา Break Connection ของ Rotate Y ออกให้หมด

เมื่อเราย้ายตำแหน่ง joint ไปแล้วคราวนี้เรามาย้ายตำแหน่งของ Control กันบ้าง
โดยเลือก Test_rbbnelem#JntIIILFT_grp ก่อนแล้วเลือก Test_rbbnelem#CTRLIIILFT_zG
แล้วก็ใช้ Parent Constrain โดยใน option ให้เอา Maintain Offset ออกด้วยแล้วเอา
Test_rbbnelem#IIILFT_ctrl ของแต่ละอัน Parent Constrain เข้ากับ Test_rbbnelem#IIILFT_jnt

เป็นการเสร็จในส่วนของ Part1 ไว้เรามาต่อกันใน Part2 นะครับ

No comments:

Post a Comment