Browsing"Technical Research"

Stretchable Limb System for Biped

Nov 18, 2008 by     No Comments    Posted under: 3dsMax, Characters, Rigging, Technical Research

In a recent project, we were in a position that we needed a rig that incorporated stretchable limbs. The proportions of the characters made it neccesary in order for them to be able to do things like pick up objects etc. This seems to be a common problem when you have characers with large bodies and short arms. Unfortunately, this had to be set up in a hurry, so building a custom IK rig was out of the question. The solution we came up with was to bind a set of expression controllers into a custom attibute definition.

Each hand, foot and spine link is wired together, with the X scale controlling the main linear scale and the YZ scaling performing a mild squash/stretch effect. The intermediate limbs also have an attribute to control the percentage, should you want to perfom slightly less scaling at the top of the spine chain, for instance.

Each control node can launche a floater control (This is WIP, as i want to refine the interface into a dotnet control) This has sliders and node selection tools for the control of the scaling.

This is the expression control dialog – Here you can see the variables that are bound to the custom attribute parameter block. This is possibly going to be adapted into a script controller in the future, using weak references to tie in the whole rig to other animation systems.

Finally, and most importantly the setup of this extra layer is automated in a rollout, that allows you to store presets and tweak the intermediate controllers before you apply. It is a system that can provide this very quickly – It only provides an interface to biped’s subanim functionality.

Delving into the DotNet SDK – A timechange callback via Dotnet

Oct 28, 2008 by     No Comments    Posted under: 3dsMax, DotNet, Technical Research

A quick look into the dotnet SDK shows a few useful classes that one can use. Over time as I discover what some are for I will hopefully be able to document some of them. One class that stuck out to me was the ManagedServices.AnimationFrameChangeListener class. After a quick inspection of the methods and properties I was able to work out how to enable this and get it talking to max – namely calling a function when the timeslider was scrubbed back and forth.

The example is just to show it working, it updates a label control on the dialog with the current frame. However, knowing that this is possible from dotnet is interesting, as in the future it might be possible to use it to bind max controllers to dotnet objects and controls. Whether it is any better or worse that the current timechange callback that MXS implements is something I’m yet to figure out. The way i see it is that it’s been put there for a reason, I’m sure a use can be found!

global DotNetTimeChangeCallback

rollout DotNetTimeCallback "DotNet Time Callback" width:194 height:70

fn testcallback =
DotNetTimeCallback.framelbl.text = "Current Frame - " + currenttime as string

button btnaddCB"Add Callback" pos:[3,3] width:92 height:40
button btnremoveCB "Remove Callback" pos:[99,3] width:92 height:40
dotnetcontrol framelbl "label" pos:[4,46] width:186 height:21

on DotNetTimeCallback open do
framelbl.borderstyle = (dotNetClass "System.Windows.Forms.BorderStyle").fixedsingle
framelbl.backcolor = (dotnetclass "System.Drawing.Color").slategray
framelbl.forecolor = (dotnetclass "System.Drawing.Color").black
framelbl.textalign = (dotnetclass "System.Drawing.ContentAlignment").middlecenter
framelbl.text = "Current Frame - " + currenttime as string

on btnaddCB pressed do
if DotNetTimeChangeCallback == undefined do
DotNetTimeChangeCallback= dotnetobject "ManagedServices.AnimationFrameChangeListener"
dotNet.addEventHandler DotNetTimeChangeCallback "AnimationFrameChanged" testcallback
framelbl.backcolor = (dotnetclass "System.Drawing.Color").orangered
framelbl.forecolor = (dotnetclass "System.Drawing.Color").yellow

on btnremoveCB pressed do
dotNet.removeEventHandler DotNetTimeChangeCallback "AnimationFrameChanged" testcallback
DotNetTimeChangeCallback = nothing
framelbl.backcolor = (dotnetclass "System.Drawing.Color").slategray
framelbl.forecolor = (dotnetclass "System.Drawing.Color").black


createdialog DotNetTimeCallback

TrackBot – A Max Custom UI Control for Characters

Oct 27, 2008 by     No Comments    Posted under: 3dsMax, Characters, DotNet, Technical Research, User Controls

