#include <UT/UT_DSOVersion.h>
#include <UT/UT_Color.h>
#include <GEO/GEO_PrimPart.h>
#include <GEO/GEO_Point.h>
#include <GU/GU_Detail.h>
#include <PRM/PRM_Include.h>
#include <OP/OP_Operator.h>
#include <OP/OP_OperatorTable.h>
#include "POP_SpotLight.h"
using namespace HDK_Sample;
static PRM_Name names[] =
{
PRM_Name("center", "Center"),
PRM_Name(0)
};
PRM_Template
POP_SpotLight::myTemplateList[] =
{
PRM_Template(PRM_FLT_J, 1, &POPactivateName, PRMoneDefaults, 0,
&PRMunitRange),
PRM_Template(PRM_STRING, 1, &POPsourceName, 0,
&POP_Node::pointGroupMenu),
PRM_Template(PRM_XYZ_J, 3, &names[0]),
PRM_Template()
};
OP_TemplatePair
POP_SpotLight::myTemplatePair (myTemplateList, &POP_LocalVar::myTemplatePair);
OP_VariablePair
POP_SpotLight::myVariablePair (0, &POP_LocalVar::myVariablePair);
void
newPopOperator (OP_OperatorTable* table)
{
table->addOperator(
new OP_Operator("hdk_spotlight",
"SpotLight",
POP_SpotLight::myConstructor,
&POP_SpotLight::myTemplatePair,
1,
1,
&POP_SpotLight::myVariablePair));
}
OP_Node*
POP_SpotLight::myConstructor (OP_Network* net, const char* name,
OP_Operator* entry)
{
return new POP_SpotLight(net, name, entry);
}
int *POP_SpotLight::myIndirect = 0;
POP_SpotLight::POP_SpotLight (OP_Network* net, const char* name,
OP_Operator* entry)
:POP_LocalVar (net, name, entry)
{
if (!myIndirect)
myIndirect = allocIndirect(sizeof(myTemplateList)/sizeof(PRM_Template));
}
POP_SpotLight::~POP_SpotLight (void)
{
}
OP_ERROR
POP_SpotLight::cookPop (OP_Context& context)
{
POP_ContextData* data = (POP_ContextData*) context.getData();
float t = context.getTime();
int thread = context.getThread();
GEO_PrimParticle* part;
GEO_ParticleVertex* pvtx;
POP_FParam centerx;
POP_FParam centery;
POP_FParam centerz;
UT_String sourceName;
const GB_PointGroup *sourceGroup = NULL;
if (lockInputs(context) >= UT_ERROR_ABORT)
return(error());
setupDynamicVars(data);
if (buildParticleList(context) >= UT_ERROR_ABORT)
goto done;
if (data->isGuideOnly())
goto done;
if (!checkActivation(data, (POP_FParam) &POP_SpotLight::ACTIVATE))
goto done;
SOURCE(sourceName);
if (sourceName.isstring())
{
sourceGroup = parsePointGroups((const char*) sourceName,
data->getDetail());
if (!sourceGroup)
{
addError(POP_BAD_GROUP, sourceName);
goto done;
}
}
setupVars(data, sourceGroup);
POP_FCACHE(centerx, CENTERX, getCenterX, myCenterX, POP_SpotLight);
POP_FCACHE(centery, CENTERY, getCenterY, myCenterY, POP_SpotLight);
POP_FCACHE(centerz, CENTERZ, getCenterZ, myCenterZ, POP_SpotLight);
if (error() >= UT_ERROR_ABORT)
goto done;
myCurrIter = 0;
if (sourceGroup)
{
FOR_ALL_GROUP_POINTS(data->getDetail(), sourceGroup, myCurrPt)
{
changePoint(myCurrPt, data, t, centerx, centery, centerz);
myCurrIter++;
}
}
else
{
for (part = myParticleList.iterateInit() ;
part ; part = myParticleList.iterateNext())
{
for (pvtx = part->iterateInit() ; pvtx ; pvtx = pvtx->next)
{
myCurrPt = pvtx->getPt();
changePoint(myCurrPt, data, t, centerx, centery, centerz);
myCurrIter++;
}
}
}
done:
cleanupDynamicVars();
unlockInputs();
myCurrPt = NULL;
return error();
}
void
POP_SpotLight::changePoint (GEO_Point* ppt, POP_ContextData* data, float t,
POP_FParam centerx, POP_FParam centery,
POP_FParam centerz)
{
UT_Vector3 center;
UT_Vector3 color;
UT_Vector3 d;
UT_Vector3 p;
UT_Color HSVtoRGB(UT_HSV);
UT_Color RGBtoHSV(UT_RGB);
float r, g, b;
float h, s, v;
float d2;
center.assign(POP_PEVAL(centerx), POP_PEVAL(centery), POP_PEVAL(centerz));
p = ppt->getPos();
d = p - center;
color = ppt->getValue<UT_Vector3>(data->getDiffuseOffset());
RGBtoHSV.setValue(color.x(), color.y(), color.z());
RGBtoHSV.getHSV(&h, &s, &v);
d2 = d.length2();
v = UTequalZero(d2) ? 1.0f : 1.0f / d.length2();
if (v > 1.0f)
v = 1.0f;
HSVtoRGB.setValue(h, s, v);
HSVtoRGB.getRGB(&r, &g, &b);
color.assign(r, g, b);
ppt->setValue<UT_Vector3>(data->getDiffuseOffset(), color);
}
void
POP_SpotLight::addAttrib (void* userdata)
{
POP_ContextData* data = (POP_ContextData*) userdata;
addDiffuseAttrib(data);
}