2021SC@SDUSC
上次我们分析了flaxEgnine游戏引擎中WheeledVehicle.h文件。而本次我将针对flaxEngine游戏引擎中的WheeledVehicle.c文件进行源码的分析。
void FreeDrive(WheeledVehicle::DriveTypes driveType, PxVehicleWheels* drive)
{
switch (driveType)
{
case WheeledVehicle::DriveTypes::Drive4W:
((PxVehicleDrive4W*)drive)->free();
break;
case WheeledVehicle::DriveTypes::DriveNW:
((PxVehicleDriveNW*)drive)->free();
break;
case WheeledVehicle::DriveTypes::NoDrive:
((PxVehicleNoDrive*)drive)->free();
break;
}
}
上述代码是构建一个自由交通工具的代码段,包括四轮,n轮,无论驱动的三种类型的汽车。
WheeledVehicle::WheeledVehicle(const SpawnParams& params)
: RigidBody(params)
{
_useCCD = 1;
}
上述代码是WheeledVehicle的构造函数,继承自刚体。
WheeledVehicle::DriveTypes WheeledVehicle::GetDriveType() const
{
return _driveType;
}
void WheeledVehicle::SetDriveType(DriveTypes value)
{
if (_driveType == value)
return;
_driveType = value;
Setup();
}
const Array<WheeledVehicle::Wheel>& WheeledVehicle::GetWheels() const
{
return _wheels;
}
void WheeledVehicle::SetWheels(const Array<Wheel>& value)
{
_wheels = value;
Setup();
}
WheeledVehicle::EngineSettings WheeledVehicle::GetEngine() const
{
return _engine;
}
void WheeledVehicle::SetEngine(const EngineSettings& value)
{
_engine = value;
}
WheeledVehicle::DifferentialSettings WheeledVehicle::GetDifferential() const
{
return _differential;
}
void WheeledVehicle::SetDifferential(const DifferentialSettings& value)
{
_differential = value;
}
WheeledVehicle::GearboxSettings WheeledVehicle::GetGearbox() const
{
return _gearbox;
}
void WheeledVehicle::SetGearbox(const GearboxSettings& value)
上述代码是WheeledVehicle.h头文件中定义的变量的get和set方法。
包括:1:载具类型 2:车轮数量 3:汽车引擎 4:齿轮 5:不同种类
void WheeledVehicle::SetThrottle(float value)
{
_throttle = Math::Clamp(value, -1.0f, 1.0f);
}
void WheeledVehicle::SetSteering(float value)
{
_steering = Math::Clamp(value, -1.0f, 1.0f);
}
void WheeledVehicle::SetBrake(float value)
{
_brake = Math::Saturate(value);
}
void WheeledVehicle::SetHandbrake(float value)
{
_handBrake = Math::Saturate(value);
}
void WheeledVehicle::ClearInput()
{
_throttle = 0;
_steering = 0;
_brake = 0;
_handBrake = 0;
}
float WheeledVehicle::GetForwardSpeed() const
{
#if WITH_VEHICLE
auto& drive = (const PxVehicleWheels*&)_drive;
return drive ? drive->computeForwardSpeed() : 0.0f;
#else
return 0.0f;
#endif
}
float WheeledVehicle::GetSidewaysSpeed() const
{
#if WITH_VEHICLE
auto& drive = (const PxVehicleWheels*&)_drive;
return drive ? drive->computeSidewaysSpeed() : 0.0f;
#else
return 0.0f;
#endif
}
float WheeledVehicle::GetEngineRotationSpeed() const
{
#if WITH_VEHICLE
auto& drive = (const PxVehicleDrive*&)_drive;
return drive && _driveType != DriveTypes::NoDrive ? RadPerSToRpm(drive->mDriveDynData.getEngineRotationSpeed()) : 0.0f;
#else
return 0.0f;
#endif
}
int32 WheeledVehicle::GetCurrentGear() const
{
#if WITH_VEHICLE
auto& drive = (const PxVehicleDrive*&)_drive;
return drive && _driveType != DriveTypes::NoDrive ? (int32)drive->mDriveDynData.getCurrentGear() - 1 : 0;
#else
return 0;
#endif
}
void WheeledVehicle::SetCurrentGear(int32 value)
{
#if WITH_VEHICLE
auto& drive = (PxVehicleDrive*&)_drive;
if (drive && _driveType != DriveTypes::NoDrive)
{
drive->mDriveDynData.forceGearChange((PxU32)(value + 1));
}
#endif
}
int32 WheeledVehicle::GetTargetGear() const
{
#if WITH_VEHICLE
auto& drive = (const PxVehicleDrive*&)_drive;
return drive && _driveType != DriveTypes::NoDrive ? (int32)drive->mDriveDynData.getTargetGear() - 1 : 0;
#else
return 0;
#endif
}
void WheeledVehicle::SetTargetGear(int32 value)
{
#if WITH_VEHICLE
auto& drive = (PxVehicleDrive*&)_drive;
if (drive && _driveType != DriveTypes::NoDrive)
{
drive->mDriveDynData.startGearChange((PxU32)(value + 1));
}
#endif
}
void WheeledVehicle::GetWheelState(int32 index, WheelState& result)
{
if (index >= 0 && index < _wheels.Count())
{
const auto collider = _wheels[index].Collider.Get();
for (auto& wheelData : _wheelsData)
{
if (wheelData.Collider == collider)
{
result = wheelData.State;
return;
}
}
}
}
上述代码代码还是WheeledVehicle.h头文件中定义的变量的get和set方法。
包括变量1:油门 2:刹车 3:手刹 4:前进速度 5:横向速度 6:发动机转速 7:电流齿轮 8:靶机 这8个变量的get和set方法。
下面的WheeledVehicle载具的set up设置的源代码:
if (drive)
{
WheelVehicles.Remove(this);
FreeDrive(_driveTypeCurrent, drive);
drive = nullptr;
}
首先判断drive有没有存在的。如果有的删去,新创建一个自由汽车。
Array<Wheel*, FixedAllocation<PX_MAX_NB_WHEELS>> wheels;
_wheelsData.Clear();
for (auto& wheel : _wheels)
{
if (!wheel.Collider)
{
LOG(Warning, "Missing wheel collider in vehicle {0}", ToString());
continue;
}
if (wheel.Collider->GetParent() != this)
{
LOG(Warning, "Invalid wheel collider {1} in vehicle {0} attached to {2} (wheels needs to be added as children to vehicle)", ToString(), wheel.Collider->ToString(), wheel.Collider->GetParent() ? wheel.Collider->GetParent()->ToString() : String::Empty);
continue;
}
if (wheel.Collider->GetIsTrigger())
{
LOG(Warning, "Invalid wheel collider {1} in vehicle {0} cannot be a trigger", ToString(), wheel.Collider->ToString());
continue;
}
if (wheel.Collider->IsDuringPlay())
{
wheels.Add(&wheel);
}
}
if (wheels.IsEmpty())
{
// No wheel, no car
// No woman, no cry
return;
}
_wheelsData.Resize(wheels.Count());
其次是初始化车轮,添加一个自动轮胎。
1:判断是否有车轮连接装置:如果没有的话发出警告
2:判断车轮联动装置:如果没有的话发出警告
3:判断联机装置:添加车轮联动装置。
Array<PxShape*, InlinedAllocation<8>> shapes;
shapes.Resize(_actor->getNbShapes());
_actor->getShapes(shapes.Get(), shapes.Count(), 0);
const PxTransform centerOfMassOffset = _actor->getCMassLocalPose();
上述代码是获取轮子贴图的链接形状
PxVec3 offsets[PX_MAX_NB_WHEELS];
for (int32 i = 0; i < wheels.Count(); i++)
{
Wheel& wheel = *wheels[i];
offsets[i] = C2P(wheel.Collider->GetLocalPosition());
}
PxF32 sprungMasses[PX_MAX_NB_WHEELS];
const float mass = _actor->getMass();
PxVehicleComputeSprungMasses(wheels.Count(), offsets, centerOfMassOffset.p, mass, 1, sprungMasses);
PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(wheels.Count());
上述代码是初始化车轮模拟数据
PxFilterData filter = wheelShape->getQueryFilterData();
filter.word3 = _id.D + 1;
wheelShape->setQueryFilterData(filter);
wheelShape->setSimulationFilterData(filter);
wheelsSimData->setSceneQueryFilterData(i, filter);
上述代码是在word3内设置车辆ID,以便悬架光线投射忽略自身。
wheelShape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
上述代码从模拟中拆下车轮(悬架力保持车辆)
_driveTypeCurrent = _driveType;
switch (_driveType)
{
case DriveTypes::Drive4W:
{
PxVehicleDriveSimData4W driveSimData;
// Differential
PxVehicleDifferential4WData diff;
diff.mType = (PxVehicleDifferential4WData::Enum)_differential.Type;
diff.mFrontRearSplit = _differential.FrontRearSplit;
diff.mFrontLeftRightSplit = _differential.FrontLeftRightSplit;
diff.mRearLeftRightSplit = _differential.RearLeftRightSplit;
diff.mCentreBias = _differential.CentreBias;
diff.mFrontBias = _differential.FrontBias;
diff.mRearBias = _differential.RearBias;
driveSimData.setDiffData(diff);
// Engine
PxVehicleEngineData engine;
engine.mMOI = M2ToCm2(_engine.MOI);
engine.mPeakTorque = M2ToCm2(_engine.MaxTorque);
engine.mMaxOmega = RpmToRadPerS(_engine.MaxRotationSpeed);
engine.mDampingRateFullThrottle = M2ToCm2(0.15f);
engine.mDampingRateZeroThrottleClutchEngaged = M2ToCm2(2.0f);
engine.mDampingRateZeroThrottleClutchDisengaged = M2ToCm2(0.35f);
driveSimData.setEngineData(engine);
// Gears
PxVehicleGearsData gears;
gears.mSwitchTime = Math::Max(_gearbox.SwitchTime, 0.0f);
driveSimData.setGearsData(gears);
// Auto Box
PxVehicleAutoBoxData autoBox;
driveSimData.setAutoBoxData(autoBox);
// Clutch
PxVehicleClutchData clutch;
clutch.mStrength = M2ToCm2(_gearbox.ClutchStrength);
driveSimData.setClutchData(clutch);
// Ackermann steer accuracy
PxVehicleAckermannGeometryData ackermann;
ackermann.mAxleSeparation = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x);
ackermann.mFrontWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_RIGHT).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).z);
ackermann.mRearWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_RIGHT).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).z);
driveSimData.setAckermannGeometryData(ackermann);
// Create vehicle drive
auto drive4W = PxVehicleDrive4W::allocate(wheels.Count());
drive4W->setup(CPhysX, _actor, *wheelsSimData, driveSimData, Math::Max(wheels.Count() - 4, 0));
drive4W->setToRestState();
drive4W->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
drive4W->mDriveDynData.setUseAutoGears(_gearbox.AutoGear);
drive = drive4W;
break;
}
上述代码是初始化载具。
|