make steerstate for AIWheeledVehicleControllerData's self contained

variable raylength for the rpath filter. same 0.001 for players to stop recalculating a path when jumping, but bump anything they're mounted to to a 2 unit check

bit of work towards parallel parking. or at least not ending up arcing back and forth infinitely in an arc
This commit is contained in:
AzaezelX 2025-04-17 23:31:30 -05:00
parent 1fad2c7372
commit 2d5e8c1560
2 changed files with 70 additions and 26 deletions

View file

@ -141,12 +141,16 @@ bool AIController::getAIMove(Move* movePtr)
{ {
if (getGoal()->getDist() > mControllerData->mFollowTolerance) if (getGoal()->getDist() > mControllerData->mFollowTolerance)
{ {
F32 raylength = 2.0; //for vehicles
SceneObject* obj = getAIInfo()->mObj->getObjectMount(); SceneObject* obj = getAIInfo()->mObj->getObjectMount();
if (!obj) if (!obj)
{
obj = getAIInfo()->mObj; obj = getAIInfo()->mObj;
raylength = 0.001f; //for jumping
}
RayInfo info; RayInfo info;
if (obj->getContainer()->castRay(obj->getPosition(), obj->getPosition() - Point3F(0, 0, 0.001f), StaticShapeObjectType, &info)) if (obj->getContainer()->castRay(obj->getPosition(), obj->getPosition() - Point3F(0, 0, raylength), StaticShapeObjectType, &info))
{ {
getNav()->repath(); getNav()->repath();
} }
@ -607,7 +611,7 @@ IMPLEMENT_CO_DATABLOCK_V1(AIWheeledVehicleControllerData);
// Build a Triangle .. calculate angle of rotation required to meet target.. // Build a Triangle .. calculate angle of rotation required to meet target..
// man there has to be a better way! >:) // man there has to be a better way! >:)
F32 AIWheeledVehicleControllerData::getSteeringAngle(AIController* obj) F32 AIWheeledVehicleControllerData::getSteeringAngle(AIController* obj, Point3F location)
{ {
WheeledVehicle* wvo = dynamic_cast<WheeledVehicle*>(obj->getAIInfo()->mObj.getPointer()); WheeledVehicle* wvo = dynamic_cast<WheeledVehicle*>(obj->getAIInfo()->mObj.getPointer());
if (!wvo) if (!wvo)
@ -618,6 +622,8 @@ F32 AIWheeledVehicleControllerData::getSteeringAngle(AIController* obj)
} }
if (!wvo) return 0;//not a WheeledVehicle if (!wvo) return 0;//not a WheeledVehicle
DrivingState steerState = SteerNull;
// What is our target // What is our target
Point3F desired; Point3F desired;
desired = obj->getNav()->mMoveDestination; desired = obj->getNav()->mMoveDestination;
@ -661,10 +667,6 @@ F32 AIWheeledVehicleControllerData::getSteeringAngle(AIController* obj)
F32 fTol = mSqrt((ftol.x * ftol.x) + (ftol.y * ftol.y)); F32 fTol = mSqrt((ftol.x * ftol.x) + (ftol.y * ftol.y));
F32 myAngle = mAcos(((lToc * lToc) + (fToc * fToc) - (fTol * fTol)) / (2 * lToc * fToc)); F32 myAngle = mAcos(((lToc * lToc) + (fToc * fToc) - (fTol * fTol)) / (2 * lToc * fToc));
Point3F location = obj->getAIInfo()->getPosition();
F32 xDiff = desired.x - location.x;
F32 yDiff = desired.y - location.y;
F32 finalYaw = mRadToDeg(myAngle); F32 finalYaw = mRadToDeg(myAngle);
@ -673,10 +675,12 @@ F32 AIWheeledVehicleControllerData::getSteeringAngle(AIController* obj)
VehicleData* vd = (VehicleData*)(wvo->getDataBlock()); VehicleData* vd = (VehicleData*)(wvo->getDataBlock());
maxSteeringAngle = vd->maxSteeringAngle; maxSteeringAngle = vd->maxSteeringAngle;
// if(finalYaw > 150) Point2F steering = wvo->getSteering();
// steerState = TurnAround;
if (finalYaw < 5) if (finalYaw < 5 && steering.x != 0.0f)
mSteerState = Straight; steerState = Straight;
else if (finalYaw < 5)
steerState = SteerNull;
else else
{// Quickly Hack out left or right turn info {// Quickly Hack out left or right turn info
Point3F rotData = objFront - desired; Point3F rotData = objFront - desired;
@ -686,32 +690,74 @@ F32 AIWheeledVehicleControllerData::getSteeringAngle(AIController* obj)
leftP = leftP + desired; leftP = leftP + desired;
if (leftP.x < desired.x) if (leftP.x < desired.x)
mSteerState = Right; steerState = Right;
else else
mSteerState = Left; steerState = Left;
} }
Point2F steering = wvo->getSteering();
F32 xDiff = obj->getNav()->mMoveDestination.x - location.x;
F32 yDiff = obj->getNav()->mMoveDestination.y - location.y;
Point3F rotation = wvo->getTransform().toEuler();
Point2F mov;
// Build move direction in world space
if (mIsZero(xDiff))
mov.y = (location.y > obj->getNav()->mMoveDestination.y) ? -1.0f : 1.0f;
else
{
if (mIsZero(yDiff))
mov.x = (location.x > obj->getNav()->mMoveDestination.x) ? -1.0f : 1.0f;
else
if (mFabs(xDiff) > mFabs(yDiff))
{
F32 value = mFabs(yDiff / xDiff);
mov.y = (location.y > obj->getNav()->mMoveDestination.y) ? -value : value;
mov.x = (location.x > obj->getNav()->mMoveDestination.x) ? -1.0f : 1.0f;
}
else
{
F32 value = mFabs(xDiff / yDiff);
mov.x = (location.x > obj->getNav()->mMoveDestination.x) ? -value : value;
mov.y = (location.y > obj->getNav()->mMoveDestination.y) ? -1.0f : 1.0f;
}
}
// Rotate the move into object space (this really only needs
// a 2D matrix)
Point3F throttle;
MatrixF moveMatrix;
moveMatrix.set(EulerF(0.0f, 0.0f, -(rotation.z + steering.x)));
moveMatrix.mulV(Point3F(mov.x, mov.y, 0.0f), &throttle);
F32 turnAdjust = myAngle - steering.x;
if (throttle.y < 0.0f)
{
F32 reverseReduction = 0.25f;
if (steerState == Left)
steerState = Right;
else if (steerState == Right)
steerState = Left;
turnAdjust *= reverseReduction;
myAngle *= reverseReduction;
}
F32 steer = 0; F32 steer = 0;
switch (mSteerState) switch (steerState)
{ {
case SteerNull:
break;
case Left: case Left:
steer = myAngle < maxSteeringAngle ? -myAngle - steering.x : -maxSteeringAngle - steering.x; steer = myAngle < maxSteeringAngle ? -turnAdjust : -maxSteeringAngle - steering.x;
break; break;
case Right: case Right:
steer = myAngle < maxSteeringAngle ? myAngle - steering.x : maxSteeringAngle - steering.x; steer = myAngle < maxSteeringAngle ? turnAdjust : maxSteeringAngle - steering.x;
break; break;
case Straight: case Straight:
steer = -steering.x; steer = -steering.x;
break; break;
case TurnAround: default:
steer = maxSteeringAngle - steering.x;
break; break;
}; };
// Con::printf("AI Steering : %f", steer); // Con::printf("AI Steering : %f", steer);
return steer; return steer;
} }
@ -730,7 +776,7 @@ void AIWheeledVehicleControllerData::resolveYaw(AIController* obj, Point3F locat
// Orient towards our destination. // Orient towards our destination.
if (obj->mMovement.mMoveState == AIController::ModeMove || obj->mMovement.mMoveState == AIController::ModeReverse) { if (obj->mMovement.mMoveState == AIController::ModeMove || obj->mMovement.mMoveState == AIController::ModeReverse) {
movePtr->yaw = getSteeringAngle(obj); movePtr->yaw = getSteeringAngle(obj, location);
} }
}; };
void AIWheeledVehicleControllerData::resolveTriggerState(AIController* obj, Move* movePtr) {}; void AIWheeledVehicleControllerData::resolveTriggerState(AIController* obj, Move* movePtr) {};

