|
|||||||||
Conditions The great advantage of the script controller is that you can actually write any script in it, using conditions and making decisions about what action to take. In this section youll create a script that will automatically increase the optimize strength according to the distance of the object; if the object is farther than a certain distance, itll retain its value. Open auto_optimizer.ms from your CD, or start a new script and type all the commands in LISTING 16.3.
LISTING 16.3:The Auto Optimizer script (auto_optimizer.ms) utility optimizer Auto Optimizer ( pickbutton pcam Pick Camera width:120 pickbutton pobj Pick Object enabled:false width:120 spinner cdist MIN Distance enabled:false range:[0,10000,0] spinner mdist MAX Distance enabled:false range:[0,10000,0] spinner opfar Face Thresh. enabled:false on pcam picked obj do ( cam = obj pobj.enabled = true ) fn opt_calc obj c = ( txt1 = d = distance $ + c.name + $ + obj.name + \n txt2 = (if d> + cdist.value as string + and d< + mdist.value \ as string + then\n) txt3 = (f = + opfar.value as string + *pi*2*((distance $ + \ c.name + $ + obj.name + )- + cdist.value as string + )/( \ + (mdist.value - cdist.value) as string + )/360\n) txt4 = (else if d< + cdist.value as string + then f=0 else f= \ + opfar.value as string + *pi/180\nf) obj.optimize[1].controller.script = \ (txt1 + txt2 + txt3 + txt4) ) on pobj picked obj do ( opobj = obj addmodifier opobj (optimize()) d = distance cam opobj cdist.enabled = true cdist.value = d mdist.enabled = true mdist.value = d + 10 opfar.enabled = true opobj.optimize[1].controller = float_script() opt_calc opobj cam ) on cdist changed val do opt_calc opobj cam on mdist changed val do opt_calc opobj cam on opfar changed val do opt_calc opobj cam )
This script allows the user to select a camera and an object. Then, the user can specify the distance where the Optimize starts and where it reaches the higher value. Closer than the minimum distance, the optimize value will be zero; farther than the maximum distance, itll be constant and equal to the higher value. This script assigns a script controller and writes the following script (if the camera is named $Camera01 and the object is a sphere named Sphere01): d = distance $Camera01 $Sphere01 if d > min and d < max then f = threshold*pi*2*((distance $Camera01 $Sphere01)-min) / (max-min) / 360 else if d < min then f = 0 else f = threshold * pi / 180 f First, it checks the distance between objects. If its between Min and Max, it calculates the face angle threshold. This value is interpolated from 0 to Threshold, and its calculated in radians (this explains *2*pi/360). If the distance isnt between those two values the script checks if its above or below them, and will set the correct values. Animate an object moving outwards the camera. Then, using this script, specify the optimize value and the distances. Play the animation and notice how it gradually reduces the number of faces. Limitations and Setup The biggest limitation of a script controller is that its not interactive, which means that youll have to move one frame back and forth to see it working. You can make a small script for it, with only two lines: max time forward and max time back. In addition, another script problem is that it relates to objects by their name, which will make the script fail if an object is renamed or deleted. You can turn off the script controllers through the MAXScript option in the Preferences dialog box (Figure 16.7). This might be helpful when you have too many controllers, or when you have controllers crashing and many error messages popping. Just disable Load Controller Scripts and they will not be executed.
Animating VerticesIf you look at the tracks of an editable mesh object in Track View, you will notice there are no tracks for vertices, but theres a Master Point controller. However, as soon as you animate any vertex, it appears in Track View as a new track. The same happens in MAXScript. Theres no way to animate vertices until you tell MAXScript you want to animate them. This is done using ANIMATEVERTEX, which works with editable meshes, editable splines, and FFD modifiers, allowing us to access the vertex tracks and animate them. To do ANIMATEVERTEX, you need to specify which vertices you want to animate so MAX will create the tracks and you can access them through a script. For example, if you want to animate vertex #3 in the selected object, use animate-vertex $ 3. If youre unsure of which vertices youll animate, use animate-vertex $ #all, which will allow you to animate all vertices, but this is memory- intensive and very hard to track in Track View later. Editable Mesh You can access the editable mesh vertex position in two ways: using obj.vertex_n or obj[4][1][n].value. In either case, n is the number of the vertex. The vertex position is in the objects local coordinate system. To know the position of the vertex in the world coordinate system, you simply need to multiply it to obj.objecttransform. Lets look at a simple example to understand this. b = box() c = converttomesh b animatevertex c #all v1 = c.vertex_1 This will return the first vertex position, which will be [-12.5,-12.5,0]. c.pos = [20,20,5] v1 = c.vertex_1 After moving the object, c.vertex_1 still returns [-12.5,-12.5,0], which proves that the vertex position is in object space, not in world space. v1a = c.vertex_1*c.objecttransform This will return [7.5,7.5,5], which is the vertex position in world space. c.vertex_1 = [0,0,0] This will move the vertex to [0,0,0], but in object space, which will move it to the center of the base. If you want to move it to [0,0,0] in world space, youll need: c.vertex_1 = [0,0,0]*(inverse c.objecttransform)
© 2000, Frol (selection, edition, publication) |
|||||||||
|
|||||||||