This control was made to try and build some UI shortcuts when using morph controls on a character. I wanted to be able to add a control that gave me the ability to reset, nudge and scrub the morph values. In the past I would have to build each button control in MXS and make sure they all worked.

With this control, I am hoping it will work well enough to use in a facial rig setup.

There are a few extras with this control of use. Firstly, the slider, once focused can be moved by rolling the mouse wheel. This makes it good for fine tuning expressions. And secondly, the label color can be changed so that you can visually group expressions together by type. The nudge buttons can be used with shift and control to nudge values of 10 and 5 respectively. I will add a property to set these soon, as you may wish to specify max and min values smaller than this.

The buttons are drawn with GDI+, with the exception of the key icon, which is embedded as a resource in the control. I would like the button images to fill with the control color eventually too.

Apart from the Valuechanged event, there is a setkey event that is fired every time – yup, you guessed it – the setkey button is pressed.

Here is the class diagram so that you can see all the properties and events-

  • BarColor – The color of the right hand side of the slider
  • ElapsedColor – The color of the left hand side of the slider
  • ResetValue – Specify a value for reset, in case your slider goes negative for example.
  • Title – The text on the control
  • LabelColor – the text background

the slider is a C# control from CodeProject. I have used it because it implemented the great mouse wheel functionality. I have mirrored some of the properties in the control to allow the user to change the slider ui colors. I am currently trying to convert the source to VB so that i can embed it within the control. You can see the article here

One thing i have noticed with running dotnet controls in the max command panel is panel seems to refresh after the controls, and subsequently makes them dissapear. The only way to get them back is to drag the command panel out and in again. While i am not exactly sure why this is happening, it can be fixed in a slightly hacky way by placing a timer with an interval of 1 in the rollout which ticks once, invalidating the controls via the refresh() method, like so –

rollout Trackbot "" width:170 height:249
dotNetControl TBslider1 "LoneRobot.Trackbot" pos:[1,3] width:156 height:54
dotNetControl TBslider2 "LoneRobot.Trackbot" pos:[1,61] width:156 height:54
dotNetControl TBslider3 "LoneRobot.Trackbot" pos:[1,119] width:156 height:54
dotNetControl TBslider4 "LoneRobot.Trackbot" pos:[1,174] width:156 height:54
timer refresh "" interval:1

on Trackbot open do = true

on refresh tick do
TBslider4.refresh() = false



Hello again, In my recent article about ColorMatrix, I included an update to my TrackBot slider assembly. Previously, it had included a C# slider component that I handled via a custom event. Using this method can be really useful, as you can make a composite control of many other existing elements. The UI is still the same although I changed the appearance of the slider slightly. (In the picture below, I’ve hidden the lower controls by making the UI height of the dotnetcontrol smaller)

Click the image if you want to read the ColorMatrix article, and get the code for Image adjustments in Max.

I’ve updated the assembly with a VB conversion of the slider component, which means that it is now integrated into one assembly. I’ve changed the way the event is triggered also, so let me know if it doesn’t function as you expect. As usual, it is a download below.

download script

Retrieving the 3DSMax File Thumbnail with DotNet

Oct 5, 2008 by     12 Comments    Posted under: 3dsMax, DotNet, Maxscript, Technical Research

Firstly, a small disclaimer – If you are unsure about any of the information contained on this page, Please do not try to implement it.

Before Max opted for DotNet integration, You could use the Windows ActiveX thumbnail component to view the 3dsMax file thumbnail. I have always found this small image to be very useful. However, when looking for a method to retrieve this via DotNet, I found it much more difficult. There is very little written about this, and I was getting nowhere until and I was fortunate enough to have Cuney Tozdas of Splutterfish point me towards two C++ files in the SDK examples. Please note that I am not a programmer, so apologies if there are any inaccuracies in my text.

How Max Stores it

The notes in the SDK pointed me towards the notion of IPropertyStorage and Structured Storage. Basically, the summary info of a Max file is set using this method. So not only is the Thumbnail stored in this part of the file, there are options to store many other pieces of information pertaining to the maxfile. You can see this by picking File>Summary Info in 3dsMax. The bad news is that novices like myself are not going to get near the level of programming needed to access this part of a file without some C++ knowledge.

