From 1fad2c73729c685118d4cb3ccd4f1812e35061b4 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Thu, 17 Apr 2025 20:01:36 -0500 Subject: [PATCH] AIWheeledVehicleControllerData wipwork --- Engine/source/T3D/AI/AIController.cpp | 140 +++++++++++++++++- Engine/source/T3D/AI/AIController.h | 26 ++++ Engine/source/T3D/vehicles/vehicle.h | 1 + .../datablocks/defaultDatablocks.tscript | 5 + 4 files changed, 171 insertions(+), 1 deletion(-) diff --git a/Engine/source/T3D/AI/AIController.cpp b/Engine/source/T3D/AI/AIController.cpp index fa9befa03..f69345e10 100644 --- a/Engine/source/T3D/AI/AIController.cpp +++ b/Engine/source/T3D/AI/AIController.cpp @@ -22,6 +22,8 @@ #include "AIController.h" #include "T3D/player.h" +#include "T3D/rigidShape.h" +#include "T3D/vehicles/wheeledVehicle.h" IMPLEMENT_CONOBJECT(AIController); @@ -139,8 +141,12 @@ bool AIController::getAIMove(Move* movePtr) { if (getGoal()->getDist() > mControllerData->mFollowTolerance) { + SceneObject* obj = getAIInfo()->mObj->getObjectMount(); + if (!obj) + obj = getAIInfo()->mObj; + RayInfo info; - if (getAIInfo()->mObj->getContainer()->castRay(getAIInfo()->getPosition(), getAIInfo()->getPosition() - Point3F(0, 0, 0.001f), StaticShapeObjectType, &info)) + if (obj->getContainer()->castRay(obj->getPosition(), obj->getPosition() - Point3F(0, 0, 0.001f), StaticShapeObjectType, &info)) { getNav()->repath(); } @@ -596,4 +602,136 @@ void AIPlayerControllerData::resolveTriggerState(AIController* obj, Move* movePt } #endif // TORQUE_NAVIGATION_ENABLED } + +IMPLEMENT_CO_DATABLOCK_V1(AIWheeledVehicleControllerData); + +// Build a Triangle .. calculate angle of rotation required to meet target.. +// man there has to be a better way! >:) +F32 AIWheeledVehicleControllerData::getSteeringAngle(AIController* obj) +{ + WheeledVehicle* wvo = dynamic_cast(obj->getAIInfo()->mObj.getPointer()); + if (!wvo) + { + //cover the case of a connection controling an object in turn controlling another + if (obj->getAIInfo()->mObj->getObjectMount()) + wvo = dynamic_cast(obj->getAIInfo()->mObj->getObjectMount()); + } + if (!wvo) return 0;//not a WheeledVehicle + + // What is our target + Point3F desired; + desired = obj->getNav()->mMoveDestination; + + MatrixF mat = wvo->getTransform(); + Point3F center, front; + Point3F wFront; + Box3F box = wvo->getObjBox(); + + box.getCenter(¢er); + front = center; + front.y = box.maxExtents.y; // should be true for all these objects + + obj->getAIInfo()->mObj->getWorldBox().getCenter(¢er); + front = center + front; + + Point3F objFront = front; + Point3F offset = front - center; + EulerF rot; + rot = mat.toEuler(); + MatrixF transform(rot); + transform.mulV(offset, &wFront); + front = wFront + center; + + Point3F ftoc; + ftoc.x = mFabs(front.x - center.x); + ftoc.y = mFabs(front.y - center.y); + ftoc.z = mFabs(front.z - center.z); + F32 fToc = mSqrt((ftoc.x * ftoc.x) + (ftoc.y * ftoc.y)); + + Point3F ltoc; + ltoc.x = mFabs(desired.x - center.x); + ltoc.y = mFabs(desired.y - center.y); + ltoc.z = mFabs(desired.z - center.z); + F32 lToc = mSqrt((ltoc.x * ltoc.x) + (ltoc.y * ltoc.y)); + + Point3F ftol; + ftol.x = mFabs(front.x - desired.x); + ftol.y = mFabs(front.y - desired.y); + ftol.z = mFabs(front.z - desired.z); + F32 fTol = mSqrt((ftol.x * ftol.x) + (ftol.y * ftol.y)); + + 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 maxSteeringAngle = 0; + + VehicleData* vd = (VehicleData*)(wvo->getDataBlock()); + maxSteeringAngle = vd->maxSteeringAngle; + + // if(finalYaw > 150) + // steerState = TurnAround; + if (finalYaw < 5) + mSteerState = Straight; + else + {// Quickly Hack out left or right turn info + Point3F rotData = objFront - desired; + MatrixF leftM(-rot); + Point3F leftP; + leftM.mulV(rotData, &leftP); + leftP = leftP + desired; + + if (leftP.x < desired.x) + mSteerState = Right; + else + mSteerState = Left; + } + + Point2F steering = wvo->getSteering(); + + F32 steer = 0; + switch (mSteerState) + { + case SteerNull: + break; + case Left: + steer = myAngle < maxSteeringAngle ? -myAngle - steering.x : -maxSteeringAngle - steering.x; + break; + case Right: + steer = myAngle < maxSteeringAngle ? myAngle - steering.x : maxSteeringAngle - steering.x; + break; + case Straight: + steer = -steering.x; + break; + case TurnAround: + steer = maxSteeringAngle - steering.x; + break; + }; + + // Con::printf("AI Steering : %f", steer); + return steer; +} + + +void AIWheeledVehicleControllerData::resolveYaw(AIController* obj, Point3F location, Move* movePtr) +{ + WheeledVehicle* wvo = dynamic_cast(obj->getAIInfo()->mObj.getPointer()); + if (!wvo) + { + //cover the case of a connection controling an object in turn controlling another + if (obj->getAIInfo()->mObj->getObjectMount()) + wvo = dynamic_cast(obj->getAIInfo()->mObj->getObjectMount()); + } + if (!wvo) return;//not a WheeledVehicle + + // Orient towards our destination. + if (obj->mMovement.mMoveState == AIController::ModeMove || obj->mMovement.mMoveState == AIController::ModeReverse) { + movePtr->yaw = getSteeringAngle(obj); + } +}; +void AIWheeledVehicleControllerData::resolveTriggerState(AIController* obj, Move* movePtr) {}; #endif //_AICONTROLLER_H_ diff --git a/Engine/source/T3D/AI/AIController.h b/Engine/source/T3D/AI/AIController.h index 78c7cb86b..d724d9ee5 100644 --- a/Engine/source/T3D/AI/AIController.h +++ b/Engine/source/T3D/AI/AIController.h @@ -45,6 +45,7 @@ public: ModeMove, // AI is currently moving. ModeStuck, // AI is stuck, but wants to move. ModeSlowing, // AI is slowing down as it reaches it's destination. + ModeReverse // AI is reversing }; private: @@ -198,5 +199,30 @@ public: void resolveTriggerState(AIController* obj, Move* movePtr); DECLARE_CONOBJECT(AIPlayerControllerData); }; + +class AIWheeledVehicleControllerData : public AIControllerData +{ + typedef AIControllerData Parent; + + enum DrivingState { + SteerNull, + Left, + Right, + Straight, + TurnAround + } mSteerState; + +public: + AIWheeledVehicleControllerData() + { + mSteerState = SteerNull; + resolveYawPtr.bind(this, &AIWheeledVehicleControllerData::resolveYaw); + resolveTriggerStatePtr.bind(this, &AIWheeledVehicleControllerData::resolveTriggerState); + } + F32 getSteeringAngle(AIController* obj); + void resolveYaw(AIController* obj, Point3F location, Move* movePtr); + void resolveTriggerState(AIController* obj, Move* movePtr); + DECLARE_CONOBJECT(AIWheeledVehicleControllerData); +}; #endif // TORQUE_NAVIGATION_ENABLED #endif //_AICONTROLLER_H_ diff --git a/Engine/source/T3D/vehicles/vehicle.h b/Engine/source/T3D/vehicles/vehicle.h index 402a3109a..52dbb8e68 100644 --- a/Engine/source/T3D/vehicles/vehicle.h +++ b/Engine/source/T3D/vehicles/vehicle.h @@ -146,6 +146,7 @@ public: bool onAdd() override; void onRemove() override; + Point2F getSteering() { return mSteering; }; /// Interpolates between move ticks @see processTick /// @param dt Change in time between the last call and this call to the function void advanceTime(F32 dt) override; diff --git a/Templates/BaseGame/game/core/gameObjects/datablocks/defaultDatablocks.tscript b/Templates/BaseGame/game/core/gameObjects/datablocks/defaultDatablocks.tscript index fbd8cd5fc..ffdc4806c 100644 --- a/Templates/BaseGame/game/core/gameObjects/datablocks/defaultDatablocks.tscript +++ b/Templates/BaseGame/game/core/gameObjects/datablocks/defaultDatablocks.tscript @@ -173,4 +173,9 @@ datablock LightAnimData( SpinLightAnim ) datablock AIPlayerControllerData( aiPlayerControl ) { +}; + +datablock AIWheeledVehicleControllerData( aiCarControl ) +{ + }; \ No newline at end of file