Projekt_Grafika/dependencies/physx-4.1/source/physxvehicle/src/PxVehicleDrive.cpp

215 lines
10 KiB
C++

//
// 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-2019 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#include "vehicle/PxVehicleDrive.h"
#include "vehicle/PxVehicleSDK.h"
#include "PxRigidDynamic.h"
#include "PxVehicleDefaults.h"
#include "PsFoundation.h"
#include "PsUtilities.h"
#include "CmPhysXCommon.h"
namespace physx
{
bool PxVehicleDriveSimData::isValid() const
{
PX_CHECK_AND_RETURN_VAL(mEngine.isValid(), "Invalid PxVehicleCoreSimulationData.mEngine", false);
PX_CHECK_AND_RETURN_VAL(mGears.isValid(), "Invalid PxVehicleCoreSimulationData.mGears", false);
PX_CHECK_AND_RETURN_VAL(mClutch.isValid(), "Invalid PxVehicleCoreSimulationData.mClutch", false);
PX_CHECK_AND_RETURN_VAL(mAutoBox.isValid(), "Invalid PxVehicleCoreSimulationData.mAutoBox", false);
return true;
}
void PxVehicleDriveSimData::setEngineData(const PxVehicleEngineData& engine)
{
PX_CHECK_AND_RETURN(engine.mTorqueCurve.getNbDataPairs()>0, "Engine torque curve must specify at least one entry");
PX_CHECK_AND_RETURN(engine.mPeakTorque>0, "Engine peak torque must be greater than zero");
PX_CHECK_AND_RETURN(engine.mMaxOmega>0, "Engine max omega must be greater than zero");
PX_CHECK_AND_RETURN(engine.mDampingRateFullThrottle>=0, "Full throttle damping rate must be greater than or equal to zero");
PX_CHECK_AND_RETURN(engine.mDampingRateZeroThrottleClutchEngaged>=0, "Zero throttle clutch engaged damping rate must be greater than or equal to zero");
PX_CHECK_AND_RETURN(engine.mDampingRateZeroThrottleClutchDisengaged>=0, "Zero throttle clutch disengaged damping rate must be greater than or equal to zero");
mEngine=engine;
mEngine.mRecipMOI=1.0f/engine.mMOI;
mEngine.mRecipMaxOmega=1.0f/engine.mMaxOmega;
}
void PxVehicleDriveSimData::setGearsData(const PxVehicleGearsData& gears)
{
PX_CHECK_AND_RETURN(gears.mRatios[PxVehicleGearsData::eREVERSE]<0, "Reverse gear ratio must be negative");
PX_CHECK_AND_RETURN(gears.mRatios[PxVehicleGearsData::eNEUTRAL]==0, "Neutral gear ratio must be zero");
PX_CHECK_AND_RETURN(gears.mRatios[PxVehicleGearsData::eFIRST]>0, "First gear ratio must be positive");
PX_CHECK_AND_RETURN(PxVehicleGearsData::eSECOND>=gears.mNbRatios || (gears.mRatios[PxVehicleGearsData::eSECOND]>0 && gears.mRatios[PxVehicleGearsData::eSECOND] < gears.mRatios[PxVehicleGearsData::eFIRST]), "Second gear ratio must be positive and less than first gear ratio");
PX_CHECK_AND_RETURN(PxVehicleGearsData::eTHIRD>=gears.mNbRatios || (gears.mRatios[PxVehicleGearsData::eTHIRD]>0 && gears.mRatios[PxVehicleGearsData::eTHIRD] < gears.mRatios[PxVehicleGearsData::eSECOND]), "Third gear ratio must be positive and less than second gear ratio");
PX_CHECK_AND_RETURN(PxVehicleGearsData::eFOURTH>=gears.mNbRatios || (gears.mRatios[PxVehicleGearsData::eFOURTH]>0 && gears.mRatios[PxVehicleGearsData::eFOURTH] < gears.mRatios[PxVehicleGearsData::eTHIRD]), "Fourth gear ratio must be positive and less than third gear ratio");
PX_CHECK_AND_RETURN(PxVehicleGearsData::eFIFTH>=gears.mNbRatios || (gears.mRatios[PxVehicleGearsData::eFIFTH]>0 && gears.mRatios[PxVehicleGearsData::eFIFTH] < gears.mRatios[PxVehicleGearsData::eFOURTH]), "Fifth gear ratio must be positive and less than fourth gear ratio");
PX_CHECK_AND_RETURN(PxVehicleGearsData::eSIXTH>=gears.mNbRatios || (gears.mRatios[PxVehicleGearsData::eSIXTH]>0 && gears.mRatios[PxVehicleGearsData::eSIXTH] < gears.mRatios[PxVehicleGearsData::eFIFTH]), "Sixth gear ratio must be positive and less than fifth gear ratio");
PX_CHECK_AND_RETURN(gears.mFinalRatio>0, "Final gear ratio must be greater than zero");
PX_CHECK_AND_RETURN(gears.mNbRatios>=3, "Number of gear ratios must be at least 3 - we need at least reverse, neutral, and a forward gear");
mGears=gears;
}
void PxVehicleDriveSimData::setClutchData(const PxVehicleClutchData& clutch)
{
PX_CHECK_AND_RETURN(clutch.mStrength>0, "Clutch strength must be greater than zero");
PX_CHECK_AND_RETURN(PxVehicleClutchAccuracyMode::eBEST_POSSIBLE==clutch.mAccuracyMode || clutch.mEstimateIterations > 0, "Clutch mEstimateIterations must be greater than zero in eESTIMATE mode.");
mClutch=clutch;
}
void PxVehicleDriveSimData::setAutoBoxData(const PxVehicleAutoBoxData& autobox)
{
PX_CHECK_AND_RETURN(autobox.mUpRatios[PxVehicleGearsData::eREVERSE]>=0, "Autobox gearup ratio in reverse must be greater than or equal to zero");
PX_CHECK_AND_RETURN(autobox.mUpRatios[PxVehicleGearsData::eNEUTRAL]>=0, "Autobox gearup ratio in neutral must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mUpRatios[PxVehicleGearsData::eFIRST]>=0, "Autobox gearup ratio in first must be greater than or equal to zero");
PX_CHECK_AND_RETURN(autobox.mUpRatios[PxVehicleGearsData::eSECOND]>=0, "Autobox gearup ratio in second must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mUpRatios[PxVehicleGearsData::eTHIRD]>=0, "Autobox gearup ratio in third must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mUpRatios[PxVehicleGearsData::eFOURTH]>=0, "Autobox gearup ratio in fourth must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mUpRatios[PxVehicleGearsData::eFIFTH]>=0, "Autobox gearup ratio in fifth must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mDownRatios[PxVehicleGearsData::eREVERSE]>=0, "Autobox geardown ratio in reverse must be greater than or equal to zero");
PX_CHECK_AND_RETURN(autobox.mDownRatios[PxVehicleGearsData::eNEUTRAL]>=0, "Autobox geardown ratio in neutral must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mDownRatios[PxVehicleGearsData::eFIRST]>=0, "Autobox geardown ratio in first must be greater than or equal to zero");
PX_CHECK_AND_RETURN(autobox.mDownRatios[PxVehicleGearsData::eSECOND]>=0, "Autobox geardown ratio in second must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mDownRatios[PxVehicleGearsData::eTHIRD]>=0, "Autobox geardown ratio in third must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mDownRatios[PxVehicleGearsData::eFOURTH]>=0, "Autobox geardown ratio in fourth must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mDownRatios[PxVehicleGearsData::eFIFTH]>=0, "Autobox geardown ratio in fifth must be greater than zero");
PX_CHECK_AND_RETURN(autobox.mDownRatios[PxVehicleGearsData::eSIXTH]>=0, "Autobox geardown ratio in fifth must be greater than zero");
mAutoBox=autobox;
}
///////////////////////////////////
PxVehicleDriveDynData::PxVehicleDriveDynData()
: mUseAutoGears(false),
mGearUpPressed(false),
mGearDownPressed(false),
mCurrentGear(PxVehicleGearsData::eNEUTRAL),
mTargetGear(PxVehicleGearsData::eNEUTRAL),
mEnginespeed(0.0f),
mGearSwitchTime(0.0f),
mAutoBoxSwitchTime(0.0f)
{
for(PxU32 i=0;i<eMAX_NB_ANALOG_INPUTS;i++)
{
mControlAnalogVals[i]=0.0f;
}
}
void PxVehicleDriveDynData::setToRestState()
{
//Set analog inputs to zero so the vehicle starts completely at rest.
for(PxU32 i=0;i<eMAX_NB_ANALOG_INPUTS;i++)
{
mControlAnalogVals[i]=0.0f;
}
mGearUpPressed=false;
mGearDownPressed=false;
//Set the vehicle to neutral gear.
mCurrentGear=PxVehicleGearsData::eNEUTRAL;
mTargetGear=PxVehicleGearsData::eNEUTRAL;
mGearSwitchTime=0.0f;
mAutoBoxSwitchTime=0.0f;
//Set internal dynamics to zero so the vehicle starts completely at rest.
mEnginespeed=0.0f;
}
bool PxVehicleDriveDynData::isValid() const
{
return true;
}
void PxVehicleDriveDynData::setAnalogInput(const PxU32 type, const PxReal analogVal)
{
PX_CHECK_AND_RETURN(analogVal>=-1.01f && analogVal<=1.01f, "PxVehicleDriveDynData::setAnalogInput - analogVal must be in range (-1,1)");
PX_CHECK_AND_RETURN(type<eMAX_NB_ANALOG_INPUTS, "PxVehicleDriveDynData::setAnalogInput - illegal type");
mControlAnalogVals[type]=analogVal;
}
PxReal PxVehicleDriveDynData::getAnalogInput(const PxU32 type) const
{
PX_CHECK_AND_RETURN_VAL(type<eMAX_NB_ANALOG_INPUTS, "PxVehicleDriveDynData::getAnalogInput - illegal type", 0.0f);
return mControlAnalogVals[type];
}
///////////////////////////////////
bool PxVehicleDrive::isValid() const
{
PX_CHECK_AND_RETURN_VAL(PxVehicleWheels::isValid(), "invalid PxVehicleWheels", false);
PX_CHECK_AND_RETURN_VAL(mDriveDynData.isValid(), "Invalid PxVehicleDrive.mCoreSimData", false);
return true;
}
PxU32 PxVehicleDrive::computeByteSize(const PxU32 numWheels)
{
return PxVehicleWheels::computeByteSize(numWheels);
}
PxU8* PxVehicleDrive::patchupPointers( const PxU32 numWheels, PxVehicleDrive* veh, PxU8* ptr)
{
return PxVehicleWheels::patchupPointers(numWheels, veh, ptr);
}
void PxVehicleDrive::init(const PxU32 numWheels)
{
PxVehicleWheels::init(numWheels);
}
void PxVehicleDrive::free()
{
PxVehicleWheels::free();
}
void PxVehicleDrive::setup
(PxPhysics* physics, PxRigidDynamic* vehActor,
const PxVehicleWheelsSimData& wheelsData,
const PxU32 numDrivenWheels, const PxU32 numNonDrivenWheels)
{
//Set up the wheels.
PxVehicleWheels::setup(physics,vehActor,wheelsData,numDrivenWheels,numNonDrivenWheels);
}
void PxVehicleDrive::setToRestState()
{
//Set core to rest state.
PxVehicleWheels::setToRestState();
//Set dynamics data to rest state.
mDriveDynData.setToRestState();
}
} //namespace physx