cxVec2f cxSplinePointAt(cxAny pav,cxInt idx) { CX_ASSERT_THIS(pav, cxSpline); idx = CX_MIN(cxAnyArrayLength(this->points) - 1, CX_MAX(idx, 0)); return *cxAnyArrayAt(this->points, idx, cxVec2f); }
#include <core/cxEngine.h> #include <core/cxNumber.h> #include <core/cxActionRoot.h> #include "cxSpline.h" static void cxSplineInit(cxAny pav) { cxSpline this = pav; CX_ASSERT(this->super.view != NULL, "view not set"); this->delta = 1.0f/((cxFloat)cxArrayLength(this->points) - 1.0f); } static cxVec2f cxSplinePointAt(cxSpline this,cxInt idx) { idx = CX_MIN(cxArrayLength(this->points) - 1, CX_MAX(idx, 0)); cxNumber num = cxArrayAtIndex(this->points, idx); CX_ASSERT(num != NULL, "num error"); return cxNumberToVec2f(num); } static void cxSplineStep(cxAny pav,cxFloat dt,cxFloat time) { cxInt index = 0; cxSpline this = pav; cxFloat lt = 0; if (time >= 1.0f){ index = cxArrayLength(this->points) - 1; lt = 1.0f; }else{ index = time / this->delta;
cxBool cxActionUpdate(cxAny pav,cxFloat dt) { cxAction this = pav; cxBool isExit = false; dt = dt * this->speed; if(this->isPause || this->isExit){ goto finished; } //action delay this->delayElapsed += dt; if(this->delay > 0 && this->delayElapsed < this->delay){ goto finished; } //init event if(!this->isFirst){ this->isFirst = true; CX_ASSERT(this->view != NULL, "action viewptr null"); this->prevTime = 0; this->delayElapsed = 0; this->durationElapsed = this->durationInit; CX_METHOD_FIRE(NULL, this->Init, this); CX_EVENT_FIRE(this, onStart); } //for active if(!this->isActive){ this->isActive = true; CX_METHOD_FIRE(NULL, this->Active, this); } this->durationElapsed += dt; cxFloat value = this->durationElapsed/CX_MAX(this->duration, FLT_EPSILON); cxFloat time = kmClamp(value, 0.0f, 1.0f); //split index event fire cxInt index = -1; if(time >= 1.0f){ index = this->split - 1; }else if(this->splitDelta > 0){ index = time / this->splitDelta; } if(this->index != index && index >= 0){ this->index = index; CX_EVENT_FIRE(this,onSplit); } //wait exit if(this->duration < 0){ CX_METHOD_FIRE(NULL, this->Step,this,dt,time); CX_EVENT_FIRE(this, onStep); }else if(this->duration == 0){ isExit = CX_METHOD_FIRE(true, this->Exit, this); }else if(this->durationElapsed < this->duration){ time = CX_METHOD_FIRE(time, this->Curve, this, time); this->delta = time - this->prevTime; this->prevTime = time; CX_METHOD_FIRE(NULL, this->Step,this,dt,time); CX_EVENT_FIRE(this, onStep); }else{ time = CX_METHOD_FIRE(1.0f, this->Curve,this,1.0f); this->delta = time - this->prevTime; this->prevTime = 0; this->durationElapsed = 0.0f; this->delayElapsed = 0.0f; CX_METHOD_FIRE(NULL, this->Step,this,dt,1.0f); CX_EVENT_FIRE(this, onStep); //check exit isExit = CX_METHOD_FIRE(true, this->Exit,this); this->isActive = false; } //check action exit finished: //force exit or auto exit if(this->isExit || isExit){ CX_EVENT_FIRE(this, onStop); CX_METHOD_FIRE(NULL, this->Over,this); } return (this->isExit || isExit); }