Animated Sculpty Exporter Download here

I've created a tool to make it (relatively) straightforward to create mesh deformation animation within Second Life by leveraging the power of sculptys.

The actual exporting of images is lifted from the original sculpty exporter script written by Qarl (with a minor change to keep the scale the same). I've expanded on that script to provide a nice clean workflow for woring with animated sculpties, and one that allows for a great degree of control on the part of the artist.

Getting Ready

First off, be sure to grab the script from here. Then, create some animation in Maya. All of the standard caveats regarding sculpties hold (NURBS are best, polygons are okay with careful mapping). There is one additional constraint with my script, however...

Since I removed the automatic resizing in Qarl's exporter (in order to keep the scale from changing frame-to-frame), it's the resposibility of the artist to ensure that the entire animation fits within a unit cube.
Upon startup, the script will create a non-renderable unit cube at the origin (named "psASrefCube"). If one already exists, that step will be skipped. Make sure that your object fits completely within the cube at all frames. If you move and scale a copy of the object, be sure to freeze transformations on the copy before exporting.

Creating Sequences

The script is set up so that one can easily create multiple sequences from one or more objects and export them all at the same time. Each "sequence" represents an unique set of frames for a single object. In order to export anything, you'll need to create one or more sequences. Fire up the script, and you'll see the following:
Note the text at the top of the interface- that indicates where the images and LSL code will be stored upon exporting (derived from the current project settings).

Each sequence must be named (no spaces or punctuation, please). You also need to specify the start frame, end frame, and number of frames to export. Note that the number of frames can be less than the difference between the start and end frame, allowing for arbitrary sampling rates. As a result, one can create the animation over a large number of frames (easier to visualize), and yet export a minimum number of frames (as image uploading can get expensive).

The start frame, end frame, and number of frames will default to the current time range and a sampling rate of once per frame, but feel free to change it to suit your needs. Note that since Maya does allow fractional frames, you don't have to have the number of frames be an even divisor of the difference between start and end.

Once you've named the sequence and specified the start, end, and number, click on the "add as sequence" button.

Editing Sequences

When you add a sequence to the scene, the script will render out preview images for each frame. To view the previews, expand the "Animation Sequences" section of the interface. You should see a section for each sequence that has been added so far.
Since uploading images can get expensive ($L10 per frame), I've added the ability to knock out individual frames. If there isn't much of a difference between two sucessive frames, and you think the animation would be okay omitting one of them, you can set the sequence to skip that frame. To do that, right-click on the preview image, and select "toggle frame". That will replace the preview image with a strikeout image, as in the following:
Previously removed frames can be restored by right-clicking on the image and choosing "toggle frame" again.

Exporting Sequences

Once you've created all of the sequences you want to use, click on the "export all" button. That will create a new folder named with the sequence name, in the location indicated at the top of the window. In each folder, there will be bitmaps for each (selected) frame, and a text file containing LSL that can be used to animate an object in SL.

Generated LSL

The LSL that's generated by the script is intentionally incomplete, in order to make it easier to integrate in the context of larger scripts or multiple sequences. It consists of two parts: The generated code is slightly different for sequences that have had frames knocked out and those that haven't. Below are examples:

Generated code (no removed frames)
integer anim_newtest_noskip()
{
	string texture = "newtest_noskip_frame_"+(string)current_frame;
	llSetPrimitiveParams([PRIM_TYPE,PRIM_TYPE_SCULPT,texture,PRIM_SCULPT_TYPE_SPHERE]);
	if (current_frame == 4)
	{
		llSetTimerEvent(0);
	}
	current_frame = (current_frame + 1) % 5;
	return 1;
}

state newtest_noskip
{
	state_entry()
	{
		current_frame = 0;
	}

	timer()
	{
		anim_newtest_noskip();
	}
}


Generated code (with removed frames)
integer anim_newtest_skip()
{
	string texture = "newtest_skip_frame_"+(string)current_frame;
	integer index = llListFindList([1,6,7,8], [current_frame]);
	if (index == -1)
	{
		llSetPrimitiveParams([PRIM_TYPE,PRIM_TYPE_SCULPT,texture,PRIM_SCULPT_TYPE_SPHERE]);
	}
	if (current_frame == 9)
	{
		llSetTimerEvent(0);
	}
	current_frame = (current_frame + 1) % 10;
	return 1;
}

state newtest_skip
{
	state_entry()
	{
		current_frame = 0;
	}

	timer()
	{
		anim_newtest_skip();
	}
}
You'll want to add some code to trigger the animation in an appropriate way, but I leave that up to the user. If you wanted to have the animation play when the object is touched (for example), you'd want to end up with the following:

integer current_frame = 0;

integer anim_example()
{
    string texture = "example_frame_"+(string)current_frame;
    llSetPrimitiveParams([PRIM_TYPE,PRIM_TYPE_SCULPT,texture,PRIM_SCULPT_TYPE_SPHERE]);
    current_frame = (current_frame + 1) % 10;
    if (current_frame == 9)
    {
        llSetTimerEvent(0);
    }
    return 1;
}

default
{
    state_entry()
    {
    }

    touch_start(integer total_number)
    {
        llSetTimerEvent(0.2);
        state example;
    }
}

state example
{
    state_entry()
    {
        current_frame = 0;
    }

    timer()
    {
        anim_example();
    }

    touch_start(integer a)
    {
        llSetPrimitiveParams([PRIM_TYPE,PRIM_TYPE_SCULPT,"example_frame_0",PRIM_SCULPT_TYPE_SPHERE]);
        state default;
    }
}
Note that all of the frames for the animation must be in the inventory of the object to which they apply.

Notes, caveats, etc

I developed and tested the script on WindowsXP using Maya 7.0. It should work fine on other versions of Maya, but I can't guarantee that it will work on Macs (due to a difference in the way that Mac and Windows handle bitmaps). If you use the script and find a bug, please let me know about it by emailing me at purplestatic at yahoo dot com.

While I greatly appreciate feedback, I'm not likely to respond if you're having problems installing the script. If that's the case, make sure you're putting the script in the correct place and calling it in the correct manner (that's slightly tricky, and easy to get wrong if you're not used to working with MEL scripts - see here for more info).

Also, feel free to contact me to let me know how you're using the script. Knowing that it's getting used to do cool things is a powerful motivator for me to add new features ;).

Enjoy!