View file

@ -208,18 +208,16 @@ class AIWheeledVehicleControllerData : public AIControllerData
SteerNull, SteerNull,
Left, Left,
Right, Right,
Straight, Straight
TurnAround };
} mSteerState;
public: public:
AIWheeledVehicleControllerData() AIWheeledVehicleControllerData()
{ {
mSteerState = SteerNull;
resolveYawPtr.bind(this, &AIWheeledVehicleControllerData::resolveYaw); resolveYawPtr.bind(this, &AIWheeledVehicleControllerData::resolveYaw);
resolveTriggerStatePtr.bind(this, &AIWheeledVehicleControllerData::resolveTriggerState); resolveTriggerStatePtr.bind(this, &AIWheeledVehicleControllerData::resolveTriggerState);
} }
F32 getSteeringAngle(AIController* obj); F32 getSteeringAngle(AIController* obj, Point3F location);
void resolveYaw(AIController* obj, Point3F location, Move* movePtr); void resolveYaw(AIController* obj, Point3F location, Move* movePtr);
void resolveTriggerState(AIController* obj, Move* movePtr); void resolveTriggerState(AIController* obj, Move* movePtr);
DECLARE_CONOBJECT(AIWheeledVehicleControllerData); DECLARE_CONOBJECT(AIWheeledVehicleControllerData);