bool APathFollower::Interpolate () { fixed_t dx = 0, dy = 0, dz = 0; if ((args[2] & 8) && Time > 0.f) { dx = X(); dy = Y(); dz = Z(); } if (CurrNode->Next==NULL) return false; UnlinkFromWorld (); fixed_t x, y, z; if (args[2] & 1) { // linear x = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->X()), FIXED2FLOAT(CurrNode->Next->X()))); y = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->Y()), FIXED2FLOAT(CurrNode->Next->Y()))); z = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->Z()), FIXED2FLOAT(CurrNode->Next->Z()))); } else { // spline if (CurrNode->Next->Next==NULL) return false; x = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->X()), FIXED2FLOAT(CurrNode->X()), FIXED2FLOAT(CurrNode->Next->X()), FIXED2FLOAT(CurrNode->Next->Next->X()))); y = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->Y()), FIXED2FLOAT(CurrNode->Y()), FIXED2FLOAT(CurrNode->Next->Y()), FIXED2FLOAT(CurrNode->Next->Next->Y()))); z = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->Z()), FIXED2FLOAT(CurrNode->Z()), FIXED2FLOAT(CurrNode->Next->Z()), FIXED2FLOAT(CurrNode->Next->Next->Z()))); } SetXYZ(x, y, z); LinkToWorld (); if (args[2] & 6) { if (args[2] & 8) { if (args[2] & 1) { // linear dx = CurrNode->Next->X() - CurrNode->X(); dy = CurrNode->Next->Y() - CurrNode->Y(); dz = CurrNode->Next->Z() - CurrNode->Z(); } else if (Time > 0.f) { // spline dx = x - dx; dy = y - dy; dz = z - dz; } else { int realarg = args[2]; args[2] &= ~(2|4|8); Time += 0.1f; dx = x; dy = y; dz = z; Interpolate (); Time -= 0.1f; args[2] = realarg; dx = x - dx; dy = y - dy; dz = z - dz; x -= dx; y -= dy; z -= dz; SetXYZ(x, y, z); } if (args[2] & 2) { // adjust yaw angle = R_PointToAngle2 (0, 0, dx, dy); } if (args[2] & 4) { // adjust pitch; use floats for precision double fdx = FIXED2DBL(dx); double fdy = FIXED2DBL(dy); double fdz = FIXED2DBL(-dz); double dist = sqrt (fdx*fdx + fdy*fdy); double ang = dist != 0.f ? atan2 (fdz, dist) : 0; pitch = (fixed_t)RAD2ANGLE(ang); } } else { if (args[2] & 2) { // interpolate angle float angle1 = (float)CurrNode->angle; float angle2 = (float)CurrNode->Next->angle; if (angle2 - angle1 <= -2147483648.f) { float lerped = Lerp (angle1, angle2 + 4294967296.f); if (lerped >= 4294967296.f) { angle = xs_CRoundToUInt(lerped - 4294967296.f); } else { angle = xs_CRoundToUInt(lerped); } } else if (angle2 - angle1 >= 2147483648.f) { float lerped = Lerp (angle1, angle2 - 4294967296.f); if (lerped < 0.f) { angle = xs_CRoundToUInt(lerped + 4294967296.f); } else { angle = xs_CRoundToUInt(lerped); } } else { angle = xs_CRoundToUInt(Lerp (angle1, angle2)); } } if (args[2] & 1) { // linear if (args[2] & 4) { // interpolate pitch pitch = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->pitch), FIXED2FLOAT(CurrNode->Next->pitch))); } } else { // spline if (args[2] & 4) { // interpolate pitch pitch = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->pitch), FIXED2FLOAT(CurrNode->pitch), FIXED2FLOAT(CurrNode->Next->pitch), FIXED2FLOAT(CurrNode->Next->Next->pitch))); } } } } return true; }
bool APathFollower::Interpolate () { fixed_t dx = 0, dy = 0, dz = 0; if ((args[2] & 8) && Time > 0.f) { dx = x; dy = y; dz = z; } if (CurrNode->Next==NULL) return false; UnlinkFromWorld (); if (args[2] & 1) { // linear x = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->x), FIXED2FLOAT(CurrNode->Next->x))); y = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->y), FIXED2FLOAT(CurrNode->Next->y))); z = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->z), FIXED2FLOAT(CurrNode->Next->z))); } else { // spline if (CurrNode->Next->Next==NULL) return false; x = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->x), FIXED2FLOAT(CurrNode->x), FIXED2FLOAT(CurrNode->Next->x), FIXED2FLOAT(CurrNode->Next->Next->x))); y = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->y), FIXED2FLOAT(CurrNode->y), FIXED2FLOAT(CurrNode->Next->y), FIXED2FLOAT(CurrNode->Next->Next->y))); z = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->z), FIXED2FLOAT(CurrNode->z), FIXED2FLOAT(CurrNode->Next->z), FIXED2FLOAT(CurrNode->Next->Next->z))); } LinkToWorld (); if (args[2] & 6) { if (args[2] & 8) { if (args[2] & 1) { // linear dx = CurrNode->Next->x - CurrNode->x; dy = CurrNode->Next->y - CurrNode->y; dz = CurrNode->Next->z - CurrNode->z; } else if (Time > 0.f) { // spline dx = x - dx; dy = y - dy; dz = z - dz; } else { int realarg = args[2]; args[2] &= ~(2|4|8); Time += 0.1f; dx = x; dy = y; dz = z; Interpolate (); Time -= 0.1f; args[2] = realarg; dx = x - dx; dy = y - dy; dz = z - dz; x -= dx; y -= dy; z -= dz; } if (args[2] & 2) { // adjust yaw angle = R_PointToAngle2 (0, 0, dx, dy); } if (args[2] & 4) { // adjust pitch; use floats for precision float fdx = FIXED2FLOAT(dx); float fdy = FIXED2FLOAT(dy); float fdz = FIXED2FLOAT(-dz); float dist = (float)sqrt (fdx*fdx + fdy*fdy); float ang = dist != 0.f ? (float)atan2 (fdz, dist) : 0; pitch = (angle_t)(ang * 2147483648.f / PI); } } else { if (args[2] & 2) { // interpolate angle float angle1 = (float)CurrNode->angle; float angle2 = (float)CurrNode->Next->angle; if (angle2 - angle1 <= -2147483648.f) { float lerped = Lerp (angle1, angle2 + 4294967296.f); if (lerped >= 4294967296.f) { angle = (angle_t)(lerped - 4294967296.f); } else { angle = (angle_t)lerped; } } else if (angle2 - angle1 >= 2147483648.f) { float lerped = Lerp (angle1, angle2 - 4294967296.f); if (lerped < 0.f) { angle = (angle_t)(lerped + 4294967296.f); } else { angle = (angle_t)lerped; } } else { angle = (angle_t)Lerp (angle1, angle2); } } if (args[2] & 1) { // linear if (args[2] & 4) { // interpolate pitch pitch = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->pitch), FIXED2FLOAT(CurrNode->Next->pitch))); } } else { // spline if (args[2] & 4) { // interpolate pitch pitch = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->pitch), FIXED2FLOAT(CurrNode->pitch), FIXED2FLOAT(CurrNode->Next->pitch), FIXED2FLOAT(CurrNode->Next->Next->pitch))); } } } } return true; }
bool APathFollower::Interpolate () { DVector3 dpos(0, 0, 0); FLinkContext ctx; if ((args[2] & 8) && Time > 0.f) { dpos = Pos(); } if (CurrNode->Next==NULL) return false; UnlinkFromWorld (&ctx); DVector3 newpos; if (args[2] & 1) { // linear newpos.X = Lerp(CurrNode->X(), CurrNode->Next->X()); newpos.Y = Lerp(CurrNode->Y(), CurrNode->Next->Y()); newpos.Z = Lerp(CurrNode->Z(), CurrNode->Next->Z()); } else { // spline if (CurrNode->Next->Next==NULL) return false; newpos.X = Splerp(PrevNode->X(), CurrNode->X(), CurrNode->Next->X(), CurrNode->Next->Next->X()); newpos.Y = Splerp(PrevNode->Y(), CurrNode->Y(), CurrNode->Next->Y(), CurrNode->Next->Next->Y()); newpos.Z = Splerp(PrevNode->Z(), CurrNode->Z(), CurrNode->Next->Z(), CurrNode->Next->Next->Z()); } SetXYZ(newpos); LinkToWorld (&ctx); if (args[2] & 6) { if (args[2] & 8) { if (args[2] & 1) { // linear dpos.X = CurrNode->Next->X() - CurrNode->X(); dpos.Y = CurrNode->Next->Y() - CurrNode->Y(); dpos.Z = CurrNode->Next->Z() - CurrNode->Z(); } else if (Time > 0.f) { // spline dpos = newpos - dpos; } else { int realarg = args[2]; args[2] &= ~(2|4|8); Time += 0.1f; dpos = newpos; Interpolate (); Time -= 0.1f; args[2] = realarg; dpos = newpos - dpos; newpos -= dpos; SetXYZ(newpos); } if (args[2] & 2) { // adjust yaw Angles.Yaw = dpos.Angle(); } if (args[2] & 4) { // adjust pitch; use floats for precision double dist = dpos.XY().Length(); Angles.Pitch = dist != 0.f ? VecToAngle(dist, -dpos.Z) : 0.; } } else { if (args[2] & 2) { // interpolate angle DAngle angle1 = CurrNode->Angles.Yaw.Normalized180(); DAngle angle2 = angle1 + deltaangle(angle1, CurrNode->Next->Angles.Yaw); Angles.Yaw = Lerp(angle1.Degrees, angle2.Degrees); } if (args[2] & 1) { // linear if (args[2] & 4) { // interpolate pitch Angles.Pitch = Lerp(CurrNode->Angles.Pitch.Degrees, CurrNode->Next->Angles.Pitch.Degrees); } } else { // spline if (args[2] & 4) { // interpolate pitch Angles.Pitch = Splerp(PrevNode->Angles.Pitch.Degrees, CurrNode->Angles.Pitch.Degrees, CurrNode->Next->Angles.Pitch.Degrees, CurrNode->Next->Next->Angles.Pitch.Degrees); } } } } return true; }