Fortunately, help is at hand because it just so happened that while researching IPropertyStorage I stumbled across something on from Microsoft. MS Office files also use the same method as 3dsMax to store information in office files, using OLE Structured Storage, and Microsoft have provided a class for dealing with the lower level stuff for you called DSOFile.

DsoFile is a COM class and can be freely downloaded from this link

And the tricky bit….

Com classes need to be registered, which means that you have to use regsrv32 in order to do this. If you use the installer from the Microsoft website it will perform this step for you. However, should you ever move the dll or are interested here are the steps for performing this manually. If anyone knows about building setup projects in Visual Studio to automate this i’d be grateful if they could let me know, as i would much prefer to give an installer for this and save everyone the trouble.

  1. Once your Window’s operating system has loaded completely, click on Start and then click on Run.
  2. Input in the Run field a command that tells your computer to register the DLL file. You will need to input specific information including the path and the file name. The following is a template for the command: regsvr32 “FileName.dll”
    It is important to note that path is the actually location or directory of where the file is located.

  1. Once the command is input into the Run field correctly, press Enter.
  2. Once the DLL has been registered, you should receive a confirmation in the form of a pop up box.

This message will list your newly registered DLL file and confirm that is was successfully registered into the registry.

Once registered, you will now be able to use this class in Visual Studio. I’m not going to go into how to use DSOfile for this, as you can figure this out from the source provided from microsoft. When you add a reference to a COM class in Visual Studio, it creates an interop class that allows the .net framework and the COM class to talk to each other. So as well as registering the DSOfile dll, you will need to load the InterOp class as an assembly in any MaxScript code to use it.

The MaxFileInfo Class

I have written a basic dotnet class with a few properties and an overloaded method to retrieve the Max Thumbnail. Note that when instantiated, the MaxFileInfo class creates a MaxFileinfo dotnetobject. This means that once created, it will automatically reference the information properties. However, the Thumbnail access is fast so it is generated on demand. In my HitchHiker utility at the top It propagates the control almost immediately.

to create a MaxFileInfo object, you provide a string path variable

MaxFileInfo “<Maxfile path and filename>”

I have provided two options – calling Thumbnail on the file will return a DotNet image, useful if you are building a dotNet rollout in max, or by specifying Thumbnail True will copy this to the clipboard and allow you to use getclipboardBitmap() to put onto a MXS button. I have included a small example of the two methods in the download.

Still to do…

This class will only currently work in 32 bit versions of Max and Windows. Someone very kindly recompiled DSOFile for the X64 platform for me and i am working around a couple of issues at the moment, so I will hope to release a working version for the X64 platform very soon. I am slightly behind on this because my Laptop runs 32bit vista and my work machine XPx64, so i don’t get an awful lot of time to test in this environment. I will be upgrading my laptop shortly in order to develop this further, as without 64bit compatibility it is about as much use as a chocolate teapot. Indeed, i wish it was more straightforward.

I will be the first to say that this implementation is far from perfect. There are a couple of other references that need to be addressed depending on the platform you are running. On XP, I sometimes had to provide the stdole.dll also, as well as visualbasic.compatibility.dll as this is used by the class to convert the picture thumbnail to a dotnet image.

If you have any questions or need help with this class, feel free to email me (pete at lonerobot dot com) or PM me via CGTalk. If you want to use this in any scripts, you are freely welcome to do so, although I’d appreciate a mention!

I have also looked into extending this class with a few GDI+ methods, embedding the file information into the image before it returns it with some layout control, as well as a crude resampling routine to resize the thumbnail to something larger.

Included in the download is a very basic utility written in Visual Studio that allows you to browse files via a treeview. It has drag and drop functionality too. Its just provided as is, in the hope it would be useful to someone.

The other thing to add to this class library would be the comprehensive ability to specify the summary properties of a maxfile via dotnet. If you think this would be of particular use to you, please let me know, and I might be able to find the time to write it for you.