// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of NVIDIA CORPORATION nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #pragma once #include "vehicle2/PxVehicleAPI.h" #include "../physxintegration/PhysXIntegration.h" namespace snippetvehicle { using namespace physx; using namespace physx::vehicle2; struct EngineDrivetrainParams { PxVehicleAutoboxParams autoboxParams; PxVehicleClutchCommandResponseParams clutchCommandResponseParams; PxVehicleEngineParams engineParams; PxVehicleGearboxParams gearBoxParams; PxVehicleMultiWheelDriveDifferentialParams multiWheelDifferentialParams; PxVehicleFourWheelDriveDifferentialParams fourWheelDifferentialParams; PxVehicleTankDriveDifferentialParams tankDifferentialParams; PxVehicleClutchParams clutchParams; EngineDrivetrainParams transformAndScale( const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const; PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const { if (!autoboxParams.isValid(gearBoxParams)) return false; if (!clutchCommandResponseParams.isValid()) return false; if (!engineParams.isValid()) return false; if (!gearBoxParams.isValid()) return false; if (!multiWheelDifferentialParams.isValid(axleDesc)) return false; if (!fourWheelDifferentialParams.isValid(axleDesc)) return false; if (!tankDifferentialParams.isValid(axleDesc)) return false; if (!clutchParams.isValid()) return false; return true; } }; struct EngineDrivetrainState { PxVehicleEngineDriveThrottleCommandResponseState throttleCommandResponseState; PxVehicleAutoboxState autoboxState; PxVehicleClutchCommandResponseState clutchCommandResponseState; PxVehicleDifferentialState differentialState; PxVehicleWheelConstraintGroupState wheelConstraintGroupState; PxVehicleEngineState engineState; PxVehicleGearboxState gearboxState; PxVehicleClutchSlipState clutchState; PX_FORCE_INLINE void setToDefault() { throttleCommandResponseState.setToDefault(); autoboxState.setToDefault(); clutchCommandResponseState.setToDefault(); differentialState.setToDefault(); wheelConstraintGroupState.setToDefault(); engineState.setToDefault(); gearboxState.setToDefault(); clutchState.setToDefault(); } }; // //This class holds the parameters, state and logic needed to implement a vehicle that //is using an engine drivetrain with gears, clutch etc. // //See BaseVehicle for more details on the snippet code design. // class EngineDriveVehicle : public PhysXActorVehicle , public PxVehicleEngineDriveCommandResponseComponent , public PxVehicleFourWheelDriveDifferentialStateComponent , public PxVehicleMultiWheelDriveDifferentialStateComponent , public PxVehicleTankDriveDifferentialStateComponent , public PxVehicleEngineDriveActuationStateComponent , public PxVehicleEngineDrivetrainComponent { public: enum Enum { eDIFFTYPE_FOURWHEELDRIVE, eDIFFTYPE_MULTIWHEELDRIVE, eDIFFTYPE_TANKDRIVE }; bool initialize(PxPhysics& physics, const PxCookingParams& params, PxMaterial& defaultMaterial, Enum differentialType, bool addPhysXBeginEndComponents=true); virtual void destroy(); virtual void initComponentSequence(bool addPhysXBeginEndComponents); virtual void getDataForPhysXActorBeginComponent( const PxVehicleAxleDescription*& axleDescription, const PxVehicleCommandState*& commands, const PxVehicleEngineDriveTransmissionCommandState*& transmissionCommands, const PxVehicleGearboxParams*& gearParams, const PxVehicleGearboxState*& gearState, const PxVehicleEngineParams*& engineParams, PxVehiclePhysXActor*& physxActor, PxVehiclePhysXSteerState*& physxSteerState, PxVehiclePhysXConstraints*& physxConstraints, PxVehicleRigidBodyState*& rigidBodyState, PxVehicleArrayData& wheelRigidBody1dStates, PxVehicleEngineState*& engineState) { axleDescription = &mBaseParams.axleDescription; commands = &mCommandState; physxActor = &mPhysXState.physxActor; physxSteerState = &mPhysXState.physxSteerState; physxConstraints = &mPhysXState.physxConstraints; rigidBodyState = &mBaseState.rigidBodyState; wheelRigidBody1dStates.setData(mBaseState.wheelRigidBody1dStates); transmissionCommands = &mTransmissionCommandState; gearParams = &mEngineDriveParams.gearBoxParams; gearState = &mEngineDriveState.gearboxState; engineParams = &mEngineDriveParams.engineParams; engineState = &mEngineDriveState.engineState; } virtual void getDataForPhysXActorEndComponent( const PxVehicleAxleDescription*& axleDescription, const PxVehicleRigidBodyState*& rigidBodyState, PxVehicleArrayData& wheelParams, PxVehicleArrayData& wheelShapeLocalPoses, PxVehicleArrayData& wheelRigidBody1dStates, PxVehicleArrayData& wheelLocalPoses, const PxVehicleGearboxState*& gearState, const PxReal*& throttle, PxVehiclePhysXActor*& physxActor) { axleDescription = &mBaseParams.axleDescription; rigidBodyState = &mBaseState.rigidBodyState; wheelParams.setData(mBaseParams.wheelParams); wheelShapeLocalPoses.setData(mPhysXParams.physxWheelShapeLocalPoses); wheelRigidBody1dStates.setData(mBaseState.wheelRigidBody1dStates); wheelLocalPoses.setData(mBaseState.wheelLocalPoses); physxActor = &mPhysXState.physxActor; gearState = &mEngineDriveState.gearboxState; throttle = &mCommandState.throttle; } virtual void getDataForEngineDriveCommandResponseComponent( const PxVehicleAxleDescription*& axleDescription, PxVehicleSizedArrayData& brakeResponseParams, const PxVehicleSteerCommandResponseParams*& steerResponseParams, PxVehicleSizedArrayData& ackermannParams, const PxVehicleGearboxParams*& gearboxParams, const PxVehicleClutchCommandResponseParams*& clutchResponseParams, const PxVehicleEngineParams*& engineParams, const PxVehicleRigidBodyState*& rigidBodyState, const PxVehicleEngineState*& engineState, const PxVehicleAutoboxParams*& autoboxParams, const PxVehicleCommandState*& commands, const PxVehicleEngineDriveTransmissionCommandState*& transmissionCommands, PxVehicleArrayData& brakeResponseStates, PxVehicleEngineDriveThrottleCommandResponseState*& throttleResponseState, PxVehicleArrayData& steerResponseStates, PxVehicleGearboxState*& gearboxResponseState, PxVehicleClutchCommandResponseState*& clutchResponseState, PxVehicleAutoboxState*& autoboxState) { axleDescription = &mBaseParams.axleDescription; brakeResponseParams.setDataAndCount(mBaseParams.brakeResponseParams, sizeof(mBaseParams.brakeResponseParams) / sizeof(PxVehicleBrakeCommandResponseParams)); steerResponseParams = &mBaseParams.steerResponseParams; ackermannParams.setDataAndCount(mBaseParams.ackermannParams, sizeof(mBaseParams.ackermannParams)/sizeof(PxVehicleAckermannParams)); gearboxParams = &mEngineDriveParams.gearBoxParams; clutchResponseParams = &mEngineDriveParams.clutchCommandResponseParams; engineParams = &mEngineDriveParams.engineParams; rigidBodyState = &mBaseState.rigidBodyState; engineState = &mEngineDriveState.engineState; autoboxParams = &mEngineDriveParams.autoboxParams; commands = &mCommandState; transmissionCommands = (Enum::eDIFFTYPE_TANKDRIVE == mDifferentialType) ? &mTankDriveTransmissionCommandState : &mTransmissionCommandState; brakeResponseStates.setData(mBaseState.brakeCommandResponseStates); throttleResponseState = &mEngineDriveState.throttleCommandResponseState; steerResponseStates.setData(mBaseState.steerCommandResponseStates); gearboxResponseState = &mEngineDriveState.gearboxState; clutchResponseState = &mEngineDriveState.clutchCommandResponseState; autoboxState = &mEngineDriveState.autoboxState; } virtual void getDataForFourWheelDriveDifferentialStateComponent( const PxVehicleAxleDescription*& axleDescription, const PxVehicleFourWheelDriveDifferentialParams*& differentialParams, PxVehicleArrayData& wheelRigidbody1dStates, PxVehicleDifferentialState*& differentialState, PxVehicleWheelConstraintGroupState*& wheelConstraintGroups) { axleDescription = &mBaseParams.axleDescription; differentialParams = &mEngineDriveParams.fourWheelDifferentialParams; wheelRigidbody1dStates.setData(mBaseState.wheelRigidBody1dStates); differentialState = &mEngineDriveState.differentialState; wheelConstraintGroups = &mEngineDriveState.wheelConstraintGroupState; } virtual void getDataForMultiWheelDriveDifferentialStateComponent( const PxVehicleAxleDescription*& axleDescription, const PxVehicleMultiWheelDriveDifferentialParams*& differentialParams, PxVehicleDifferentialState*& differentialState) { axleDescription = &mBaseParams.axleDescription; differentialParams = &mEngineDriveParams.multiWheelDifferentialParams; differentialState = &mEngineDriveState.differentialState; } virtual void getDataForTankDriveDifferentialStateComponent( const PxVehicleAxleDescription *&axleDescription, const PxVehicleTankDriveTransmissionCommandState*& tankDriveTransmissionCommands, PxVehicleArrayData& wheelParams, const PxVehicleTankDriveDifferentialParams *& differentialParams, PxVehicleDifferentialState *& differentialState, PxVehicleWheelConstraintGroupState*& wheelConstraintGroups) { axleDescription = &mBaseParams.axleDescription; tankDriveTransmissionCommands = &mTankDriveTransmissionCommandState; wheelParams.setData(mBaseParams.wheelParams); differentialParams = &mEngineDriveParams.tankDifferentialParams; differentialState = &mEngineDriveState.differentialState; wheelConstraintGroups = &mEngineDriveState.wheelConstraintGroupState; } virtual void getDataForEngineDriveActuationStateComponent( const PxVehicleAxleDescription*& axleDescription, const PxVehicleGearboxParams*& gearboxParams, PxVehicleArrayData& brakeResponseStates, const PxVehicleEngineDriveThrottleCommandResponseState*& throttleResponseState, const PxVehicleGearboxState*& gearboxState, const PxVehicleDifferentialState*& differentialState, const PxVehicleClutchCommandResponseState*& clutchResponseState, PxVehicleArrayData& actuationStates) { axleDescription = &mBaseParams.axleDescription; gearboxParams = &mEngineDriveParams.gearBoxParams; brakeResponseStates.setData(mBaseState.brakeCommandResponseStates); throttleResponseState = &mEngineDriveState.throttleCommandResponseState; gearboxState = &mEngineDriveState.gearboxState; differentialState = &mEngineDriveState.differentialState; clutchResponseState = &mEngineDriveState.clutchCommandResponseState; actuationStates.setData(mBaseState.actuationStates); } virtual void getDataForEngineDrivetrainComponent( const PxVehicleAxleDescription*& axleDescription, PxVehicleArrayData& wheelParams, const PxVehicleEngineParams*& engineParams, const PxVehicleClutchParams*& clutchParams, const PxVehicleGearboxParams*& gearboxParams, PxVehicleArrayData& brakeResponseStates, PxVehicleArrayData& actuationStates, PxVehicleArrayData& tireForces, const PxVehicleEngineDriveThrottleCommandResponseState*& throttleResponseState, const PxVehicleClutchCommandResponseState*& clutchResponseState, const PxVehicleDifferentialState*& differentialState, const PxVehicleWheelConstraintGroupState*& constraintGroupState, PxVehicleArrayData& wheelRigidBody1dStates, PxVehicleEngineState*& engineState, PxVehicleGearboxState*& gearboxState, PxVehicleClutchSlipState*& clutchState) { axleDescription = &mBaseParams.axleDescription; wheelParams.setData(mBaseParams.wheelParams); engineParams = &mEngineDriveParams.engineParams; clutchParams = &mEngineDriveParams.clutchParams; gearboxParams = &mEngineDriveParams.gearBoxParams; brakeResponseStates.setData(mBaseState.brakeCommandResponseStates); actuationStates.setData(mBaseState.actuationStates); tireForces.setData(mBaseState.tireForces); throttleResponseState = &mEngineDriveState.throttleCommandResponseState; clutchResponseState = &mEngineDriveState.clutchCommandResponseState; differentialState = &mEngineDriveState.differentialState; constraintGroupState = Enum::eDIFFTYPE_TANKDRIVE == mDifferentialType ? &mEngineDriveState.wheelConstraintGroupState : NULL; wheelRigidBody1dStates.setData(mBaseState.wheelRigidBody1dStates); engineState = &mEngineDriveState.engineState; gearboxState = &mEngineDriveState.gearboxState; clutchState = &mEngineDriveState.clutchState; } //Parameters and states of the vehicle's engine drivetrain. EngineDrivetrainParams mEngineDriveParams; EngineDrivetrainState mEngineDriveState; //The commands that will control the vehicle's transmission PxVehicleEngineDriveTransmissionCommandState mTransmissionCommandState; PxVehicleTankDriveTransmissionCommandState mTankDriveTransmissionCommandState; //The type of differential that will be used. //If eDIFFTYPE_TANKDRIVE is chosen then the vehicle's transmission //commands are stored in mTankDriveTransmissionCommandState. //If eDIFFTYPE_FOURWHEELDRIVE or eDIFFTYPE_MULTIWHEELDRIVE is chosen //then the vehicle's transmission commands are stored in //mTransmissionCommandState Enum mDifferentialType; }; }//namespace snippetvehicle