Anim8or Community

General Category => ASL Scripts => Topic started by: Raxx on January 18, 2016, 02:10:18 pm

Title: Animated Textures Using Controller Scripts
Post by: Raxx on January 18, 2016, 02:10:18 pm
Animated Textures Using Controller Scripts
The not as hard way of doing it the hard way

Hello folks, here's a controller script for animating textures within the scene editor. Please read the information below on how to use it, download the .7z file containing the examples, and/or watch the video tutorial. (Note: the images in the .7z file had to be reduced in quality in order to upload correctly).

What it does
This controller script takes an Anim8or texture and swaps the file name on command, using a main controller script that reads the data of an animation controller for a sprite object. This script will animate any texture on any material that is applied to any mesh.

Applications

How to use the controller script
Download the .zip file attached to this forum post and extract it. The contents of the zip file should be:

Step 1: Setting up the sprite object


A unique object, material, and texture for each unique sprite you wish to animate

The sprite object, in the object editor, needs to contain a mesh with a material applied to it. This material needs to have a texture loaded into it. The important thing is the name of this texture object (circled in red in the image above). The controller script will be swapping the filename of this texture, and to do so it needs this name.

If you want to have multiple unique sprites in the scene that use the same sequence of images (just animated differently), you need to create a new object, a new material, and a new texture for each sprite instance you want to use. You don't have to make these copies if you only want to use one instance of the sprite in multiple scenes, or if you want to use duplicates of the sprite that all animate identical to each other in the same scene.

Step 2: Setting up the scene
The first thing you need to do is create a "sprites_enabled" boolean controller in the scene, applied to the "world" element. This is an on/off switch which enables or disables all of the animated textures in the scene. This is handy because sometimes Anim8or will randomly crash if you click on the sprite element while the controller script is active (the setFileName() in the script function seems to cause this random-seeming crash).



Add a "sprites_enabled" boolean controller

Do this by going to Edit->Controllers..., select the world element in the top drop down menu, and then clicking on the "New" button. A boolean controller can only have a value of 0 or 1. In the timeline on the first frame, set its value to 1 to enable it ahead of time.



Add and name your sprite object to the scene

Next, add your sprite object to the scene and give it a suitable name. For example in the image above, I named it "fire1_sprite". The reason for the "1" in the name is in case I wanted multiple unique instances of the sprite in that scene. This name is important since the controller script will be referencing it.



Mouthe needs both an anim_controller and a swap_controller

