// diffvel is required change in velocity in object space // returns true if this can be done in a single timestep bool Ship::AIChangeVelBy(const vector3d &diffvel) { // counter external forces vector3d extf = GetExternalForce() * (Pi::game->GetTimeStep() / GetMass()); vector3d diffvel2 = diffvel - extf * GetOrient(); vector3d maxThrust = GetMaxThrust(diffvel2); vector3d maxFrameAccel = maxThrust * (Pi::game->GetTimeStep() / GetMass()); vector3d thrust(diffvel2.x / maxFrameAccel.x, diffvel2.y / maxFrameAccel.y, diffvel2.z / maxFrameAccel.z); SetThrusterState(thrust); // use clamping if (thrust.x*thrust.x > 1.0 || thrust.y*thrust.y > 1.0 || thrust.z*thrust.z > 1.0) return false; return true; }
// Change object-space velocity in direction of param vector3d Ship::AIChangeVelDir(const vector3d &reqdiffvel) { // get max thrust in desired direction after external force compensation vector3d maxthrust = GetMaxThrust(reqdiffvel); maxthrust += GetExternalForce() * GetOrient(); vector3d maxFA = maxthrust * (Pi::game->GetTimeStep() / GetMass()); maxFA.x = fabs(maxFA.x); maxFA.y = fabs(maxFA.y); maxFA.z = fabs(maxFA.z); // crunch diffvel by relative thruster power to get acceleration in right direction vector3d diffvel = reqdiffvel; if (fabs(diffvel.x) > maxFA.x) diffvel *= maxFA.x / fabs(diffvel.x); if (fabs(diffvel.y) > maxFA.y) diffvel *= maxFA.y / fabs(diffvel.y); if (fabs(diffvel.z) > maxFA.z) diffvel *= maxFA.z / fabs(diffvel.z); AIChangeVelBy(diffvel); // should always return true because it's already capped? return GetOrient() * (reqdiffvel - diffvel); // should be remaining diffvel to correct }
// diffvel is required change in velocity in object space // returns true if this can be done in a single timestep bool Ship::AIChangeVelBy(const vector3d &diffvel) { // counter external forces unless we're in an orbital station rotating frame matrix4x4d rot; GetRotMatrix(rot); vector3d diffvel2 = GetExternalForce() * Pi::GetTimeStep() / GetMass(); if (GetFrame()->IsStationRotFrame()) diffvel2 = diffvel; else diffvel2 = diffvel - diffvel2 * rot; vector3d maxThrust = GetMaxThrust(diffvel2); vector3d maxFrameAccel = maxThrust * Pi::GetTimeStep() / GetMass(); vector3d thrust(diffvel2.x / maxFrameAccel.x, diffvel2.y / maxFrameAccel.y, diffvel2.z / maxFrameAccel.z); SetThrusterState(thrust); // use clamping if (thrust.x*thrust.x > 1.0 || thrust.y*thrust.y > 1.0 || thrust.z*thrust.z > 1.0) return false; return true; }