Dynamic Hair Wagon
I noticed that I have been using the “Make Selected Curves Dynamic” option more and more in many of my projects. I found it very powerful and can easily give me expected results for a range of applications. I decided to use it in a practice for creating some kind of direction anticipation engine in a dynamic vehicle rig, utilizing the hair’s dynamic playback advantages. I’m going to try to achieve as many features as I can without compromising processing time and ultimately stepping away from the use of any type of MEL expressions. The following is a list of features I am aiming to accomplish in this practice:
Direction Detector – Automatically orient a vehicle’s rotation to the direction it is travelling in.
Height Collision System – Automatically detect a vehicle’s collisions and adjusting itself to climb over harsh terrain.
Balance Stabilizer – Automatically adjusts a vehicle’s balance in case one tire may be higher than the other.
Suspension System – Active suspension system that smoothens and balances the vehicle.
Wheel Rotation – Automatically rotates the vehicle’s tires depending on the distance and speed travelled.
Height Collision System
Instead of reading a surface’s UV’s and interpreting it in world space I decided to utilize something that may seem a bit unorthodox.
If you assign a Toon outline to two polygons that are intersecting, you can disable everything except for keeping its intersection outline. This outline can be converted in to a polygon. To find out where its travelling in the Y axis, since its world translation remains the same no matter how much it moves, I decided to create a hair on the outline’s surface so that I can use it’s follicle information along its UV surface. I can read the follicle’s translate to determine where the intersection between the two objects occur.
When tackling this issue, I went straight for a joint system with various point and aim constrains. I should have thought more about the situation before doing this because after some few hours and a number of different rigs, I found this system limited when applied to a 4-independent wheel vehicle. The rotation of the body must adjust itself in 4 different pivots since all 4 wheels will be calculated differently. So I trashed this idea after working on it with much help from a very close friend of mine, and creator of the popular MooM Rig, Ramtin Ahmadi. The solution that was finally used consisted of a planar polygon placed over the bottom of the rig with clusters on all 4 corners constrained to the wheels. A follicle is placed in the middle of the plane and the rotation of this follicle is translated in to the rotation of the vehicle’s chassis.
I feel that this aspect of the rig wasn’t realized as well as I wished to have accomplished. I simply used a proxy object with soft bodies and parent constrained things accordingly.
Unfortunately I couldn’t come up with a dynamic solution for this problem. I was thinking about having hard bodies drive it’s rotation but this could get heavy, even with proxies. I got some great direction from a friend of mine, Morteza Ramezanali. He suggested a MEL expression that will read the rig’s position 1 frame before and calculate its distance it has travelled, thereby feeding me the amount of rotation needed to reach that destination. However, this will mean the rig will need to be animated before we see any changes in the wheel rotation. If you remember geometry class back in the day, you should have been made to memorize the distance formula. Basically if you know the xy of point 1, and xy of point 2, you can plug in those values in this formula and reach an answer that gives you the length between these two points.
Since I need an extra dimension (z), then I will simply add that to the formula. Additionally, since it has been animated, I now know where point 1 and point 2 is by taking its current position and position it was last at 1 frame before.. Finally, to calculate the speed of my rig so that I can translate that in to the rotation of the wheel, I wrote this very simple dynamics expression.
float $time; float $lastx; float $lasty; float $lastz; float $distx = main_CTRL_Crv.translateX - $lastx; float $disty = main_CTRL_Crv.translateY - $lasty; float $distz = main_CTRL_Crv.translateZ - $lastz; float $distance = sqrt( $distx*$distx + $disty*$disty + $distz*$distz ); float $velocity = $distance / ( time - $time ); $lastx = main_CTRL_Crv.translateX; $lasty = main_CTRL_Crv.translateY; $lastz = main_CTRL_Crv.translateZ; $time = time; main_CTRL_Crv.Speed = $velocity;