Now create two float-type controllers for that sprite element. The first one will be the animation controller, so name it something sensible like "anim_controller". The second one will be the swap controller (I usually name it "swap_controller", and is optional and only required if you want to animate two different sets of sprites on the same sprite element (like in the second .an8 file where the mouthe sprite has a run and jump animation that it swaps between).

What you just created were the controllers that tell the controller script which frames to animate for what set of textures. Next you'll have to create the element that holds the controller script itself. There is some flexibility in how you do this, but you can follow the next bit of instructions for an easy, organized way to manage your controller scripts.



Creating the containers for the controller scripts

First, add a target and name it "sprites_scripts" (or something similar). This will be the "container" that holds all of the controller scripts.

Next, add another target and name it based on the sprite you wish to control. For example in the image above, I named it "fire1_script". This target is what will hold the controller script. Then parent the "sprites_scripts" target to this target you just created. In the timeline, it should look something like in the image above.

Step 3: Configuring the controller script
In a text editor, open up the "sprite_controller.txt" file. There is a set of parameters that you need to configure in order for the script to know what textures to work with. Unless you are intentionally modifying the controller script to change its core programming, only modify the parameters that are between "/* FILL OUT ANIMATION DATA HERE */" and "/* EVERYTHING PAST HERE, LEAVE ALONE */"

Below is a description of each parameter. Please change any or all that are required for your specific sprites.

Enable/Disable
  1. $enabled = 1;

Required. Enables or disables the animation of that sprite. Handy if you have large amounts of sprites and just want to have a single one active while you work with it.


Texture Name
  1. $texName = "";

Required. This is the name of the texture that you made (circled in red in the image in Step 1).


Animation Controller Details
  1. $controllerAnimFloat = GetAttributeFloat("Sprite_Element_Name", "Anim_Controller_Name");

Required. Change "Sprite_Element_Name" to the name of the sprite element it's controlling. For example, it was "fire1_sprite" in Step 2. Change "Anim_Controller_Name" to the name of the animation controller you created for that sprite element. This was named "anim_controller" in the Step 2 example.


Animation Controller Type
  1. $controllerAnimType = "multiplier";

Required. There are two options to specify for how the controller script handles the values passed in the animation controller you specified above. The default option, "multiplier", interprets the values as the percentage of the animation cycle you want to play. For example, a value of 0 means it's the first frame of the animation cycle. A value of 1 means it's the last frame of the animation cycle. A value of 0.5 means it's the middle frame. A value of 2.5 means it's the middle frame, except in the second animation loop.

The second option is "frame". This allows you to specify the exact frame of the animation cycle (starts at 0). So a value of 0 means it's the first frame. A value of 1 means it's the second frame. A value of 51 means it's the 50th frame. If the animation cycle has only 25 images in its sequence, then a value of 51 would mean that it's at the start of the second loop.


Swap Controller Details
  1. $controllerSwapFloat = GetAttributeFloat("", "");

Optional. Leave blank if you don't need to swap the animation cycle with a different one for that particular sprite object. Fill the first string with the name of the sprite element it's controlling. For example, it was "fire1_sprite" in Step 2. Fill the second string with the name of the swap controller you created for that sprite element. This was named "swap_controller" in the Step 2 example.


Texture File Name - Prefix
  1. $texPrefix.push("");

Required. Fill in the quotation marks with the prefix of the texture file the animation cycle is using. For example, if a texture file is named "file_0001.png", then "file_" is the prefix.

If you are using a swap controller, then for each set of textures you need to animate, you have to add another '$texPrefix.push()' line. This is also required for all of the .push() parameters. The first .push() parameter corresponds to the value 0 in the swap controller. The second .push() parameter corresponds to value 1 in the swap controller. Etc, etc. Don't mix up the order of the .push() parameters.


Texture File Name - Number of digits
  1. $texDigits.push();

Required. The texture files in the animation sequence must be numbered sequentially with the same number of digits. "file_1.png" will not be considered in the same sequence as "file_0002.png". It must be named "file_0001.png". The parameter above specifies this number of digits. For example, "file_0001.png" has 4 digits, so you would place the number 4 inside the parenthesis with no quotation marks (it would look like '$texDigits.push(4);')


Texture File Name - Type
  1. $texType.push("");

Required. Set the file type. It'll be either png, bmp, gif, or jpg. For example, if the sequence of files were png files, it would look like '$texType.push("png");'


Texture File Name - Path
  1. $texPath.push("");

Required. Set the path to the sequence of files for that sprite. If you want to set a path relative to the .an8 file, and the files are in subfolders of that .an8 file, you would use something like '$texPath.push("./Path/To/Files/");'. Otherwise if you want to specify the absolute path to it, set it like '$texPath.push("C:/Path/To/Files/");' Make sure a forward slash is at the end for whichever of these options you choose.

If you placed all of the textures in the same path as what you specified for the texture directory in File->Configure, you can leave it as just '$texPath.push("");'. Note however that the script does not and can not look through subfolders.


Texture File Name - Starting Number
  1. $texStartingFrame.push();

Required. Use the same number as the first file in the sequence. For example, if the first file was named "file_0001.png", the parameter would look like '$texStartingFrame.push(1);'. If the first file was named "file_0024.png", it would look like '$texStartingFrame.push(24);'.


Texture File Name - Ending Number
  1. $texEndingFrame.push();

Required. Use the same number as the last file in the sequence. For example, if the last file was named "file_0036.png", the parameter would look like '$texEndingFrame.push(36);'. If the last file was named "file_0125.png", it would look like '$texEndingFrame.push(125);'.

-----

If you want to make it easier to read which set of .push() parameters applies to which set of file sequences, you can re-order it to look like this:

Alternative way to set multiple swap parameters
  1. // Swap value 0
  2. $texPrefix.push("");
  3. $texDigits.push();
  4. $texType.push("");
  5. $texPath.push("");
  6. $texStartingFrame.push();
  7. $texEndingFrame.push();
  8.  
  9. // Swap value 1
  10. $texPrefix.push("");
  11. $texDigits.push();
  12. $texType.push("");
  13. $texPath.push("");
  14. $texStartingFrame.push();
  15. $texEndingFrame.push();
  16.  
  17. // Swap value 2
  18. $texPrefix.push("");
  19. $texDigits.push();
  20. $texType.push("");
  21. $texPath.push("");
  22. $texStartingFrame.push();
  23. $texEndingFrame.push();



Step 4: Applying the controller script
Assuming you completed Step 3, copy the entire controller script to your clipboard (Ctrl+C). Next, double-click on the controller script target you had made in Step 2. Click on the '...' button next to the Location details, set the Expressions to 'On', and click the 'Edit' button. Select everything in the text field that pops up and press Ctrl+V to replace it with the controller script.


Copy the controller script into the script target's position controller

The reason we're using a controller script target and applying the controller script to its 'position' controller is so that we can bypass a bug in Anim8or, in which after setting a controller as an Expression, you can no longer access it via the timeline (or any other means aside from editing the .an8 file in a text editor). The only way you can access a controller is through the element's dialog box and clicking on the buttons corresponding to its preset controllers. Until this bug is fixed, you'll have to do it this way. Otherwise you don't have to create controller script 'targets' and instead just add controllers directly to the controller script container target you had first created. Then you'd apply the controller scripts to these controllers.

Step 5: Animating
If you want to animate the textures, you have to keyframe the animation controller and (optionally) the swap controller assigned to that sprite element. For example, in Step 2, this was "anim_controller" and "swap_controller".

Animation Controller
This is the main meat of the animation and tells the controller script which frame of the animation cycle corresponds to which frame in the timeline. Keyframe this on the timeline to any values you need, based on the animation controller type parameter you specified in Step 3. Anim8or will interpolate between these values on the timeline. Anim8or will interpolate between these values on the timeline and the controller script will round this value to the nearest integer, thus picking which frame of the animation cycle to use.

Anim8or currently doesn't have a means to create linear keyframes (that I know of, anyway). Meaning if you look in the graph editor, the paths connecting the keyframes will all look like curves until you manually change the path nodes. If you want to slow down or speed up the animations then having curves is fine. Otherwise adjust the node handles so that these paths are as linear (straight) as possible. You may have to set the keyframe type to "corner" or "step" in order to accomplish this.

Swap Controller
This controller swaps between the sets of animation sequences you had specified in Step 3 (using the .push() parameters). The first set corresponds to the value 0. The second set corresponds to the value 1, etc etc. Keyframe this on the timeline to any values you need. Anim8or will interpolate between these values on the timeline and the controller script will round this value to the nearest integer, thus picking which set to use. I recommend using "step" type keyframes for the swap controller.


Important things to know or remember



Video Tutorial


Part 1 (https://youtu.be/Y2xKzqJDCAg) | Part 2 (https://youtu.be/T97LMvvOYdE)
Title: Re: Animated Textures Using Controller Scripts
Post by: Hypure on January 18, 2016, 07:33:52 pm
Your the man, guy! It looks tricky... But it's worth it.  Thanks Raxx!   8)
Title: Re: Animated Textures Using Controller Scripts
Post by: Steve on January 18, 2016, 09:16:18 pm
Wow, nice job, Raxx!
Title: Re: Animated Textures Using Controller Scripts
Post by: neirao on January 19, 2016, 01:15:02 am
Very cool Raxx! a little complex but easy to implements! :)
for a help in "initial square' i go post in "Script page" my "square standing" script(tree script modified) ...
Title: Re: Animated Textures Using Controller Scripts
Post by: neirao on January 19, 2016, 01:22:43 am
here the script(i posted time ago...)  (http://www.anim8or.com/smf/index.php?action=dlattach;topic=1705.0;attach=13178;image)
http://www.anim8or.com/smf/index.php/topic,1705.msg37891.html#msg37891

:)
Title: Re: Animated Textures Using Controller Scripts
Post by: ClassicTyler on February 24, 2016, 08:44:35 pm
Oh goodness, so much to it, but very promising.

Now, could I apply this to a flat texture, say, like water? That way it looks like it's flowing.

Someday I'll have to sit down and try all this.
Title: Re: Animated Textures Using Controller Scripts
Post by: Raxx on February 24, 2016, 09:28:35 pm
Yeah, you can apply it to a huge body of water that has the water texture tiled, and assuming it's a seamless flowing animation, it'll look like the entire body is flowing in one direction.
Title: Re: Animated Textures Using Controller Scripts
Post by: texastuner on October 21, 2016, 03:42:13 am
I believe I am having a duh moment I cannot locate said attachments for your tutorial
Title: Re: Animated Textures Using Controller Scripts
Post by: Raxx on October 21, 2016, 03:58:32 am
It's located at the bottom of the first post as an attachment, under where the video tutorial is located. You'll need 7-zip (http://7-zip.org) or a modern file archiver/extractor program to extract the contents of the .7z file.
Title: Re: Animated Textures Using Controller Scripts
Post by: texastuner on October 25, 2016, 07:59:21 pm
Talked about duh moment wasn't logged in before asking question, thank you for the locale and your hard work on this most awesome method keep up the good work, we appreciate it greatly.
After actually attempting to view both an8 files I realized that all picture files are PNG and can't load them might use gimp to export to jpg unless im missing some awesome feature of an8 that i havent figured out yet
Title: Re: Animated Textures Using Controller Scripts
Post by: dancingshoes on October 30, 2016, 02:59:33 pm
Raxx!

Only recently came across your animated texture scripts.

However, when I try to load either of your examples, Anim8or crashes as soon as I go to the scene mode.

Tried 1250 & 1258. 64 bit Win 7.

I accomplished a similar thing using an autoit script that manipulated the an8 file. It eats a lot of memory. Does yours?

Hope it goes native in Animator.

Thanks.

Dan

Title: Re: Animated Textures Using Controller Scripts
Post by: Raxx on October 30, 2016, 07:15:32 pm
Hi dancingshoes, I gave it a shot and it doesn't crash when I go into scene mode. I suppose it's due to some ghostly reason that it crashes for you, I've never really figured it out and I think it's something only Steve can address.

I created a new set of files with the sprites_enabled controller set to 0, effectively disabling it so that it *shouldn't* crash when you enter the scene editor. Just set the controller back to 1 in the time track when you get in. Click this link (http://wub-wub.com/Animated%20Textures%20with%20Controller%20Scripts%20-%20Resources.7z) to download it.

As for the amount of memory it uses, theoretically it shouldn't use any more or less than with normal non-animated textures. What it'll do is increase the CPU cycles and harddrive activity when switching between frames since it's swapping out the files in the material.
Title: Re: Animated Textures Using Controller Scripts
Post by: daniel99 on November 12, 2017, 04:50:29 am
     I have a project now where I really need animated textures. The problem: it won't work for me at all. When I open your projects, they crash every time in scene mode. 

   I tried following your tutorial step by step, and it doesn't animate my textures. I can't understand what the problem is. Please help.
   Mine doesn't crash in scene mode, but it doesn't work either. The texture is  w001.jpg to w120.jpg, 800/800
Title: Re: Animated Textures Using Controller Scripts
Post by: Raxx on November 12, 2017, 06:06:04 am
Can you share your project, or a lesser example of with your step by step approach? Also, attached is a modified version of the first post's an8 files. These don't have the sprites_enabled controller, so it shouldn't crash when you go to the scene editor.

You'll have to add the boolean sprites_enabled controller to these files via Edit->Controllers and give it a boolean value of 1 in the timeline in order to see the animation(s) play.
Title: Re: Animated Textures Using Controller Scripts
Post by: daniel99 on November 12, 2017, 07:21:16 am
     These didn't crash. I've added sprites enable controller and they animate.
     Although I don't totally understand how this script works yet, it seems. For my material, I need the normal map. So I tried to add the same fire texture to a normal map as well and now it crashed. So, if I make any changes to the material after the script is in place, it supposed to crash?
     I kept saving over my project, and delete it after a few tries.
But mine is simple. I'd appreciate if you'll find the time to create a new project, and I'll add my textures in the ./sprites" folder afterward. You can use any images named "w001.jpg to "w150.jpg'. Size is 800x800. It's gonna be a sandy terrain, where the wind kinda blows the sand slightly, and that's why I use only the normal map for it.
     I'm sure I'm doing somethin' wrong, but I haven't figured out what...yet!
Title: Re: Animated Textures Using Controller Scripts
Post by: fefe01 on November 12, 2017, 04:57:01 pm
Thank you very much raxx! I think that it it would be helpful even though i am not really good at scripting language! :)
Title: Re: Animated Textures Using Controller Scripts
Post by: daniel99 on November 14, 2017, 05:48:29 am
@Raxx  I tried to replace the screen images with my sequence, and that's the only way I can make it kinda work. And all the crashing. I dunno what's the problem. Maybe I'm idiot  :) :) :)
   I've been using terranim8or 6 for the urgent project, but it's a pain in the ass because it doesn't have normal maps. I had to edit all 150 materials of it.
   Maybe Steve will do something about animated material soon. I mean, it's a useful and much-needed function anim8or should have. And maybe a displacement map.
   Maybe a possible way to solve this problem sooner would be the creator of Terranim8or to add the normal maps...
Title: Re: Animated Textures Using Controller Scripts
Post by: Raxx on November 19, 2017, 07:47:12 pm
@daniel99 Sorry, haven't been able to get to this. Have you been switching between the Scene editor and the other editors a lot? I recommend disabling animation using the sprites_enabled controller and saving before leaving the scene editor, to avoid crashing as much as possible.
Title: Re: Animated Textures Using Controller Scripts
Post by: dancingshoes on February 27, 2018, 09:49:51 am
In trying to see why your animation script crashes Anim8or for me (build 1318, Win 7 64 bit) I discovered, at least for me, the following:
1. Start a new project.
2. Go to Scene mode and create a Controller under World and assign a new Key in the time line.
3. Save and close the project.
4. Reopen the project.

Anim8or crashes either on opening the project or when selecting Scene mode. This is in part why your script fails for me.

Doesn't seem to matter if it's a boolean controler or float, first key frame or later.

I atttached an example an8 file.
Title: Re: Animated Textures Using Controller Scripts
Post by: Steve on March 02, 2018, 09:05:44 pm
dancingshoes: thanks for the sample project. I'm working on a fix.
Title: Re: Animated Textures Using Controller Scripts
Post by: Steve on March 05, 2018, 02:27:30 am
@daniel99 OK here's a build that should fix the crash. Give it a try and let me know if it works.

http://www.anim8or.com/download/preview/files/animcl1318plus.zip (http://www.anim8or.com/download/preview/files/animcl1318plus.zip)
Title: Re: Animated Textures Using Controller Scripts
Post by: dancingshoes on March 13, 2018, 02:21:59 pm
Steve

Thank you for the response and please excuse my tardy reply.

Don't know if the plus program was supposed to fix my issue. It fixes the test.an8 I posted but, for me, does not fix Raxx's script which still crashes.

Not to get you too bogged down in this, but I editted Raxx's example 2 an8 file and moved the "sprites_enabled" controller from the world, for a test, to "Camera01" (and of course changed the "mouthe_script" references from world to Camera01) and it doesn't crash, with nonplus 1318.

However I get inconsistent results as to whether the sprite works. The object mode texture selector is updated via the script, but the scene mode object texture is not always updated. If it works, it works thru out the scene but mostly does not work. I can't characterize when it works and doesn't.

Minor issue: The Object Mode Materials Texture Selector load button at the bottom doesn't update the static text window to show the newly selected file name. Caused confusion for me.

Thanks again for Anim8or!

Dan
Title: Re: Animated Textures Using Controller Scripts
Post by: AlecJames on April 01, 2018, 08:54:46 am
Hi Raxx and all texture animators :)

