#include <RixPattern.h>
#include <RixShadingUtils.h>
#include <RixShading.h>
#include <cstring>
class CutrSideMask : public RixPattern {
public:
CutrSideMask();
virtual ~CutrSideMask() { }
// The next four methods override those of the base class.
virtual int Init(RixContext &, char const *pluginpath);
virtual RixSCParamInfo const *GetParamTable();
virtual void Finalize(RixContext &) { }
virtual int ComputeOutputParams(RixShadingContext const *sctx,
RtInt *noutputs,
OutputSpec **outputs,
RtConstPointer instanceData,
RixSCParamInfo const *ignored);
private:
RixMessages *m_msg;
RtColorRGB m_input_outsideRGB;
RtColorRGB m_input_insideRGB;
};
// Constructor - does nothing except initializes our member variables
// in the same sequence in which they are declared.
CutrSideMask::CutrSideMask():
m_msg(NULL),
m_input_outsideRGB(1,0.4,0.4),
m_input_insideRGB(0.5,1,0.5)
{ }
int CutrSideMask::Init(RixContext &ctx, char const *pluginpath) {
m_msg = (RixMessages*)ctx.GetRixInterface(k_RixMessages);
RixRenderState *rstate = (RixRenderState*)ctx.GetRixInterface(k_RixRenderState);
RixRenderState::Type optType;
RtInt optNumValues, err;
RtColorRGB bkcolor;
err = rstate->GetOption("imager:background:color", &bkcolor, sizeof(bkcolor),
&optType, &optNumValues);
if(err == 0 && optType == RixRenderState::k_Color) {
m_msg->Info("background:color: %f %f %f", bkcolor.r,bkcolor.g,bkcolor.b);
}
return (!m_msg) ? 1 : 0;
}
RixSCParamInfo const *CutrSideMask::GetParamTable() {
static RixSCParamInfo s_ptable[] = {
// Output
RixSCParamInfo("resultRGB", k_RixSCColor, k_RixSCOutput),
// Input
RixSCParamInfo("input_outsideRGB", k_RixSCColor),
RixSCParamInfo("input_insideRGB", k_RixSCColor),
RixSCParamInfo() // end of table
};
return &s_ptable[0];
}
enum paramIndex {
k_resultRGB = 0,
k_input_outsideRGB,
k_input_insideRGB
};
int CutrSideMask::ComputeOutputParams(RixShadingContext const *sctx,
RtInt *noutputs,
OutputSpec **outputs,
RtConstPointer instanceData,
RixSCParamInfo const *ignored) {
bool varying = true;
// Declare a pointer for each input.
RtColorRGB const *input_outsideRGB;
RtColorRGB const *input_insideRGB;
sctx->EvalParam(k_input_outsideRGB, -1, &input_outsideRGB, &m_input_outsideRGB, varying);
sctx->EvalParam(k_input_insideRGB, -1, &input_insideRGB, &m_input_insideRGB, varying);
// Allocate memory for the OutputSpec data structure.
RixShadingContext::Allocator pool(sctx);
OutputSpec *outSpec = pool.AllocForPattern<OutputSpec>(1);
*outputs = outSpec;
// Allocate memory for each output.
RtColorRGB *resultRGB = pool.AllocForPattern<RtColorRGB>(sctx->numPts);
// Prepare the OutputSpec to the output(s).
*noutputs = 1;
outSpec[0].paramId = k_resultRGB;
outSpec[0].detail = k_RixSCVarying;
outSpec[0].value = resultRGB;
// Access the primitive variables that will be needed for the
// calculation of the output values.
RtNormal3 const *Ngn; // normalized geometric normal
RtVector3 const *Vn; // normalized view vector
sctx->GetBuiltinVar(RixShadingContext::k_Ngn, &Ngn);
sctx->GetBuiltinVar(RixShadingContext::k_Vn, &Vn);
// Assign values to each point.
for(int i = 0; i < sctx->numPts; i++) {
// Calculate the dot product and use it to determine if the
// point being shaded is facing the camera.
float NdotV = Dot(Ngn[i], Vn[i]);
if (NdotV > 0.f) {
resultRGB[i] = input_outsideRGB[i];
}
else
{
resultRGB[i] = input_insideRGB[i];
}
}
return 0;
}
RIX_PATTERNCREATE {
return new CutrSideMask();
}
RIX_PATTERNDESTROY {
delete ((CutrSideMask*)pattern);
}