Lightwave
Plugin Tutorials - Lesson One
| Introduction compiling
your first plugin Having been lurking around receiving the Lightwave Plugins mailing list for a couple of years now, I get the impression that its not just me that thinks the documentation for creating plugins leaves something to be desired. Its for this reason that I have started this series of tutorials. If you like them or loath them I still like getting email so send me a message. I got into writing Lightwave plugins after reading Bob Hood's introduction to his wonderful LScript language, in Inside Lightwave 3D. I cannot stress how important both Bob and Ernie Wright are to the community of plugin developers, thanks guys. When Im doing paid work Im an artist, so if I can write plugins, so can you. So lets get started on our first tutorial. The first step is to download the SDK (Software Development Kit) from the Newtek site. Unzip it to some sensible folder making sure to take the directory information. From now on everything will be totally VC++ orientated, because this is my development platform and I am strictly an IDE (Integrated Development Environment) man. I can't be doing with writing in a text editor and command-line compilng. So we need to tell VC++ where to find the include files and the library. This is done using options/directories, add the path for the includes and the library files. You will find both the includes and the library files in the SDK that you unzipped. If you are working on Intel then you will find ready made versions of serv_w.obj and server.lib, which you will need later, in the tutorial files. Place these files in DevStudio\Vc\Lib. If you are on another platform then you will need to compile your platform specific version. An Overview of Layout Plugins Lighwave plugins currently come in 18 flavours. These are:
Lightwave 6 will add another 8 to these
If you add a fancy interface to a Layout plugin then you also need to know about how to create all those input boxes that are supplied by
So there is a lot to learn! But, for now we are going to create a groovy little Item motion plugin that will bounce a ball when it hits a Y value of zero. I am absolutely useless at remembering all the bits of syntax in all the calls so I have created a blank version of each of the different kinds of plugins and this is where we will start. Firstly the standard headers that you will need to include. // ItemMotion.C -- Blank Item Motion Plug-in // by Nik Lever // last revision 2/3/99 #include <splug.h> #include <moni.h> #include <lwran.h> #include <lwpanel.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> // Disable warnings for various conversions. #ifdef _WIN32 #pragma warning(disable:4244) #endif //Typedefs typedef unsigned short int USHORT; Now here are some useful global variables that we will use later
Lightwave can have lots of objects using the services of a plugin. It identifies each one by passing an instance structure. This is just a void pointer that you cast into something that contains useful data for your plugin. Create your structure as a typedef and then the casting is easily achieved.
Now we have the standard functions that Lightwave uses for a Item Motion plugin. More about this in a minute. Take a look at them and be confused be very confused. Actually, they make far more sense than at first seems apparent and after the next 4 lessons you will understand them clearly.
The location of all the preceeding functions is passed to Lightwave with the activation function. This is the first thing that any plugin does, it tells Lightwave where to find the instructions it needs to run the plugin. We are really only interested in LW5 or above so the version number will be higher than 1. If it is not then we bomb out. We also use the activation function to fill in the global variables we declared earlier. The actual details of these functions varies with the different plugin types. But, in a later tutorial you will learn how to use the LWSDK include files to give you the information you need to create the other types of plugins.
Finally, we have to tell Lightwave where to find your plugin and its details. This is the data that will be stored in the LW.cfg file when you use AddPlugin from the options panel of Lightwave Layout.
So that is the overview of a Blank Item Motion Plugin that does absolutely nothing! Creating your first plugin To make it even easier download the tutorial files. The tutorial files include a Visual C++ project, but you'll want to know how to roll your own so this is how it was created.
Now we will amend our instance structure. So that we can keep a check on the status of our plugin. To make the code easier to read we will create a new type, VECTOR. In this plugin we are applying Newtons Second Law to a projectile. The only force working on a projectile is gravity. The maths is standard stuff, if you know the launch speed and angle then you can calculate the position at any time. Were going to calculate all these positions for an entire scene and store it in an array. This is both convenient and is the only way to work when we get to Displacement Maps so its useful to get into the habit. Because everything is stored in and array, we need a pointer to the array and how big the array is, this kept in the duration parameter. We want the user to be able to alter the starting position so we store that in an array of double values, where [0] is x, [1] is y and [3] is z. The final parameter in our instance structure is the variable mode. We use this to inform our plugin when it should perform different actions. We also define a couple of useful constants, gravity is defined as 9.82 ms2 and DEG2RAD converts between degrees and radians. There are 360 degrees and 2PI ( PI is approx 3.1415) radians in a circle. When programming in C all sin and cos functions expect radian value.
For our Activation function we simply rename our Blank Item Motion to gravity. Other than that no changes are required. Now we look at the changes to the standard handlers. Create Here we allocate memory for our instance structure and assign some default values.
destroy If we created the memory for an instance structure then we must destroy the memory allocated to it, including the array of position values.
descln The title that appears when you select Motion Plugins from the Graph Editor in Layout is defined using the descln handler. We keep the information in our instance structure. This allows use to create data specific to this instance of the plugin. For now we just use this to give the current duration:
copy, load and save The only change here is that we set the mode parameter in the load handler to 2. This can be used later to inform the process handler that the plugin has just loaded. Creation, normal running and loading normally involve different types of process. This is just planning ahead.
process This is where most of the work is done. But before we look at the code lets take a look at the ItemMotionAccess structure that is passed to the process function by Lightwave. In the include file it is defined like this
A LWItemID is simply the number of that object in the list of objects in Layout. It is not a pointer to the object. The frame value is obvious, time is in seconds but is a floating point value, a decimal. You can get at any of these in the standard way you use a structure in C. That is you use the following syntax myframe=ia->frame; The other two options are pointers to functions. Here you pass the type of parameter you want, it could be LWIP_POSITION as we will use here or If you are confused about the matrix options then maybe this will help |R1 U1 F1||x| |R1*x + U1*y + F1*z| |R2 U2 F2||y|=|R2*x + U2*y + F2*z| |R3 U3 F3||z| |R3*x + U3*y + F3*z| Here R represents LWIP_RIGHT and U and F are LWIP_UP and LWIP_FORWARD respectively. When any point is multiplied by these it gives its new location, you can see from the matirx operation above that R affects only the x value of the point, U the y and F the Z. OK, so we are now ready to put all this to work. First we check if we are on frame zero. If we are then we return so the user can alter the position of the object on frame zero. Then we find out which mode we are currently using. 0 means the plugin has just been created so we better create the data for the path. 2 means we are just loaded so we also need to Create the path. If the mode is 1 then we have a path but we need to check if it needs amending, we do this by check the current position for frame 0 against our stored value. If its changed then we need to update our path. If not then we amend the current position to our calculated value.
So you probably want to know whats in CreatePath. Well its not terribly complicated but it does contain a bit of maths. Many plugins require only basic maths so don't be put off if you feel it is a little confusing. First we check if there has been a path before and free any memory that was created if there was. Then we create some more memory for our path. Then frame by frame we create the path, check for y<0. If it is then we update the speed parameter and restart the clock and continue our calculation.
So that's it. Now compile it and run in Debug mode, Visual C++ will ask for an executable to use browse to Newtek\Programs\Lightwav.exe. Ignore the no debug information in executable messages. Add your plugin, you only need to do this once, after that Lightwave saves the path in its Lw.cfg file. Either create a scene with an object and from the Graph Editor, Motion Plugins button, scroll down to find Gravity and add it; or use the tutorial files scene "bounce1.lws". Now run the scene. Try changing the y value of the object on frame zero.
SummaryHopefully this first tutorial wasn't to over facing. In the next lesson we will add an options box so that we can change the value of gravity, launch speed and angle, and bounce coefficients. Lesson 3 we will use a NULL to define the bounce point and improve our options box to include a bitmap. Lesson 4 we will look at using a Displacement map to alter an object. Watch out for these further tutorials in the coming weeks. Lesson
2 - Loading, saving and options
boxes.
|
|
Millennium 3D Textures, models,tutorials and lots of other free stuff.
|