mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
AIWheeledVehicleControllerData wipwork
This commit is contained in:
parent
d0b0070ec7
commit
1fad2c7372
4 changed files with 171 additions and 1 deletions
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include "AIController.h"
|
#include "AIController.h"
|
||||||
#include "T3D/player.h"
|
#include "T3D/player.h"
|
||||||
|
#include "T3D/rigidShape.h"
|
||||||
|
#include "T3D/vehicles/wheeledVehicle.h"
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(AIController);
|
IMPLEMENT_CONOBJECT(AIController);
|
||||||
|
|
@ -139,8 +141,12 @@ bool AIController::getAIMove(Move* movePtr)
|
||||||
{
|
{
|
||||||
if (getGoal()->getDist() > mControllerData->mFollowTolerance)
|
if (getGoal()->getDist() > mControllerData->mFollowTolerance)
|
||||||
{
|
{
|
||||||
|
SceneObject* obj = getAIInfo()->mObj->getObjectMount();
|
||||||
|
if (!obj)
|
||||||
|
obj = getAIInfo()->mObj;
|
||||||
|
|
||||||
RayInfo info;
|
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();
|
getNav()->repath();
|
||||||
}
|
}
|
||||||
|
|
@ -596,4 +602,136 @@ void AIPlayerControllerData::resolveTriggerState(AIController* obj, Move* movePt
|
||||||
}
|
}
|
||||||
#endif // TORQUE_NAVIGATION_ENABLED
|
#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<WheeledVehicle*>(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<WheeledVehicle*>(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<WheeledVehicle*>(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<WheeledVehicle*>(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_
|
#endif //_AICONTROLLER_H_
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ public:
|
||||||
ModeMove, // AI is currently moving.
|
ModeMove, // AI is currently moving.
|
||||||
ModeStuck, // AI is stuck, but wants to move.
|
ModeStuck, // AI is stuck, but wants to move.
|
||||||
ModeSlowing, // AI is slowing down as it reaches it's destination.
|
ModeSlowing, // AI is slowing down as it reaches it's destination.
|
||||||
|
ModeReverse // AI is reversing
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -198,5 +199,30 @@ public:
|
||||||
void resolveTriggerState(AIController* obj, Move* movePtr);
|
void resolveTriggerState(AIController* obj, Move* movePtr);
|
||||||
DECLARE_CONOBJECT(AIPlayerControllerData);
|
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 // TORQUE_NAVIGATION_ENABLED
|
||||||
#endif //_AICONTROLLER_H_
|
#endif //_AICONTROLLER_H_
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,7 @@ public:
|
||||||
bool onAdd() override;
|
bool onAdd() override;
|
||||||
void onRemove() override;
|
void onRemove() override;
|
||||||
|
|
||||||
|
Point2F getSteering() { return mSteering; };
|
||||||
/// Interpolates between move ticks @see processTick
|
/// Interpolates between move ticks @see processTick
|
||||||
/// @param dt Change in time between the last call and this call to the function
|
/// @param dt Change in time between the last call and this call to the function
|
||||||
void advanceTime(F32 dt) override;
|
void advanceTime(F32 dt) override;
|
||||||
|
|
|
||||||
|
|
@ -174,3 +174,8 @@ datablock AIPlayerControllerData( aiPlayerControl )
|
||||||
{
|
{
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
datablock AIWheeledVehicleControllerData( aiCarControl )
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue