📄 atifly.cpp
字号:
if (CompileOrientations() == FALSE)
return FALSE;
return TRUE;
}
//=============================================================================
float32 AtiDistance (AtiVertex4 *v1, AtiVertex4 *v2)
{
AtiVertex4 tmpv;
tmpv.x = v1->x - v2->x;
tmpv.y = v1->y - v2->y;
tmpv.z = v1->z - v2->z;
return (float32)(sqrt((tmpv.x*tmpv.x) + (tmpv.y*tmpv.y) + (tmpv.z*tmpv.z)));
}
//=============================================================================
void AtiVertex4Lerp (AtiVertex4 *ret, AtiVertex4 *v1, AtiVertex4 *v2, float32 lerpValue)
{
ret->x = v1->x + lerpValue*(v2->x - v1->x);
ret->y = v1->y + lerpValue*(v2->y - v1->y);
ret->z = v1->z + lerpValue*(v2->z - v1->z);
}
//=============================================================================
void AtiVertex4Copy (AtiVertex4 *v1, AtiVertex4 *v2)
{
v1->x = v2->x;
v1->y = v2->y;
v1->z = v2->z;
}
//=============================================================================
bool8 AtiFlyPath::CompilePositions (void)
{
int32 i;
int32 j;
int32 k;
float32 tmpf;
float32 tmpf2;
int32 numPoints = 0;
AtiVertex4 *pointArray = NULL;
AtiVertex4 *tmpD2 = NULL;
AtiVertex4 *tmpIntD2 = NULL;
/***********************************/
/* Make sure we have enough points */
/***********************************/
if (mNumFlyPoints < 5)
return FALSE;
/********************************************/
/* Allocate new memory for spline intervals */
/********************************************/
AtiFreeArray(mLocationIntervals);
AtiMallocArray(mLocationIntervals, mNumFlyPoints, AtiSplineInterval);
/*****************************************/
/* Allocate memory for temporary storage */
/*****************************************/
AtiMallocArray(pointArray, mNumFlyPoints+9, AtiVertex4);
AtiMallocArray(tmpD2, mNumFlyPoints+9, AtiVertex4);
AtiMallocArray(tmpIntD2, mNumFlyPoints+9, AtiVertex4);
/***************************************************************************/
/* Build each array of vertices padding by 1 point on each end and process */
/***************************************************************************/
mPathTime = 0.0;
mNumSplineIntervals = 0;
for (i=0; i<mNumFlyPoints; i++)
{
/*******************/
/* Skip cut points */
/*******************/
if (mLocation[i].w != 0.0)
continue;
/****************/
/* Init counter */
/****************/
numPoints = 0;
/**************************/
/* Pad spline by 4 points */
/**************************/
if ((i == 0) && (mPreviousPath->mNumFlyPoints >= 5) && (mPreviousPath->mLocation[mPreviousPath->mNumFlyPoints-1].w == 0.0))
{
AtiVertex4Copy (&(pointArray[numPoints+3]), &(mPreviousPath->mLocation[mPreviousPath->mNumFlyPoints-1]));
if (mPreviousPath->mLocation[mPreviousPath->mNumFlyPoints-2].w == 0.0)
{
AtiVertex4Copy (&(pointArray[numPoints+2]), &(mPreviousPath->mLocation[mPreviousPath->mNumFlyPoints-2]));
if (mPreviousPath->mLocation[mPreviousPath->mNumFlyPoints-3].w == 0.0)
{
AtiVertex4Copy (&(pointArray[numPoints+1]), &(mPreviousPath->mLocation[mPreviousPath->mNumFlyPoints-3]));
if (mPreviousPath->mLocation[mPreviousPath->mNumFlyPoints-4].w == 0.0)
{
AtiVertex4Copy (&(pointArray[numPoints+0]), &(mPreviousPath->mLocation[mPreviousPath->mNumFlyPoints-4]));
}
else
{
AtiVertex4Lerp (&(pointArray[numPoints+0]), &(pointArray[numPoints+1]), &(pointArray[numPoints+2]), -1.0f);
}
}
else
{
AtiVertex4Lerp (&(pointArray[numPoints+1]), &(pointArray[numPoints+2]), &(pointArray[numPoints+3]), -1.0f);
AtiVertex4Lerp (&(pointArray[numPoints+0]), &(pointArray[numPoints+1]), &(pointArray[numPoints+2]), -1.0f);
}
}
else
{
AtiVertex4Lerp (&(pointArray[numPoints+2]), &(pointArray[numPoints+3]), &(mLocation[i]), -1.0f);
AtiVertex4Lerp (&(pointArray[numPoints+1]), &(pointArray[numPoints+2]), &(pointArray[numPoints+3]), -1.0f);
AtiVertex4Lerp (&(pointArray[numPoints+0]), &(pointArray[numPoints+1]), &(pointArray[numPoints+2]), -1.0f);
}
}
else //Not first point on spline, just create phantom points
{
if (i < mNumFlyPoints-1) //If not last point on spline
{
AtiVertex4Lerp (&(pointArray[numPoints+3]), &(mLocation[i]), &(mLocation[i+1]), -1.0f);
AtiVertex4Lerp (&(pointArray[numPoints+2]), &(mLocation[i]), &(mLocation[i+1]), -2.0f);
AtiVertex4Lerp (&(pointArray[numPoints+1]), &(mLocation[i]), &(mLocation[i+1]), -3.0f);
AtiVertex4Lerp (&(pointArray[numPoints+0]), &(mLocation[i]), &(mLocation[i+1]), -4.0f);
}
else
{
if (mNextPath->mNumFlyPoints >= 5)
{
AtiVertex4Lerp (&(pointArray[numPoints+3]), &(mLocation[i]), &(mNextPath->mLocation[0]), -1.0f);
AtiVertex4Lerp (&(pointArray[numPoints+2]), &(mLocation[i]), &(mNextPath->mLocation[0]), -2.0f);
AtiVertex4Lerp (&(pointArray[numPoints+1]), &(mLocation[i]), &(mNextPath->mLocation[0]), -3.0f);
AtiVertex4Lerp (&(pointArray[numPoints+0]), &(mLocation[i]), &(mNextPath->mLocation[0]), -4.0f);
}
else //No next point...something's wrong
{
AtiVertex4Copy (&(pointArray[numPoints+3]), &(mLocation[i]));
AtiVertex4Copy (&(pointArray[numPoints+2]), &(mLocation[i]));
AtiVertex4Copy (&(pointArray[numPoints+1]), &(mLocation[i]));
AtiVertex4Copy (&(pointArray[numPoints+0]), &(mLocation[i]));
}
}
}
numPoints += 4;
/*****************************************/
/* Add all points that aren't cut points */
/*****************************************/
for (; i<mNumFlyPoints; i++)
{
/******************/
/* Add this point */
/******************/
AtiVertex4Copy (&(pointArray[numPoints]), &(mLocation[i]));
numPoints++;
/**********************/
/* Break if cut point */
/**********************/
if (mLocation[i].w != 0.0)
break;
}
/*************************************************/
/* Add last 4 pad points by either getting them */
/* from the next path or creating phantom points */
/*************************************************/
if (((i < mNumFlyPoints) && (mLocation[i].w != 0.0)) || ((i >= mNumFlyPoints) && (mNextPath->mNumFlyPoints < 5))) //If cut point OR next path isn't valid
{
AtiVertex4Lerp (&(pointArray[numPoints+0]), &(pointArray[numPoints-2]), &(pointArray[numPoints-1]), 2.0f);
AtiVertex4Lerp (&(pointArray[numPoints+1]), &(pointArray[numPoints-2]), &(pointArray[numPoints-1]), 3.0f);
AtiVertex4Lerp (&(pointArray[numPoints+2]), &(pointArray[numPoints-2]), &(pointArray[numPoints-1]), 4.0f);
AtiVertex4Lerp (&(pointArray[numPoints+3]), &(pointArray[numPoints-2]), &(pointArray[numPoints-1]), 5.0f);
numPoints += 4;
}
else //Look at next path
{
/********************************************************************/
/* This is the last point and smoothly feeding into the next spline */
/********************************************************************/
//Add first point to close the spline
AtiVertex4Copy (&(pointArray[numPoints]), &(mNextPath->mLocation[0]));
numPoints++;
//Pad with next point
AtiVertex4Copy (&(pointArray[numPoints+0]), &(mNextPath->mLocation[1]));
if (mNextPath->mLocation[1].w == 0.0f)
{
AtiVertex4Copy (&(pointArray[numPoints+1]), &(mNextPath->mLocation[2]));
if (mNextPath->mLocation[2].w == 0.0f)
{
AtiVertex4Copy (&(pointArray[numPoints+2]), &(mNextPath->mLocation[3]));
if (mNextPath->mLocation[3].w == 0.0f)
{
AtiVertex4Copy (&(pointArray[numPoints+3]), &(mNextPath->mLocation[4]));
}
else
{
AtiVertex4Lerp (&(pointArray[numPoints+3]), &(pointArray[numPoints+1]), &(pointArray[numPoints+2]), 2.0f);
}
}
else
{
AtiVertex4Lerp (&(pointArray[numPoints+2]), &(pointArray[numPoints+0]), &(pointArray[numPoints+1]), 2.0f);
AtiVertex4Lerp (&(pointArray[numPoints+3]), &(pointArray[numPoints+1]), &(pointArray[numPoints+2]), 2.0f);
}
}
else
{
AtiVertex4Lerp (&(pointArray[numPoints+1]), &(pointArray[numPoints-1]), &(pointArray[numPoints+0]), 2.0f);
AtiVertex4Lerp (&(pointArray[numPoints+2]), &(pointArray[numPoints+0]), &(pointArray[numPoints+1]), 2.0f);
AtiVertex4Lerp (&(pointArray[numPoints+3]), &(pointArray[numPoints+1]), &(pointArray[numPoints+2]), 2.0f);
}
numPoints += 4;
}
/********************************************************/
/* Create spline interval variables based on pointArray */
/********************************************************/
tmpD2[0].x = 0.0f;
tmpD2[0].y = 0.0f;
tmpD2[0].z = 0.0f;
tmpD2[0].w = 0.0f;
tmpIntD2[0].x = 0.0f;
tmpIntD2[0].y = 0.0f;
tmpIntD2[0].z = 0.0f;
tmpIntD2[0].w = 0.0f;
//Calculate second derivative for all points except first and last
for (j=1; j<numPoints-1; j++) //For each point
{
for (k=0; k<4; k++) //For x, y, and z
{
float32 time = 0.5f;
float32 time2 = 1.0f;
tmpf = (time * tmpD2[j-1].v[k]) + 2.0f;
tmpD2[j].v[k] = (time - 1.0f) / tmpf;
tmpf2 = ((pointArray[j+1].v[k] - pointArray[j].v[k]) / (time2)) -
((pointArray[j].v[k] - pointArray[j-1].v[k]) / (time2));
tmpIntD2[j].v[k] = ((6.0f * tmpf2) / (time2+time2)) - (time * tmpIntD2[j-1].v[k]);
tmpIntD2[j].v[k] /= tmpf;
}
}
tmpD2[numPoints-1].x = 0.0f;
tmpD2[numPoints-1].y = 0.0f;
tmpD2[numPoints-1].z = 0.0f;
tmpD2[numPoints-1].w = 0.0f;
tmpIntD2[numPoints-1].x = 0.0f;
tmpIntD2[numPoints-1].y = 0.0f;
tmpIntD2[numPoints-1].z = 0.0f;
tmpIntD2[numPoints-1].w = 0.0f;
for (j=numPoints-2; j>=1; j--)
{
tmpD2[j].x = (tmpD2[j].x * tmpD2[j+1].x) + tmpIntD2[j].x;
tmpD2[j].y = (tmpD2[j].y * tmpD2[j+1].y) + tmpIntD2[j].y;
tmpD2[j].z = (tmpD2[j].z * tmpD2[j+1].z) + tmpIntD2[j].z;
tmpD2[j].w = (tmpD2[j].w * tmpD2[j+1].w) + tmpIntD2[j].w;
}
for (j=4; j<numPoints-5; j++)
{
mLocationIntervals[mNumSplineIntervals].lo.x = pointArray[j].x;
mLocationIntervals[mNumSplineIntervals].lo.y = pointArray[j].y;
mLocationIntervals[mNumSplineIntervals].lo.z = pointArray[j].z;
mLocationIntervals[mNumSplineIntervals].lo.w = pointArray[j].w;
mLocationIntervals[mNumSplineIntervals].hi.x = pointArray[j+1].x;
mLocationIntervals[mNumSplineIntervals].hi.y = pointArray[j+1].y;
mLocationIntervals[mNumSplineIntervals].hi.z = pointArray[j+1].z;
mLocationIntervals[mNumSplineIntervals].hi.w = pointArray[j+1].w;
mLocationIntervals[mNumSplineIntervals].lo2.x = tmpD2[j].x;
mLocationIntervals[mNumSplineIntervals].lo2.y = tmpD2[j].y;
mLocationIntervals[mNumSplineIntervals].lo2.z = tmpD2[j].z;
mLocationIntervals[mNumSplineIntervals].lo2.w = tmpD2[j].w;
mLocationIntervals[mNumSplineIntervals].hi2.x = tmpD2[j+1].x;
mLocationIntervals[mNumSplineIntervals].hi2.y = tmpD2[j+1].y;
mLocationIntervals[mNumSplineIntervals].hi2.z = tmpD2[j+1].z;
mLocationIntervals[mNumSplineIntervals].hi2.w = tmpD2[j+1].w;
/********************/
/* Update variables */
/********************/
mNumSplineIntervals++;
mPathTime += mSampleInterval;
}
}
/*********************************/
/* Free temporary storage memory */
/*********************************/
AtiFreeArray(pointArray);
AtiFreeArray(tmpD2);
AtiFreeArray(tmpIntD2);
return TRUE;
}
//=============================================================================
bool8 AtiFlyPath::GetPathPosition (AtiVertex3 *aPosition, float64 aTime)
{
int32 tmpi;
int32 interval;
float32 intervalOffset;
float64 tmpf64;
float32 a;
float32 b;
if (mInFlight == FALSE)
return FALSE;
/******************************/
/* Take care of loop wrapping */
/******************************/
tmpf64 = aTime - mStartTime;
if (tmpf64 >= mPathTime)
{
tmpi = (int32)(tmpf64/mPathTime);
tmpf64 -= mPathTime * (float64)(tmpi);
}
/**********************************************************************************/
/* Figure out which interval this time falls into and calculate normalized offset */
/**********************************************************************************/
interval = (int32)(tmpf64/mSampleInterval);
intervalOffset = (float32)((tmpf64 - (mSampleInterval*(float64)(interval))) / mSampleInterval);
a = 1.0f - intervalOffset;
b = intervalOffset;
aPosition->x = a*mLocationIntervals[interval].lo.x + b*mLocationIntervals[interval].hi.x + ((a*a*a - a)*mLocationIntervals[interval].lo2.x + (b*b*b - b)*mLocationIntervals[interval].hi2.x) / 6.0f;// * (float32)(mSampleInterval*mSampleInterval) / 6.0f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -