Skip to content

Instantly share code, notes, and snippets.

@mattcox
Last active July 12, 2018 21:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattcox/48b15b1c5f61919e0871 to your computer and use it in GitHub Desktop.
Save mattcox/48b15b1c5f61919e0871 to your computer and use it in GitHub Desktop.
This sample plugin demonstrates how to create a very simple and pointless modifier. The modifier attaches to every light in the scene and sets the light radiance value to the distance from the center of the world.
/*
*
* modifierSample.cpp
*
* This sample plugin demonstrates how to create a very simple and pointless
* modifier. The modifier attaches to every light in the scene and sets the
* light radiance value to the distance from the center of the world.
*
*/
#include <lxsdk/lxidef.h>
#include <lxsdk/lx_plugin.hpp>
#include <lxsdk/lxu_modifier.hpp>
#define SERVER_NAME "lightModifier"
/*
* The ModifierElement performs the actual evaluation of the channels. An
* instance of this is spawned for every light in the scene by the ModifierServer.
*/
class ModifierElement :
public CLxItemModifierElement
{
public:
ModifierElement (
CLxUser_Evaluation &eval,
ILxUnknownID itemObj)
{
/*
* In the constructor, we add the channels we want the
* modifier to read and write. The index is stored in the
* chan_index variable, however, it's should always be 0.
*/
CLxUser_Item item (itemObj);
mChanIndex = -1;
if (!item.test())
return;
/*
* We'll add two channels. The world position matrix will
* be read and the radiance will be written.
*/
mChanIndex = eval.AddChan (item, LXsICHAN_XFRMCORE_WPOSMATRIX, LXfECHAN_READ);
eval.AddChan (item, LXsICHAN_LIGHT_RADIANCE, LXfECHAN_WRITE);
}
void
Eval (
CLxUser_Evaluation &eval,
CLxUser_Attributes &attr) LXx_OVERRIDE
{
/*
* As the name suggests, the Eval function performs the
* evaluation. It reads and writes the channels allocated
* in the constructor, using the Attributes interface and
* performs whatever calculations it wants inbetween.
*/
CLxUser_Matrix matrix;
LXtVector position;
double radiance = 0.0;
unsigned tempChanIndex = mChanIndex;
LXx_VCLR (position);
if (mChanIndex < 0)
return;
/*
* Read the world position matrix channel. This will be
* read as a ILxMatrix COM object. If the matrix is read
* correctly, we get the position vector from the matrix.
*/
if (attr.ObjectRO (tempChanIndex++, matrix))
matrix.GetOffset (position);
/*
* Calculate the distance. We just use the magnitude of
* the position vector for this.
*/
radiance = LXx_VLEN (position);
/*
* Write the radiance value back to the output channel.
*/
attr.SetFlt (tempChanIndex++, radiance);
}
private:
int mChanIndex;
};
/*
* The ModifierServer allocates ModifierElements to perform the evaluation. It
* does very little, other than manage the overall state of the modifier.
*/
class ModifierServer :
public CLxItemModifierServer
{
public:
static void
initialize ()
{
CLxExport_ItemModifierServer <ModifierServer> (SERVER_NAME);
}
const char *
ItemType () LXx_OVERRIDE
{
/*
* Here we are expected to return the name of an item we
* want to modify.
*/
return LXsITYPE_LIGHT;
}
CLxItemModifierElement *
Alloc (
CLxUser_Evaluation &eval,
ILxUnknownID itemObj) LXx_OVERRIDE
{
/*
* The modifier is allocated here. We create a new instance
* of the ModifierElement and return it.
*/
return new ModifierElement (eval, itemObj);
}
};
/*
* Initialize the ModifierServer. The ModifierElement class doesn't need
* initializing, as these are created as needed by the ModifierServer.
*/
void
initialize ()
{
ModifierServer :: initialize ();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment