Vincent Touache - Character TD
/tutos/14_scales_rig/content.php
data=================:ArraySnake scale rig

Table of Contents

  1. Intro
  2. Deal with the 2d collision
    1. If Beta is smaller than 90 degrees and b is smaller than c
    2. If Beta is greather than 90 degrees
    3. Inside maya
  3. Fix the twist issues
    1. Find P
    2. Find P'
  4. Conclusion



Intro

Recently, I started to think about how to rig a snake, with all the scales. After a few researches, it turns out different snakes have different type of scales, sometimes stretchy and flexible, sometimes more rigid. The stretchy ones are not much of a concern and should be handled in texturing if no animation control is required on them. Instead, I decided to focus on how to fake collision without a realistic solver driven by CFX. In this tutorial, we're gonna look at a possible solution fast enough to be used by animators. Please note this is not something you want to keep in your low rez rig, but rather something to add in your high rez rig, along with fur, possibly face rig, and anything too heavy for blocking. Furthermore, this might be too heavy/cumbersome with maya nodes only; when I did it, it was with a c++ custom node, and if you have 200+ scales to handle, that's what I'd suggest. Let's break down the problem into 2 different smaller problems!

Let's dive right into it!

Deal with the 2d collision

Let's focus only on 2 scales; if we get it working for those 2, we can then expand to the entire snake. Introducing a rotation in scale B (yellow), we can easily picture a triangle with how scale A (blue) should be.


solving 2d collision with trigonometry

Let's take a closer look at what we know and what we want: If you remember your teenage math course, you'll know that if we have 3 elements, it's usually enough to deduct everything else in a triangle. There are 2 possibilities

If Beta is smaller than 90 degrees and b is smaller than c

a = c * cos(beta) - sqrt(b*b - c*c * sin(beta)*sin(beta)) alpha = -beta - sqrt(b*b - c*c * sin(beta)*sin(beta))

If Beta is greather than 90 degrees

a = sqrt(b*b - c*c * sin(beta)*sin(beta)) + c * cos(beta) alpha = PI - beta - arcsin( c*sin(beta) / b)

Inside maya

Before rushing into maya, remember we always work with radians, not with degrees!

Now that we figured the math, we can implement it in maya. I used an expression, just because it's simple to prototype things without using a thousand nodes. Remember, we know b (that's the length of one scale, defined by a user input), we know c (magnitude of scaleA-scaleB), and we know Beta.

Reminder: the angle between V1 and V2 is simply arccos(V1/|V1| * V2/|V2)

Now all we have to do is replacing what we know in the previous equation.

I built a basic maya scene, if you really struggle with the math part, feel free to have a look at it if it helps. You can download it here

Fix the twist issues

Now we have a working solution in 2D, let's introduce some twist in our scales. As you can see, the first equation is satisfied, yet we have some collision on the sides. In order to address this, we need to find by which angle we should twist scale A to match exactly scale B

In other words, we need to find an angle theta by which we will rotate scale A.


how to get the angle Theta by which we want to rotate scale A

To do so, we have

Find P

We don't care how far P is along the edge of scale A. All we want is to have it somewhere on that edge. To do so, we can just add F.z/|F.z| to O (the Z vector of our frame, normalized)

Find P'

This one may be a little bit more complicated on the math side, and would require a tutorial on its own, so I'll just explain the idea, without going into too much detail.
Basically, once we have the angle P, we need to cast a ray from P, in the direction of the scale normal. Then, we get the intersection point of this ray onto scale B, and that'll give us P'. Luckily, a ray/plane intersection is a super light operation. All it takes is a point (P), a direction (the Y axis of our frame, or maybe another one depending on your orientations), and a target plane, defined by a point (position of the next scale) and a normal (Y axis of the next scale). Once you have this, the math is pretty standard, but again, I'm not onna cover it here (maybe in a future tuto?). You can still have a look at the maya scene available to see how it works.

Again, if you struggle, you can simply download this sample scene (maya 2019)

Conclusion

Now that we have resolved the collision in 2D and expanded it to a 3d world, we can propagate the exact same operation to all the scales to get the desired effect. As mentioned in the introduction, I would not recommand doing it with maya nodes for many scales, but instead doing it via a custom node.