This is a really clever script, Iím using it in my animation challenge in the facebook group.  Thanks so much.

I had a couple of random problems Ė

Iíve found 2 causes for these issues:

1) If the path anim_controller (multiplier) value goes negative and the an8 file is saved, the texture file name is saved as (example) file0000-3.png.  I know I shouldnít let the value go negative by setting a nice linear gradient in the graph editor (BTW excellent video tutorial) but it took me a while to understand what was happening.

I changed
// Round down to the nearest frame when the multiplier is applied
   $texFrame = floor(max($controllerAnimFloat,0) * $numFrames + 0.5);   

Of course there is still no animation while the key is negative but I donít have to redo the texture as a result. 

2) This is still puzzling me; Iíve got a work around but donít really understand the root cause.

When anim8or builds the texture file name, sometimes it prepends the full path to the project dir and with my relative path script parameter of ./sprites/anim1 the texture filename path becomes

C:\pathtomyproject\ ./sprites/anim1/file0000.png

Which anim8or doesnít complain about but does not appear to load.

Other times anim8or prepends .\ and with my relative path script parameter of ./sprites/anim1 the texture filename becomes

.\ ./sprites/anim1/file0000.png

Similar problem.

When I started play with the script I had a relative path of ./sprites/anim1 and it worked just fine so there must be a third variant (the expected path result), but I canít recreate it now.

