Sunday, February 10, 2013

Tutorial: Rigging a Bow in 3DS Max

This tutorial shows how to rig a bow in 3DS Max. I wrote it after having figured out how to rig a longbow that I modeled. Bows are not as straightforward to rig as, say, a creature model because the rig has to cause the wooden parts of the bow to bend when the bowstring is pulled. The string may stretch for a tiny bit, but once it has reached its full stretch, it should maintain its length the whole time. When the string is released, the bow should snap back into place, and the string should slowly vibrate to a stop without causing the bow to bend.

I didn’t have any luck searching for tutorials on the Internet about rigging a longbow in 3DS Max. I did find a good video tutorial on rigging a bow, but it’s a Blender tutorial. Nevertheless, it gave me enough clues on how to do a similar rig in 3DS Max, but the workflow that I used is sufficiently different to warrant its own tutorial. Hence, I decided to write one.

This tutorial assumes that the reader already has a bow model in 3DS Max that needs to be rigged. The tutorial does not assume that the reader knows how to set up a skeleton and weight vertices to it, so I will try to explain these processes in detail. Some knowledge on the different coordinate systems that 3DS Max uses will help in understanding the later parts of the tutorial.

Ready to begin? If so, read on.

  1. Activate the Left or Right viewport. For this tutorial, I chose to activate the Right viewport to match the view in the Blender tutorial I mentioned earlier. If the mesh is not displayed in wireframe view, press [F3] to switch to it.


  2. On the rightmost side of the screen, make sure that the Create panel is selected then click the Systems button and the Bones button.


  3. Click on the center of the bow’s handle to begin creating bones. Keep clicking along the upper half of the bow to create a chain of bones, making sure that the joints are more or less along an edge loop of the bow. Don’t worry about precise placement at this point because we can edit the bones later. When we finally click the point where the bowstring pulls the bow, end the chain by right-clicking anywhere on the screen. This will create an extra nub bone, which we will use eventually. Rotate the nub bone so that it is perpendicular to the bowstring with the bone’s tip facing away from the bow.


  4. Activate the Select and Move tool, which is located on the top toolbar, then click the very first bone that we created, which should be the one closest to the handle of the bow. Zoom in on the bone with the mouse wheel to get a better view of it. Reposition the bone so that it is on the exact center of the handle. We may use the Absolute Mode Transform Type-In at the bottom of the screen to input precise X, Y, and Z coordinates.


  5. If necessary, we can adjust the placement of individual bones with the Bone Tools. Click the Animation menu then select Bone Tools to bring up a dialog box of the same name. Click the Bone Edit Mode button to toggle on bone editing mode. We can then use the Select and Move tool to edit the placement of bone joints as necessary.


  6. Press [H] to bring up the Select from Scene dialog box. Click the first bone in the list, then with the [Shift] key pressed, click the last bone to highlight all the bones. Click the OK button. Doing this will close the dialog box and select all the bones.


  7. In the Bone Tools dialog box, click the Mirror button to bring up another dialog box called Bone Mirror. Under Mirror Axis, click the Z radio button then click the OK button. All the bones on the upper half of the bow should then be mirrored on the bottom half.


  8. Having made the bones that control the wooden part of the bow, we will now create a bone to control the bowstring. Zoom in to get a good view of the center of the bowstring with the mouse wheel. In the Bone Tools dialog box, click the Create Bones button then click on the center of the bowstring to start creating a new bone. Click on a point away from the bow and its string to make a bone that is aligned like a nocked arrow. Right-click to end bone creation. An extra nub bone will be created as well, but we may delete it since it won’t be needed. Re-position and rotate the bone as necessary so that it is aligned perpendicularly to the bowstring and so that its joint is precisely at the center of the string.


  9. We will now create what is supposed to be the root bone of the bow’s skeleton. Again, press the Create Bones button in the Bone Tools dialog box, but this time, click close to the center of the handle to begin creating a new bone at that point. Don’t click too close to the center to keep from attaching the new bone to any other bone nearby. As with the last bone that we created, make the new bone perpendicular to the handle of the bow then right-click to end bone creation. Delete the extra nub bone that is created, and use the Select and Move tool to position the joint of the new bone precisely in the center of the bow’s handle.


  10. Optional but recommended step: Select each bone in turn and rename it to something meaningful. For example, I chose to rename the bones that control the upper half of the bow to “bone_bow_upper_xx,” where xx is a two-digit sequential number. In a similar fashion, the bones on the lower half of the bow are named “bone_bow_lower_xx.” The bone that controls the bowstring is named “bone_bow_string,” and the root bone is named “bone_bow_root.”

  11. At this point, we actually have four separate skeletons for the bow. This is evident when we look at the schematic hierarchy of the objects we’ve made. Click the Schematic View button on the toolbar. This will open a new window named Schematic View 1.


    As we can see from the schematic view, we have four separate skeletons for the bow, but what we want to do is to integrate all the bones of the bow into one skeleton. This way, we will only need to move or rotate a single bone to move or rotate the entire skeleton. There are several ways to accomplish this in 3DS Max, but since we are already viewing the schematics of our objects, we might as link the bones within the schematic view itself.


    In the toolbar of the Schematic View window, click the Connect button.


    Now click the box representing the root of the upper half of the bow, and without releasing the left mouse button, drag the cursor to the box representing the root bone of the entire bow. Release the mouse button. This will cause the set of bones for the upper half of the bow to be linked as children of the bow’s root bone.


    Repeat this process to connect the bone of the bowstring and the skeleton of the lower half of the bow to the bow’s root bone. When done, there should only be one skeleton for the bow as shown below.


    We may now close the Schematic View window.

  12. Use the Select Object tool to select the root bone of the bow.


    Scroll down the Bone Tools dialog box to see the Object Properties group box. Untick the Freeze Length checkbox and set Stretch to None. This will allow us to pull on the bowstring bone while keeping it parented to the root bone.


    We may now close the Bone tools dialog box.

  13. Use the Select Object tool to select the mesh of the bow.


    Click the Modify panel on the right side of the screen and add a Skin modifier to the mesh. Under the Parameters rollout, click the Add button beside the “Bones” label. This will bring up a dialog box named “Select Bones.”


    Highlight all the bones of the bow then click the Select button. This will close the dialog box and add all the highlighted bones to the Skin modifier.


  14. Using the Select and Rotate tool, click each bone in turn and rotate it to test the rig. Press [Ctrl]+Z to undo the rotation each time and restore the bones to their original state. If there are errors in how the mesh deforms when a bone is rotated, that means the vertex weights for the associated bones will have to be adjusted.

    In the skin modifier of the mesh, click the Edit Envelopes button, which will allow us to adjust the vertex weights of any bone as necessary. In the list of bones that also appear under the Skin modifier, select the bone whose associated vertex weights you want to adjust.

    There are a number of ways to adjust vertex weights for any given bone, but for this model, I will only use two methods. The first method is to use the Weight Tool. For this, we will need to be able to select vertices by ticking the checkbox labeled “Vertices” in the Select group box of the Skin modifier.


    For this task, it may help to switch from Wireframe view to Shaded + Edged Faces view. Pressing [F3] toggles between both views, and pressing [F4] toggles edged faces.
      In the list of bones, select the bone that we want to adjust vertex weights for.  With the Select and Move tool, select the vertices whose weights we want to adjust. Now click the button for the Weight Tool, whose icon looks like a wrench. In the Weight Tool dialog box, make sure that the bone that we are adjusting vertex weights for is highlighted.  We can input any number between 0 and 1 in the box beside the Set Weight button. This number represents how much influence the highlighted bone will have over the selected vertices when we click the Set Weight button. For a given bone, vertices with a weight of 1 or close to 1 will appear red. Those with a weight of approximately 0.75 will appear orange. Vertices with a weight of 0.5 will be yellow, and this color will appear progressively paler as the vertex weight approaches 0.1. Vertices with a weight of less than 0.1 will be blue.


    There are other buttons in the Weight Tool dialog box that can affect vertex weights, but I will let you figure out what those do.

  15. The second method that we will use to set vertex weights is to “paint” them. This is particularly useful for fine-tuning vertex weights that were set using the Weight Tool.

    Scroll down the Skin modifier until we see the Paint Weights button, which is inside a group box labeled “Weight Properties.” Beside it is a button marked “…” It is this button that we will press first to open the Painter Options dialog box to set up vertex weight painting.


    Different meshes may require different setups, but for this particular model, we set Max Size to 5 to give us a “paint brush” of just the right size. The checkbox labeled “Enable Pressure Sensitivity” may also be ticked if we are using a graphics tablet to paint vertex weights. We may then close the Painter Options dialog box.


    We now click the Paint Weights button and proceed to use the mouse (or the graphics stylus as the case may be) to paint vertex weights on the vertices that are supposed to be affected by the selected bone. Continue doing this with other bones until we are satisfied with the vertex weights. We may then press the Paint Weights button to toggle off vertex weight painting.


  16. Go back to wireframe view by pressing [F3]. Zoom out the scene until we have a good view of the entire upper half of the bow then select the nub bone at the very top of the bow. Click the Animation menu then click IK Solvers > HI Solver.


    At this point, we will see a stretchy dotted line anchored to the nub bone that we selected. Bring the mouse cursor to the bone of the upper half of the bow’s handle and click it. This will create an IK (Inverse Kinematics) chain from the nub bone at the top to the bone that we clicked. If we were to change the position of the nub bone, the rest of the bones in the IK chain will rotate and shift position to maintain the connection between them.


  17. Repeat the previous step to connect the bottom nub bone to the bone of the lower half of the bow’s handle. At the end of this step, we will have two IK chains named IK Chain001 and IK Chain002.


  18. Activate the Select and Move tool then click the bone of the bowstring. Note down the X, Y, and Z position of this bone. Likewise, click IK Chain001 and IK Chain002 in turn and note down their X, Y, and Z positions.

    For my model, I had the following values for the aforementioned objects:

    World Coordinates

    Bowstring Bone
    IK Chain001
    IK Chain002
    X
    0.0
    -0.009
    -0.002
    Y
    18.41
    17.282
    17.282
    Z
    80.0
    149.091
    10.913

  19. We will need to link the two IK chains that we created to the root bone of the bow’s skeleton so that they will move and rotate with the root bone. Click the Schematic View button on the toolbar again then link both IK chains to the root bone. The skeleton hierarchy should then appear as shown below.


    We now close the Schematic View window. Linking the IK chains to the root bone would have caused them to change position. With the Select and Move tool, click on each IK chain in turn and move them so that they are back to their original positions.

  20. We’re going to use wire parameters so that whenever we pull the bone of the bowstring horizontally, the bow will bend. Wire parameters can be confusing to work with because all their positions are in reference to the parent coordinate system of the objects that are affecting each other, but the coordinates given in the table above are in reference to the world coordinate system. The bowstring bone and the two IK chains are directly parented to the bow’s root bone, so their parent coordinates are all in relation to the coordinates of the root bone. Below is a table showing the parent coordinates of these three objects.

    Parent Coordinates

    Bowstring Bone
    IK Chain001
    IK Chain002
    X
    -18.41
    -17.282
    -17.282
    Y
    0.0
    -69.091
    69.087
    Z
    0.0
    -0.009
    -0.002

    I don’t want to launch into an explanation on the different coordinate systems that 3DS Max uses. Suffice it to say that because of the way the bowstring bone and IK chains are oriented, making the bone and chains move horizontally means moving them along their parent X axis, and moving them vertically means moving them along their parent Y axis. In the case of my model, the parent X axis of these objects correspond to the world Y axis, and the parent Y axis to the world Z axis. Got that? No? Let’s forge ahead anyway.

    Select the bowstring bone and right-click it to bring up a context-sensitive menu. Click Wire Parameters > Transform > Position> X Position.


    Click the IK chain at the top of the bow then click Transform > IK Goal > Position > X Position. This will bring up a dialog box named “Parameter Wiring #1.”


    We want to make the bowstring bone control IK Chain001 by making the IK chain’s X-position change whenever the bowstring bone’s X-position changes. To indicate that it is the bowstring bone controlling the IK chain and not the other way around, we click the button with the right-facing arrow in the dialog box. Next, we enter a formula for the IK chain’s X-position. As shown in the picture below, the formula for my model is

    X_Position*0.4 - 9.918

    What the above formula means is that the IK chain moves horizontally at a fraction of the speed that the bowstring moves along its parent X axis. The fraction, 0.4, was chosen through trial and error to get the bow to bend realistically when its string is pulled. The closer the fraction is to 0, the more resistant the bow becomes to bending. The closer the fraction is to 1, the more pliable the bow is. The value 9.918 is there to ensure that when the bowstring bone’s world Y-position is at 18.41 (its original position as shown in the above table), the world Y-position of IK Chain001 will be at 17.282 (the original position of the IK chain). I derived the value 9.918 by first entering the following formula as the expression for IK Chain001’s parent X_Position:

    X_Position*0.4

    I then clicked the Connect button and took note of the new world Y-position of IK Chain001, which was 7.364 for my model. I subtracted this new value from 17.282, the original world Y-position of the IK chain, to derive 9.918. I then edited my formula to subtract 9.918 then clicked the Update button in the dialog box.


  21. We also have to provide an expression for the parent Y-position of IK Chain001 to account for the lowering of the upper half of the bow when the bowstring is stretched. In the Parameter Wiring dialog box, in the box labeled IK Chain001, click the words “Y Position: Bezier Float.” As before, click the button with the right-pointing arrow to indicate that it is the bowstring bone controlling the IK chain then enter an appropriate expression for IK Chain001’s Y-position. For my model, I used the following formula:

    sqrt(4775.944 -(-0.6*X_Position - 9.918)^2) + 79.992

    This rather cumbersome formula is derived from the distance formula. Recall that in three-dimensional space, the square of the distance between any two points is as follows:

    distance
    2 = (x1 - x2)2 + (y1 - y2)2 + (z1 - z2)2

    For my model, the square of the distance between the bowstring bone and IK Chain001 is

    (0 + 0.009)
    2 + (18.41 - 17.282)2 + (80 - 149.091)2 = 4775.944

    Hence, the distance between these two objects is the square root of 4775.944, which is 69.108. However far we stretch the bowstring, we want the distance between the bowstring bone and IK Chain001 to be constant. We need to derive a formula for the parent Y-position of IK Chain001, given the parent X-position of the bowstring bone. If we let the coordinates (x
    1, y1, z1) represent the position of the bowstring bone and the coordinates (x2, y2, z2) the position of IK Chain001, we solve for y2 using the following formula:

    y
    2 = y1 - sqrt(distance2 - [z1 - z2]2 - [x1 - x2]2)

    Substituting the known X, Y, and Z positions of the bowstring bone and IK Chain001 as well as the distance between them, we derive the following:

    y
    2 = 80 - sqrt(4775.944 - [0 - -0.009]2 - [x1 - x2]2)
  22. = 80 - sqrt(4775.944 - [x1 - x2]2)

    Note that the expression [0 - -0.009]2 equates to 0.000081, a figure so small as to be practically zero for all intents and purposes.

    The parent Y-position of IK Chain001, y2, changes whenever the parent X-position of the bowstring bone changes as well. In fact, we’ve already established that x2 is given by the following formula:

    X_Position*0.4 - 9.918

    As for x
    1, it is simply the X_Position.

    Therefore, the Y-position of IK Chain001 is given by the following expression:


    80 - sqrt(4775.944 - [X_Position -{X_Position*0.4 - 9.918}]2)
    = 80 - sqrt(4775.944 - [0.6 * X_Position + 9.918]2)


    Written in a way that 3DS Max can interpret, this formula becomes

    80 - sqrt(4775.944 - (0.6*X_Position + 9.918)^2)

    Applying the above formula will cause the world Z-position of IK Chain001 to go down to 69.099 when the bowstring bone is at its original position, so we need to subtract 79.992 to the whole expression so that the world Z-position of the IK chain will be at 149.091. Hence the expression to use is

    80 - sqrt(4775.944 - (0.6*X_Position + 9.918)^2) - 79.992

    Simplifying, we get our final expression, which is

    0.008 - sqrt(4775.944 -(0.6*X_Position + 9.918)^2)


    Upon inputting the above formula as the expression for IK Chain001’s parent Y_Position, we click the Update button to apply it, after which we may close the Parameter Wiring dialog box.

    At this point, I should mention that the exact formulas given here and in the previous step will not necessarily work with other bow models unless the X, Y, and Z positions of the bowstring bone and the two IK chains are the same as the ones shown in the table in step 19. I took pains to explain the derivation of these formulas so that readers will understand how to adapt them for their models.

  23. Verify that the wire parameter works properly by using the Select and Move tool to move the bowstring bow horizontally like an arrow being strung. If the formulas we entered are correct, the upper half of the bow should bend the way a real bow should. Afterward, press [Ctrl]+Z to restore the bone to its original position.


  24. Just as we did with the upper half of the bow, we will set up some wire parameters for the lower half. Repeat step 20 above, but instead of clicking on the IK chain on top, click on IK Chain002. Because both IK chains have the same parent X-position, w set up the parent X-position of IK Chain002 exactly as we did with the other IK chain, using the same formula as before.

    The IK chains do not have the same parent Y-position, however. Also, whereas the upper IK chain should go down whenever we stretch the bowstring bone horizontally, the lower chain should go up. Initially, we set the expression of IK Chain002’s parent Y-position as follows:

    sqrt(4775.944 - (0.6*X_Position + 9.918)^2) - 80

    We then take note of the new world Z-position of IK Chain002 and subtract it from the IK chain’s original world Z-position to derive a constant that should be subtracted from the earlier formula. In the case of my model, the new world Z-position was 90.901. Subtracting this value from the original world Z-position of 10.913 gives us -79.988, which we subtract from the above formula to derive the following:

    sqrt(4775.944 - (0.6*X_Position + 9.918)^2) - 80 + 79.988

    Simplifying the formula gives us its final form:

    sqrt(4775.944 - (0.6*X_Position + 9.918)^2) - 0.012


    After updating the formula, we may close the Parameter Wiring dialog box.

  25. Repeat step 22 to verify that the wire parameters for both the upper and lower half of the bow have been set up correctly.


  26. We’re not quite done with the bow yet. If we were to push the bowstring bone a little toward the bow, we will see that the bow also moves. Likewise, pulling the bow a tiny distance away will also cause the bow to move. We want the bowstring to vibrate when it is released, but we don’t want the wood of the bow to move with it. We will need to edit our wire parameters to accomplish this.

    First, we have to decide how far the bowstring should be allowed to stretch before it moves the wood with it. For my model, I decided to apply a tolerance of 4 centimeters.

    Next, we select the bowstring bone then right-click it to bring up the context-sensitive menu. We click Wire Parameters > Transform > Position> X Position, after which we click IK Chain001 at the top of the bow then click Transform > IK Goal > Position > X Position. This will bring up the Parameter Wiring dialog box.

    We will edit the expression for IK Chain001’s X-position so that the IK chain will move horizontally only if the bowstring bone’s position exceeds our chosen tolerance. Otherwise, it will stay at its original parent position of -17.282. The expression that we entered previously should thus be replaced with the following:


    if X_Position <= -(18.41 + 4) then
    X_Position*0.4 - 9.918
    else
    -17.282


    In my model, the parent X coordinates of the bowstring bone and the IK chains run opposite to the world Y coordinates, which explains my use of negation (-) in the first line of the above expression.

  27. Next, click on the words “Y Position: Float Wire” in the box under IK Chain001. We will now edit the expression so that the bow will not bend up or down unless the bowstring bone goes beyond its tolerance limit. For my model, I edited the expression to read as follows:

    if X_Position <= -(18.41 + 4) then
    0.008 - sqrt(4775.944 - (0.6*X_Position + 9.918)^2)
    else
    -69.091


  28. Click the Show All Tracks button beside the label “IK Chain001” in the Parameter Wiring dialog box. The label “IK Chain001” will change to “World,” and we should now be able to see within this box all the objects that we can wire the bowstring bone to.  Scroll around the box until we see “IK Chain002,” which should be labeled in red. Click the “+” sign beside it to expand its contents then click the “+” signs of “Transform : IKChainControl,” “IK Goal : Position/Rotation/Scale,” and “Position : Position XYZ.” Now click “X Position : Float Wire,” which is also written in red. Edit the text in the box labeled “Expression for X_Position” so that it will be the same as what we wrote in step 25.


  29. Click the red label “Y Position : Float Wire” and edit the expression to read as follows:

    if X_Position <= -(18.41 + 4) then
    sqrt(4775.944 - (0.6*X_Position + 9.918)^2) - 0.012
    else
    69.087


  30. Close the Parameter Wiring dialog box and try moving the bowstring bone horizontally. Tiny movements should not cause the bow to bend, but pulling the bone farther ought to.

This ends my tutorial on rigging a bow. It’s a long tutorial, but I hope it’s also clear and easy to understand. Anyone who wants to offer feedback or suggestions for improvement is welcome to write in the Comments section.


10 comments:

  1. Formula thingie too hard to understand, i suck at math. How about a bow rigging tutorial for dummies, instead of math teachers?

    ReplyDelete
    Replies
    1. Apologies, that comment wasn't constructive at all, what i meant to say was...good tutorial up to the point of that formula calculation where i got stuck and couldn't continue due to lack of math skills.

      Delete
    2. Sorry for the delay in replying. I noticed your comment just now. I understand your concern regarding the math. I can't make any promises, but I'll see if I can rewrite the tutorial to make it easier to plug in the appropriate values.

      Delete
  2. I struggled with the math as well. But to get through it, I wrote it all down, broke it down by group (x1, x2, y1, y2, etc.) and got it to a point where it didn't butcher the arm on the bow.

    Now, my problem is that it still doesn't bend down to the Arrow Notching point. It only slides across the X-Axis. Additionally, the bones of each arm straighten out into a long pole, rather than flexing like its supposed to. I'm not sure why this is.

    Besides my problem, this is a great tutorial! It got me far closer to what I sought than any other tutorial! The vibration in the bow string was a great touch, too! Adds more realism, and very much appreciated. Thanks!

    ReplyDelete
    Replies
    1. I'm glad you're finding this tutorial useful to some extent, although I admit that the math can be daunting.

      Regarding your problem with the bones of each arm straightening into a long pole instead of flexing gently, please check the formula used in the latter part of step 20 of my tutorial. Note that the formula I used was
      X_Position*0.4 - 9.918

      In my example, the X_Position multiplier that I used was 0.4. For your model, your multiplier may be too high. You may want to experiment with lower values until you find one that will make your model flex properly. Hope this helps.

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Absolutely spot on tutorial, very well explained and easy to follow. I was able to rig my bow in about an hour following this.

    I do have one question about this.
    http://i.imgur.com/zzBZkB9.png

    Is there a way to maybe decrease the falloff on the effect of the bow? So make my bow flex more at the tip and less at the middle?
    http://i.imgur.com/9I8GYxf.png

    Thanks for a great tutorial!

    ReplyDelete
    Replies
    1. Awesome! I'm glad you got it to work.

      Regarding your question, though, I can't find a solution to the problem. You actually raise a very good point as the bow should be less pliant along its thicker middle than toward the ends. I tried looking it up in various online sources, but nothing came up. If some other reader can post a possible solution, that would be great.

      Delete
  5. Thank you! Very good and detailed tutorial. Just one hour of work - awesome!

    ReplyDelete