Thursday, May 22, 2008

Creating a custom shake node deriving from an existing one

I just found you can make a custom shake node easily deriving from an existing shake node.

#include <NRiIPlug.h>
#include <NRiMove2D.h>

class NRiFx_Linkage TmpTest : public NRiMove2D {
public:
    virtual int eval(NRiPlug *p)
    {
        NRiSys::error("TmpTest eval() called.\n"); //Just prints out something in the console.
        return NRiMove2D::eval(p);
    }
    virtual ~TmpTest(){}
    NRiDeclareNodeName(TmpTest);
};

const NRiName TmpTest::thisClassName = "TmpTest";

You may also want to use Move2D's creator function but you can't because a creator function usually creates a node and set default parameters at the same time. Instead you'll need to set parameter values directly.
extern "C"
{
   NRiExport NRiIPlug *TmpTest_(
      NRiIPlug *img,
      const char *xPan,
      const char *yPan,
      const char *angle,
      const char *aspectRatio,
      const char *xScale,
      const char *yScale,
      const char *xShear,
      const char *yShear,
      const char *xCenter,
      const char *yCenter,
      const char *xFilter,
      const char *yFilter,
      const char *transformOrder,
      const char *invertTransform,
      const char *motionBlur,
      const char *shutterTiming,
      const char *shutterOffset,
      const char *useReference,
      const char *referenceFrame)
      {
         TmpTest * fx = new TmpTest;
         fx->setParent(NRiNode::getRoot());
         fx->in->connect(img);
         fx->pXPan()->set(xPan);
         fx->pYPan()->set(yPan);
         fx->pAngle()->set(angle);
         fx->pAspect()->set(aspectRatio);
         fx->pXScale()->set(xScale);
         fx->pYScale()->set(yScale);
         fx->pXShear()->set(xShear);
         fx->pYShear()->set(yShear);
         fx->pXCenter()->set(xCenter);
         fx->pYCenter()->set(yCenter);
         fx->pXFilter()->set(xFilter);
         fx->pYFilter()->set(yFilter);
         fx->pTOrder()->set(transformOrder);
         fx->pTReverse()->set(invertTransform);
         fx->pMotionBlur()->set(motionBlur);
         fx->pShutterTiming()->set(shutterTiming);
         fx->pShutterOffset()->set(shutterOffset);
         fx->pUseReference()->set(useReference);
         fx->pReferenceFrame()->set(referenceFrame);
         return fx->out;
    }
}

And register it to the shake compiler (Part of the string to be passed to the cmplr).
  "extern image TmpTest_(image,\n"
  " float xPan = 0 , float yPan = 0,\n"
  " float angle = 0, float aspectRatio = GetDefaultAspect(),\n"
  " float xScale = 1, float yScale = xScale,\n"
  " float xShear = 0, float yShear = 0,\n"
  " float xCenter = width/2, float yCenter = height/2,\n"
  " const char *xFilter = \"default\", const char *yFilter = xFilter,\n"
  " const char *transformOrder = \"trsx\",\n"
  " int invertTransform = 0,\n"
  " float motionBlur = 0, float shutterTiming = 0.5, float shutterOffset = 0,\n"
  " int useReference = 0, float referenceFrame = time\n"
  " );\n"

Shake uses C++ in a straightforward way which brings this flexibility.
I'm quite impressed. Cool, cool

No comments: