Friday 18 March 2011

Post 12- Arm Twist Bones and Hand Controls

I have just finished constructing the twist bones. The twist bones run down the arm and are aligned and linked to the bones they sit on. These are then linked to the wrist control. The orientation constraint is then applied and shared between the two (same as the spine). This allows for the immediate twist bone to twist at 100%, and the secondary one to twist at 50%. The upper twist bone is twisted using additional 'Float Expressions' in order to create a relationship between the elbow control and the clavicle. The controls are then wired to the main waist controller so that when this is moved, the rig moves with it, without disturbing any poses that are present. 

The main hurdle was now creating the bones for the fingers and using MaxScript to create the controls (similar to the foot) First, I used the plugin script known as PEN_ATTRIBUTE_HOLDER. This allows for any spline (e.g. the circle above the hand) to become a store for controls. Once this was established, a series of Max scripted sliders and spinners were made. These were extremely complicated. I cannot take all the credit for this as the DVD set by Paul Neale gives an example of one such control. My job was to now repeat this controller, but for every digit and column.

The final Max Script for the hand digits are is as follows:
ca=attributes HandControls
(
            parameters thumbP rollout: thumbR
            (
                        thumb01 type:#float ui: (thumb01Sp,thumb01Sl)
                        thumb02 type:#float ui: (thumb02Sp,thumb02Sl)
                        thumb03 type:#float ui: (thumb03Sp,thumb03Sl)
                        thumb04 type:#float ui: (thumb04Sp,thumb04Sl)
                       
            )
            parameters indexP rollout:indexR
            (                      
                        index01 type:#float ui: (index01Sp,index01Sl)
                        index02 type:#float ui: (index02Sp, index02Sl)
                        indexSplay type:#float ui: (indexSplaySp,indexSplaySl)
           
            )
            parameters middleP rollout:middleR
            (
                        middle01 type:#float ui: (middle01Sp,middle01Sl)
                        middle02 type:#float ui: (middle02Sp,middle02Sl)
                        middleSplay type:#float ui: (middleSplaySp,middleSplaySl)
            )
            parameters ringP rollout:ringR
            (
                        ring01 type:#float ui:(ring01Sp,ring01Sl)
                        ring02 type:#float ui:(ring02Sp,ring02Sl)
                        ringSplay type:#float ui: (ringSplaySp,ringSplaySl)
            )
            parameters pinkyP rollout:pinkyR
            (
                        pinky01 type:#float ui:(pinky01Sp,pinky01Sl)
                        pinky02 type:#float ui:(pinky02Sp,pinky02Sl)
                        pinkySplay type:#float ui: (pinkySplaySp,pinkySplaySl)
            )
            parameters othersP rollout:othersR
            (
                        cup01 type:#float ui:(cupSp,cupSl)
            )
                        rollout thumbR "Thumb"
            (
                        local fW = 40, oS = [0,-23]
                        spinner thumb01Sp "" range: [-90,100,0] fieldWidth:fW
                        slider thumb01Sl "Thumb 01:" range:thumb01Sp.range offest: oS
                        spinner thumb02Sp "" range: [-90,100,0] fieldWidth:fW
                        slider thumb02Sl "Thumb 02:" range:thumb02Sp.range offest: oS
                        spinner thumb03Sp "" range: [-90,100,0] fieldWidth:fW
                        slider thumb03Sl "Thumb 03:" range:thumb03Sp.range offset: oS
                        spinner thumb04Sp "" range: [-90,100,0] fieldWidth:fW
                        slider thumb04Sl "Thumb 03:" range:thumb04Sp.range offset: oS
            )
            rollout indexR "Index"
            (
                        local fW = 40, oS = [0,-23]
                        spinner index01Sp "" range: [-90,100,0] fieldWidth:fW
                        slider index01Sl "Index 01:" range:index01Sp.range offest: oS
                        spinner index02Sp "" range: [-90,100,0] fieldWidth:fW
                        slider index02Sl "Index 02:" range:index02Sp.range offest: oS
                        spinner indexSplaySp "" range: [-90,100,0] fieldWidth:fW
                        slider indexSplaySl "Splay:" range:indexSplaySp.range offset: oS
            )
            rollout middleR "Middle"
            (
                        local fW = 40, oS = [0,-23]
                        spinner middle01Sp "" range: [-90,100,0] fieldWidth:fW
                        slider middle01Sl "Middle 01:" range:middle01Sp.range offest: oS
                        spinner middle02Sp "" range: [-90,100,0] fieldWidth:fW
                        slider middle02Sl "Middle 02:" range:middle02Sp.range offest: oS
                        spinner middleSplaySp "" range: [-90,100,0] fieldWidth:fW
                        slider middleSplaySl "Splay:" range:middleSplaySp.range offset: oS
            )
            rollout ringR "Ring"
            (
                        local fW = 40, oS = [0,-23]
                        spinner ring01Sp "" range: [-90,100,0] fieldWidth:fW
                        slider ring01Sl "Ring 01:" range:ring01Sp.range offest: oS
                        spinner ring02Sp "" range: [-90,100,0] fieldWidth:fW
                        slider ring02Sl "Ring 02:" range:ring02Sp.range offest: oS
                        spinner ringSplaySp "" range: [-90,100,0] fieldWidth:fW
                        slider ringSplaySl "Splay:" range:ringSplaySp.range offset: oS
            )
            rollout pinkyR "Pinky"
            (
                        local fW = 40, oS = [0,-23]
                        spinner pinky01Sp "" range: [-90,100,0] fieldWidth:fW
                        slider pinky01Sl "Pinky 01:" range:pinky01Sp.range offest: oS
                        spinner pinky02Sp "" range: [-90,100,0] fieldWidth:fW
                        slider pinky02Sl "Pinky 02:" range:pinky02Sp.range offest: oS
                        spinner pinkySplaySp "" range: [-90,100,0] fieldWidth:fW
                        slider pinkySplaySl "Splay:" range:pinkySplaySp.range offset: oS
            )
            rollout othersR "Others"
            (
                        local fW = 40, oS = [0,-23]
                        spinner cupSp "" range: [-90,90,0] fieldWidth:fW
                        slider cupSl "Cup:" range:cupSp.range offset: oS
            )
)

custAttributes.add $.modifiers[1] ca

In Order to get this to work, select the item you wish to make the controller. Then in the modifiers panel select PEN_ATTRIBUTE_HOLDER (However, you may need to download this and save it in the script plugins file in you 3ds Max folder) Then open MaxScript, copy and paste the script above, then on the bottom line, select 'Evaluate All' (Control or Command E). This will then create all the custom spinners ans sliders for a five digit hand (the code may be altered to have less digits, or name changes etc). But note: the item you give the attribute holder modifier to MUST be selected when you so this. This is because in the code, there is the $ symbol. This is basically you telling Max to apply the code to the selected item ($ = currently selected item).

Each bone of each finger were then individually wired to each corresponding slider. This was done using wire parameters as most of the digests needed to be controlled on the Y axis (although the 'cup' and 'thumb' digits rotate on more than one axis).

Very pleased with the result, although it took a very long time and it surprises me that there isn't a quicker way around this. The clip below demonstrates it's movement behaviour.


Arm and hand demonstration clip - LINK

No comments:

Post a Comment