#define _MESSIAH_FULL_API #include <messiah_main.h> // Access Function FX_ACCESSFUNC(LagPointsAccess); // Effect's state data structure typedef struct { FXdouble lag; FXtool weight_obj; FXint scan; //work variables - used to increase speed of pointscan FXdouble frame; FXvecd piv; }LagPointState;
#define _MAINPLUGIN_FILE #include "LagPoints.h" _pluginEntry // FXint messiahEntry(FXchar pname[256], FXvoid *api_func, FXint api, FXint program, const FXchar *rev) { // Get all API components and do initial plugin setup _MESSIAH_PLUGIN_ALL("LagPoints"); // Describe the effect in English fxModuleDescription("Points lag behind the motion of the object based on their distance from the pivot", FX_NOFLAG); // Request AN messages fxModuleAccess(ACCESS_OBJECT, O_CREATE|O_DESTROY|O_LOAD|O_SAVE, FX_NOFLAG); fxModuleAccess(ACCESS_SYSTEM, S_MODULE_INIT, FX_NOFLAG); fxModuleAccess(ACCESS_INTERFACE, IN_CREATE, FX_NOFLAG); fxModuleAccess(ACCESS_PROCESS, P_POST_POINT_DISPLACE, FX_NOFLAG); // Register the effect fxModuleRegister( FX_MODTYPE_EFFECT, "LagPoints", &LagPointsAccess, FX_NOFLAG); return FX_PLUGIN_OK; } _pluginExit // FXvoid messiahExit(FXvoid) { }
case O_CREATE: { if( !(state = (LagPointState *)calloc(1, sizeof(LagPointState))) ) return ENTRY_CONTINUE; // User defined state initialization function LagPointDataInit(state); fxObjectSetTypeData( effect, state, FX_NOFLAG ); fxChannelSetup( effect, "lag", FX_CHAN_0, FX_CHANTYPE_VALUE, state->lag, 0.0, 0.0, FX_NOFLAG); fxChannelDataLink( effect, FX_CHAN_0, FX_ARG_DOUBLE, &state->lag, FX_NOFLAG); }// O_CREATE break;
case O_SAVE: { FX_Format *f; if( state = fxObjectGetTypeData( effect, FX_NOFLAG ) ) { // Create new format called "LagData" f = fxFormatNew(ai, "LagData", 0); // Store state->weight in this format and call it "weight" fxArgSaveObj(f, "weight", state->weight_obj); // Store state->scan also, calling it "scan" fxArgSaveInt(f, "scan", state->scan); } }//O_SAVE break;
case O_LOAD: { FX_Format *f; if( state = fxObjectGetTypeData(effect, FX_NOFLAG) ) { // initialize data prior to loading LagPointDataInit(state); // Retrieve our format from ai f = fxFormatGet( ai, "LagData" ); // Retrieve state->weight_obj from the format by name (weight) fxArgLoadObj(f, "weight", &state->weight_obj); // Retrieve state->scan from the format by name (scan) fxArgLoadInt(f, "scan", &state->scan); } }//O_LOAD break;
case ACCESS_INTERFACE: switch(entry) { case IN_CREATE: { FXcontrol block, c1, c2, c3; block = fxCC_Block("LagPoint", NULL, ACC_NONE, FX_NOFLAG); c1 = fxCC_ChannelFloat("Lag", NULL, ACC_NONE, FX_CHAN_0, 0); fxConSetPos(c1, 75, 4); c2 = fxCC_WeightPopup("Weight", &Lag_WeightPopup, ACC_VALUE|ACC_UPDATE, 175); c3 = fxCC_Bool("Use PointScan", &LagScan_Bool, ACC_VALUE|ACC_UPDATE); fxInterfaceBlockSet(FX_MODE_ANIMATE, NULL, NULL, block); fxInterfaceBlockSet(FX_MODE_ANIMATE, FX_MODE_ANIMATE, FX_MBLOCK_SPLINE, FX_NULLID); fxInterfaceBlockSet(FX_MODE_SETUP, NULL, NULL, block); }//IN_CREATE break; }//ACCESS_INTERFACE break;
static FX_CONCALLBACK(Lag_WeightPopup) // FXint control_func(FXcontrol ctl, FXentity ctl_data, FX_Arg *arg, FXint64 entry ) { FXeffect effect = (FXeffect)ctl_data; LagPointState *state = fxObjectGetTypeData(effect, FX_NOFLAG); if (!state) return ENTRY_CONTINUE; switch(entry) { case ACC_VALUE: fxConGetObj(ctl, &state->weight_obj); break; case ACC_UPDATE: fxConSetObj(ctl, state->weight_obj); break; default: break; } return ENTRY_CONTINUE; }
FXeffect
and call it effect. We'll use the effect instance to get the state data attached to it by calling fxObjectGetTypeData(). Once we've got the state data we will use the fxConGetObj() function to get the value from the control and store it in the state data when responding to the ACC_UPDATE message (which get sent when the control's value had been changed by the user). We will also use the fxConSetObj() function to set the control's value from our state data in response to the ACC_UPDATE CN (which gets sent when the control needs to redraw). int's
instead of objects: static FX_CONCALLBACK(LagScan_Bool) // FXint control_func(FXcontrol ctl, FXentity ctl_data, FX_Arg *arg, FXint64 entry ) { FXeffect effect = (FXeffect)ctl_data; LagPointState *state = fxObjectGetTypeData(effect, FX_NOFLAG); if (!state) return ENTRY_CONTINUE; switch(entry) { case ACC_VALUE: fxConGetInt(ctl, &state->scan); break; case ACC_UPDATE: fxConSetInt(ctl, state->scan); break; default: break; } return ENTRY_CONTINUE; }
static FX_EFFECTSCAN(EffectScan, LagPointState, state) { // ... fxChannelsGet(target, FX_PIVOT, state->frame, state->piv, 0); if (state->scan) { fxDisplaceScan(target, state->weight_obj, FX_WEIGHT_SETUP, &DisplaceScan, state, FX_NOFLAG); } else { // manually displace points // ... } return FX_TRUE; }
static FX_EFFECTSCAN(EffectScan, LagPointState, state) { FXvecd pos, v, pnt; FXdouble t, d; FXint num_points=0, i; FXmatrix m; fxChannelsGet(target, FX_PIVOT, state->frame, state->piv, 0); if (state->scan) { fxDisplaceScan(target, state->weight_obj, FX_WEIGHT_SETUP, &DisplaceScan, state, 0); } else { fxMeshNumPoints(target, &num_points, FX_NOFLAG); fxDisplaceBegin(target, FX_NOFLAG); for (i=0;i<num_points;i++) { fxMeshPoint(target, i, pnt, FX_NOFLAG); FX_V3SUB(v, pnt, state->piv); d = FX_V3LEN(v); t = state->frame - (d*state->lag); fxMatrixGet(target, FX_MATRIX_WORLD, t, m, 1); _fxMatrixXform(pos, v, m, 1); fxDisplacePoint(target, i, pos[0], pos[1], pos[2]); } fxDisplaceEnd(target, FX_NOFLAG); } return FX_TRUE; }
© 2003 pmG WorldWide,
LLC.
|
Last
Updated on Thu Jul 10 04:49:37 2003
|