/*----------------------------------------------------------------------------- Name : bsStartup Description : Start the spline module Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void bsStartup(void) { #if BS_TEST FILE *fp; splinecurve *curve; static real32 points[] = {0.0f, 1.0f, -1.0f, -0.5f, 0.0f, -2.0f, -1.2f}; static real32 times[] = {0.0f, 0.5f, 2.0f, 3.0f, 4.0f, 5.5f, 7.0f, 7.5f, 9.0f}; static tcb tcbs[] = {{0.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}; real32 time, value = 0.0f; sdword point; fp = fopen("b-spline.chart", "wt"); if (fp != NULL) { curve = bsCurveStart(7, points, times, tcbs, TRUE); for (time = 0.0f; value != REALlyBig; time += 0.02f) { point = curve->currentPoint; value = bsCurveUpdate(curve, 0.02f); fprintf(fp, "\nTime = %2.2f, value = %2.8f", time, value); if (point != curve->currentPoint) { fprintf(fp, ", point = %2.2f", curve->points[curve->currentPoint]); } } bsCurveDelete(curve); fclose(fp); } #endif }
/*----------------------------------------------------------------------------- Name : madAnimBindingUpdate Description : Mesh binding function for scripted mesh animations. Inputs : flags - ignored startMatrix - initial matrix data - pointer to ship ID - index of object path in the animation for this ship Outputs : matrixDest - animated matrix Return : TRUE = matrix updated ----------------------------------------------------------------------------*/ bool madAnimBindingUpdate(udword flags, hmatrix *startMatrix, hmatrix *matrixDest, void *data, sdword ID) { real32 timeElapsed; Ship *ship = (Ship *)data; sdword j, startPoint; madheader *header; madanim *anim = ship->madBindings; madobjpath *path; madanimation *animation; splinecurve *curve; vector hpb, xyz; matrix _3x3Matrix; hmatrix rotMatrix; #if MR_TEST_HPB if (mrTestHPBMode && ID == madTestHPBIndex) { hpb.x = mrHeading; hpb.y = mrPitch; hpb.z = mrBank; curve = &anim->curves[ID * 6]; //pointer to spline curves for this object xyz.x = curve[0].points[0]; xyz.y = curve[1].points[0]; xyz.z = curve[2].points[0]; nisObjectEulerToMatrix(&_3x3Matrix, &hpb); //make a rotation matrix hmatMakeHMatFromMatAndVec(&rotMatrix, &_3x3Matrix, &xyz);//make a hmatrix *matrixDest = rotMatrix; return(TRUE); } #endif dbgAssertOrIgnore(anim != NULL); curve = &anim->curves[ID * 6]; //pointer to spline curves for this object if (curve->currentPoint == BS_NoPoint) { //if this object not animating *matrixDest = *startMatrix; return(FALSE); //don't bother updating animation } timeElapsed = anim->timeElapsed; header = anim->header; //pointer to animation data path = &header->objPath[ID]; //pointer to motion path animation = &header->anim[anim->nCurrentAnim]; //pointer to animation header if (curve[0].timeElapsed + timeElapsed > animation->endTime) { //if we'll go past the end if (bitTest(animation->flags, MAF_Loop)) { //if this is a looping animation timeElapsed = (real32)fmod((double)(curve[0].timeElapsed + timeElapsed - animation->endTime), (double)(animation->endTime - animation->startTime)); for (startPoint = 0; startPoint < curve[0].nPoints; startPoint++) { //find a point to restart at if (curve[0].times[startPoint] == anim->startTime) { goto foundTime; } } #if MAD_ERROR_CHECKING dbgFatalf(DBG_Loc, "madAnimationStart: Object #%d ('%s') has no keyframe at frame %.0f", anim->nCurrentAnim, header->objPath[anim->nCurrentAnim].name, anim->startTime / header->framesPerSecond); #endif foundTime: for (j = 0; j < 6; j++) { //reset all the motion curves curve[j].timeElapsed = animation->startTime; curve[j].currentPoint = startPoint; } } else { //else it's a non-looping animation; clamp at the end timeElapsed = animation->endTime - curve[0].timeElapsed;//clamp to end } } //now update the motion curves xyz.x = bsCurveUpdate(&curve[1], timeElapsed); xyz.y = bsCurveUpdate(&curve[2], timeElapsed); xyz.z = -bsCurveUpdate(&curve[0], timeElapsed); hpb.x = bsCurveUpdate(&curve[3], timeElapsed); hpb.y = bsCurveUpdate(&curve[4], timeElapsed); hpb.z = bsCurveUpdate(&curve[5], timeElapsed); dbgAssertOrIgnore(xyz.x != REALlyBig && xyz.y != REALlyBig && xyz.z != REALlyBig); dbgAssertOrIgnore(hpb.x != REALlyBig && hpb.y != REALlyBig && hpb.z != REALlyBig); nisObjectEulerToMatrix(&_3x3Matrix, &hpb); //make a rotation matrix hmatMakeHMatFromMatAndVec(&rotMatrix, &_3x3Matrix, &xyz); //make a hmatrix *matrixDest = rotMatrix; //remember when this curve was last updated return(TRUE); }