CG Academy Main Banner
News Training DVDs Instructors Free Tutorials Our Policies Feedback
CG Academy Forums 3dsmax Resources Contact Us CG Academy Main Banner Your Shopping Cart Your Shopping Cart Your Shopping Cart
MAXScript Based Distance Indicator

Aim of Tutorial
In Paul Neale's Intermediate Rigging DVDs one of the features Paul demonstrates is a spline based spine system. He also shows a leg rigged with the capability to stretch the bones when the foot is moved beyond the normal length of the leg. So, we have the concept in both systems that the limb or spine can actually be extended beyond its normal length to allow for extreme animation.

But... if we can go beyond normal, just what IS normal for the rig. We need a way to display to the animator that the rig is in the normal position range for that system, whatever it may be. In this case we are going to use colour as a cue to give the user visual feedback. We'll take green as being the optimal length for the item, and the colour will shift into blues and purples if the distance is too short , and into yellows and reds if the distance is too great.

What do we need to know before doing this Tutorial?
This tutorial for the most part lies in the intermediate skill area. We wont be doing anything to major, but we will be using some scripting and basic maths toward the end. If you are not familiar with MAXScript then you may want to have a look at our MAXScript Fundamentals DVDs. Though you do not need them to get this system working. As you can see though, this tutorial does show MAXScript can be powerful and indeed plain handy when working within 3dsmax. Anyway, on with the show...

Setup
First we'll create the two points that will be the basis of our distance measurement. We'll create two point helpers one at 0,0,0 in the world and the second at 50,0,0. The position of the second point helper is important as we know it is on 50 in X, and so it is 50 units away from the first point helper. This will be used in our script later. We call the first point helper Point01 and the second Point02.


See Example1
Now that we have our two points to measure the distance we need the object that is going to change colour when the distance changes in some way. For that we'll create a Geosphere and we'll snap it to the same position as Point02. Now that we have it on the same spot as Point02 we can make Point02 follow the sphere by constraining it. Select Point02 and go to the Animation/Constraints menu and pick Position Constraint, this will want you to pick a target, click on Geosphere01. Now Point 2 is position constrained to Geosphere01 and will move along with it when you move Geosphere01. We now have our basic scene setup. If we move Geosphere01 we'll want to see it change colour to indicate that its not in its ideal position. Before we go on, lets rename Geosphere01 to test_sphere, its a little more memorable, which never harms..

See Example2
Example 1
Example 2
The System
Now we have our basic pieces in place, what is the plan from here onwards? Well, the basic idea is to apply a material to test_sphere and then modify the diffuse colour swatch of that material so that it reflects the colour change that we need. So, the first stage is to make a material and apply it to test_sphere. I wont bother illustrating this as I'm sure your easily capable of this. So take the first material in the material editor and apply it to test_sphere and re-name the material to test_material

In this case the re-naming is not vital, as we will not be referring to the material by name within our script, this is just for neatness sake in case we did. With scripting it's a good idea to give things nice short, unique and sensible names so that you can refer to them in a script if needed. Anyway, onwards....


Applying the Scripted Controller
Our system is going to use a scripted controller to make the changes to our materials diffuse colour each time test_sphere is moved. So, we need to place the scripted controller somewhere. In our case, probably the best place to put it would be on the scale controller for the sphere. So, select test_sphere, right click and choose Curve Editor from the quad menu. Now you have the curve editor open, make sure that test _sphere is shown. Find its Scale controller nub, right click on it, and from the small quad menu choose Assign Controller...

See Example 3

You will be presented with a menu with a number of options as to which controller to apply, we'll be going with scripted controller, so go to that option about 3/4 of the way down and pick Scale Script and press ok to assign it. Now Max opens the controller properties for that newly assigned controller and its in here we'll really do our nitty gritty. From now on refer to the script that you can see in Example 4 to your right. I'll explain what each part of it does here so you fully understand what is going on and why I have done things this way. So..

dependsOn $Point01 $Point02
We want our controller to update whenever one of the two objects we are basing our distance measurements on move. So here we use the dependsOn command to "keep an eye" on Point01 and Point02.

rag = (color 100 100 100)
We need a variable with a color value assigned to it. This is because we want to work with HSV values later in the script and these cannot be assigned at creation time for a color in max.

dis = (distance $Point01 $Point02)
This line measures the distance between the two points and assigns it to the variable dis for use later.

rag.hue = (50 - dis) + 90
This is the real meat and potatoes of the script. here we take the hue component of our rag colour variable we setup eariler and we assign our own value to it. That value is 50 (the original distance of Point01 from Point02) minus dis (which again should equal 50 to start with), that gives us a value of zero i.e. we are at the perfect length. If we assigned zero to the Hue though we'd have a red ball, and that's wrong. So we add 90 onto it, which is the correct value for green.

Now if the distance gets shorter the distance value will drop down from 50 to 40, 30 onwards down to a minimum distance of 0. As the distance drops our hue should change become cyan and on towards blue. If our distance increases we'll have dis values of 60, 70 90 etc. And these will shift the Hue towards yellow, orange and on to red. When the hue value drops below zero, it will cause the colour to bork out to white.
rag.saturation = 255
This is to make the final colour fully saturated

rag.value = 255
And we'll apply 255 to the value to ensure the colour is very bright.

$test_sphere.material.Diffuse = rag
And now we apply the new rag colour by assigning it to test_sphere's .material (which was created when you assigned the material earlier). That .material property has a sub property called .Diffuse, which is the diffuse colour maps swatch colour. So we have now assigned the new colour in rag to our diffuse material on test_sphere. THATS IT !!!, except...

[1, 1, 1]
This is a Scale controller right? yes, and the previous lines output would have not been too usefull as a scale value. So the last line of our script supplies a valid scale value for the controller to use, in this case 1,1,1 which is a scale of 100%,100%,100% i.e.the default scale.


Conclusion
So, there you have it. Thats how you make an object display a distance offset using colour. One question you may have is "Why not apply the script to the objects .wirecolor property instead of using a material, thats a cleaner way to do it no?" Well, it would be, but the .wirecolor paramater cannot be animated, so try it for your self, if you change the .wirecolors value interactively like this you'll find you have update issues. Anyway, this system requires a little more work in assigning the material, but not much more. The final file can be downloaded from here. It has the working system in it, feel free to have a look at test_sphere's scale controller and how the script in there works.


Cheers

Chris Thomas
chris@cg-academy.net

Example 3
Example 4

Example 5
Example 6
Example 7
Training DVDs CG Academy Main Banner
Copyright © 2010 CG Academy LTD