#include <RixPattern.h>
#include <RixShadingUtils.h>
#include <RixShading.h>
#include <cstring>
class CutrSparky : public RixPattern {
public:
CutrSparky();
virtual ~CutrSparky() { }
virtual int Init(RixContext &, char const *pluginpath);
virtual RixSCParamInfo const *GetParamTable();
virtual void Finalize(RixContext &) { }
virtual int ComputeOutputParams(RixShadingContext const *ctx,
RtInt *noutputs,
OutputSpec **outputs,
RtConstPointer instanceData,
RixSCParamInfo const *ignored);
private:
RixMessages *m_msg;
RtFloat m_age;
RtFloat m_width;
RtFloat m_frontblur;
RtFloat m_rearblur;
RtColorRGB m_start;
RtColorRGB m_end;
};
CutrSparky::CutrSparky():
m_msg(NULL),
m_age(0),
m_width(0),
m_frontblur(0),
m_rearblur(0),
m_start(1,1,1),
m_end(1,1,1)
{ }
int CutrSparky::Init(RixContext &ctx, char const *pluginpath) {
m_msg = (RixMessages*)ctx.GetRixInterface(k_RixMessages);
return (!m_msg) ? 1 : 0;
}
RixSCParamInfo const *CutrSparky::GetParamTable() {
static RixSCParamInfo s_ptable[] = {
// Output
RixSCParamInfo("resultRGB", k_RixSCColor, k_RixSCOutput),
RixSCParamInfo("resultF", k_RixSCFloat, k_RixSCOutput),
// Input
RixSCParamInfo("age", k_RixSCFloat),
RixSCParamInfo("width", k_RixSCFloat),
RixSCParamInfo("frontblur", k_RixSCFloat),
RixSCParamInfo("rearblur", k_RixSCFloat),
RixSCParamInfo("start", k_RixSCColor),
RixSCParamInfo("end", k_RixSCColor),
RixSCParamInfo() // end of table
};
return &s_ptable[0];
}
enum paramIndex {
k_resultRGB = 0,
k_resultF,
k_age,
k_width,
k_frontblur,
k_rearblur,
k_start,
k_end
};
int CutrSparky::ComputeOutputParams(RixShadingContext const *ctx,
RtInt *noutputs,
OutputSpec **outputs,
RtConstPointer instanceData,
RixSCParamInfo const *ignored) {
bool varying = true;
// Declare a pointer for each input.
RtFloat const *age;
RtFloat const *width;
RtFloat const *frontblur;
RtFloat const *rearblur;
RtColorRGB const *start;
RtColorRGB const *end;
ctx->EvalParam(k_age, -1, &age, &m_age, varying);
ctx->EvalParam(k_width, -1, &width, &m_width, varying);
ctx->EvalParam(k_frontblur, -1, &frontblur, &m_frontblur, varying);
ctx->EvalParam(k_rearblur, -1, &rearblur, &m_rearblur, varying);
ctx->EvalParam(k_start, -1, &start, &m_start, varying);
ctx->EvalParam(k_end, -1, &end, &m_end, varying);
// Allocate memory for the OutputSpec data structure.
RixShadingContext::Allocator pool(ctx);
OutputSpec *outSpec = pool.AllocForPattern<OutputSpec>(2);
*outputs = outSpec;
// Allocate memory for each output.
RtColorRGB *resultRGB = pool.AllocForPattern<RtColorRGB>(ctx->numPts);
RtFloat *resultF = pool.AllocForPattern<RtFloat>(ctx->numPts);
*noutputs = 2;
outSpec[0].paramId = k_resultRGB;
outSpec[0].detail = k_RixSCVarying;
outSpec[0].value = resultRGB;
outSpec[1].paramId = k_resultF;
outSpec[1].detail = k_RixSCVarying;
outSpec[1].value = resultF;
// Surface parameter
RtFloat const *V;
ctx->GetBuiltinVar(RixShadingContext::k_v, &V);
// Assign values to each point.
for(int i = 0; i < ctx->numPts; i++) {
resultF[i] = RixSmoothStep(age[i] - rearblur[i], width[i] + age[i], V[i]) *
(1 - RixSmoothStep(age[i], width[i] + age[i] + frontblur[i], V[i]));
//m_msg->Info("%f\n", resultF[i]);
resultRGB[i] = RixMix(start[i], end[i], resultF[i]);
}
return 0;
}
RIX_PATTERNCREATE {
return new CutrSparky();
}
RIX_PATTERNDESTROY {
delete ((CutrSparky*)pattern);
}