class jbd_hermite:public MPxNode{ | |
public: | |
<SNIP> | |
//- Attrs | |
static MObject inPuts; | |
static MObject inMatrix; | |
static MObject inTangentWeight; | |
static MObject outputCount; | |
static MObject outPuts; | |
static MObject outMatrix; | |
static MObject outScale; | |
static MObject outTranslate; | |
static MObject outRotate; | |
static MObject outRotateX; | |
static MObject outRotateY; | |
static MObject outRotateZ; | |
}; |
////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// HERMITE STUFF | |
// CUBIC HERMITE BASIS FUNCTIONS | |
// h1 | |
inline float cubicH1(float t){return ( 2.0f*pow(t, 3) - 3.0f*pow(t, 2) ) + 1.0f;} | |
// h2 | |
inline float cubicH2(float t){return ( -2.0f*pow(t, 3) + 3.0f * pow(t, 2) );} | |
// h3 | |
inline float cubicH3(float t){return (pow(t, 3) - (2.0f*pow(t, 2) )) + t;} | |
// h4 | |
inline float cubicH4(float t){return pow(t, 3) - pow(t, 2);} |
MFloatVector getUnitHermiteVector(float t, MFloatMatrix p1, MFloatMatrix p2, MFloatVector p1t, MFloatVector p2t){ | |
float x = (cubicH1(t)*p1(3,0)) + (cubicH3(t)*p1t.x) + (cubicH2(t)*p2(3,0)) + (cubicH4(t)*p2t.x); | |
float y = (cubicH1(t)*p1(3,1)) + (cubicH3(t)*p1t.y) + (cubicH2(t)*p2(3,1)) + (cubicH4(t)*p2t.y); | |
float z = (cubicH1(t)*p1(3,2)) + (cubicH3(t)*p1t.z) + (cubicH2(t)*p2(3,2)) + (cubicH4(t)*p2t.z); | |
MFloatVector result(x, y, z); | |
return result; | |
} |
MStatus jbd_hermite::compute( const MPlug& plug, MDataBlock& dataBlock ){ | |
struct Knot{ | |
MFloatMatrix mtx; | |
MFloatMatrix localMtx; | |
MFloatVector XTangent; | |
MFloatVector YTangent; | |
MFloatVector ZTangent; | |
MFloatVector hermitePoint; | |
}point1, point2; |
MStatus status = MS::kUnknownParameter; | |
if (plug == outPuts || plug.parent() == outPuts){ | |
MArrayDataHandle inputsArrayHndl = dataBlock.inputArrayValue(inPuts); | |
int cvCount = inputsArrayHndl.elementCount(); | |
if (cvCount < 2){ | |
status = MS::kSuccess; | |
} |
else{ | |
MDataHandle inOuputCount = dataBlock.inputValue(outputCount); | |
int outCount = inOuputCount.asInt(); | |
MArrayDataHandle outputArray = dataBlock.outputArrayValue(outPuts); | |
MArrayDataBuilder builder = outputArray.builder(); | |
inputsArrayHndl.jumpToElement(0); | |
///////////////////////////////////////////////////////////// | |
// POINT ONE | |
point1.mtx = inputsArrayHndl.inputValue().child(inMatrix).asFloatMatrix(); | |
point1.XTangent.x = point1.localMtx[0][0]; | |
point1.XTangent.y = point1.localMtx[0][1]; | |
point1.XTangent.z = point1.localMtx[0][2]; | |
point1.XTangent *= inputsArrayHndl.inputValue().child(inTangentWeight).asFloat(); | |
///////////////////////////////////////////////////////////// | |
// POINT TWO | |
inputsArrayHndl.jumpToArrayElement(1); | |
point2.mtx = inputsArrayHndl.inputValue().child(inMatrix).asFloatMatrix(); | |
point2.XTangent.x = point2.localMtx[0][0]; | |
point2.XTangent.y = point2.localMtx[0][1]; | |
point2.XTangent.z = point2.localMtx[0][2]; | |
point2.XTangent *= inputsArrayHndl.inputValue().child(inTangentWeight).asFloat(); |
///////////////////////////////////////////////////////////// | |
// CALC HERMITE NOW | |
int outPort = 0; | |
float increment = 1.0f / float(outCount-1); | |
float x = 0.0f; | |
if(outCount >= 2){ | |
for(unsigned int i=0; i<=outCount-1; i++){ | |
///////////////////////////////////////////////////////////// | |
// TRANSLATION | |
MDataHandle out = builder.addElement(outPort); | |
MDataHandle oTranslateH = out.child(outTranslate); | |
MDataHandle oRotateH = out.child(outRotate); | |
MDataHandle oScaleH = out.child(outScale); | |
MFloatVector hermiteVector = getUnitHermiteVector(x, point1.localMtx, point2.localMtx, point1.XTangent, point2.XTangent); | |
oTranslateH.set(hermiteVector); | |
oTranslateH.setClean(); | |
outPort += 1; | |
x += increment; | |
} | |
} | |
status = MS::kSuccess; | |
} | |
} | |
return status; | |
} |
for(unsigned int i=0;