Iím puzzled because I canít work out what causes each of the different path variants? (Iím on win7 x64)

My work around is either

Use an absolute path C:/pathtomyproject/sprites/anim1/ as the script parameter

Or (this is what Iím using at the moment, EDIT: didn't stay working at file open, but worked while editing / rendering)

"Sprites\\anim1\\"  as the script parameter

Hope this helps others that may have similar issues. If its not working the place I look is the object material definition to examine the path to the texture, it should be a valid path to one of your texture files, the file number is approx the last frame you viewed in the scene + starting animation file number.

@Raxx, Thanks again for a great script 

A
Title: Re: Animated Textures Using Controller Scripts
Post by: Steve on April 01, 2018, 04:00:52 pm
Oops!  I hadn't thought about relative paths when I was writing the texture file open code. I'll have to give this some more thought. It's pretty crazy the way it is now.
Title: Re: Animated Textures Using Controller Scripts
Post by: AlecJames on April 02, 2018, 07:33:28 am
Thanks Steve - I can't work out the cause and effect when the file path changes to something I didn't expect.  I set up a repeatable test and all looks good, then some time later my test setup does not have the same result. I can't be sure when something changes whether I changed something in my test project or left something in an odd state or whether something changed in anim8or?

Title: Re: Animated Textures Using Controller Scripts
Post by: dancingshoes on April 07, 2018, 12:15:40 pm
Here's a program that automatically creates an an8 file for animating a texture using a sequence of still images per Raxx's design. Setup only involves selecting, in Anim8or, the first texture file in an animation sequence, naming the texture, and then running this program which creates a new, animated An8 file. See the readme for details.

It's not as versatile as Raxx's but it is a no brainer to use. It can handle looped and unlooped sequences.

Like everything, it's experimental. If it works for you, great.

(I believe there's an error in Raxx's script that may have caused my earlier problems: it doesn't seem to handle the numbering of the 0th image properly. It adds an extra '0' (????) making the 0th texture unfindable.)
Title: Re: Animated Textures Using Controller Scripts
Post by: AlecJames on April 07, 2018, 10:36:32 pm
Thanks - looks like you've been busy!

I've got Raxx's script working well in my project. At the moment I've only got one animated texture in my project but I l really like the effect so I'd like to squeeze in some others.  In my scene I wanted "clutter" and it's taking ages to model all the stuff so not sure if I'll have time.

I will try it out, thanks for the hard work :)