Revision control

- //
- // 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-2021 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/PxVehicleWheels.h"
- #include "PxRigidDynamic.h"
- #include "PxShape.h"
- #include "PxPhysics.h"
-
- #include "PxVehicleSuspWheelTire4.h"
- #include "PxVehicleSuspLimitConstraintShader.h"
- #include "PxVehicleDefaults.h"
- #include "CmPhysXCommon.h"
- #include "CmBitMap.h"
- #include "PsUtilities.h"
- #include "PsIntrinsics.h"
- #include "PsFoundation.h"
-
- namespace physx
- {
-
- extern PxVec3 gRight;
- extern PxVec3 gUp;
- extern PxVec3 gForward;
-
- PxF32 gThresholdLongSpeed=5.0f;
- PxU32 gLowLongSpeedSubstepCount=3;
- PxU32 gHighLongSpeedSubstepCount=1;
- PxF32 gMinLongSlipDenominator=4.0f;
-
- extern PxF32 gToleranceScaleLength;
-
-
- PxU32 PxVehicleWheelsSimData::computeByteSize(const PxU32 numWheels)
- {
- const PxU32 numWheels4 =(((numWheels + 3) & ~3) >> 2);
- const PxU32 byteSize = sizeof(PxVehicleWheels4SimData)*numWheels4 + sizeof(PxVehicleAntiRollBarData)*2*numWheels4;
- return byteSize;
- }
-
- PxU8* PxVehicleWheelsSimData::patchUpPointers(const PxU32 numWheels, PxVehicleWheelsSimData* simData, PxU8* ptrIn)
- {
- const PxU32 numWheels4 =(((numWheels + 3) & ~3) >> 2);
- PxU8* ptr = ptrIn;
- simData->mWheels4SimData = reinterpret_cast<PxVehicleWheels4SimData*>(ptr);
- ptr += sizeof(PxVehicleWheels4SimData)*numWheels4;
- simData->mAntiRollBars = reinterpret_cast<PxVehicleAntiRollBarData*>(ptr);
- ptr += sizeof(PxVehicleAntiRollBarData)*numWheels4*2;
- PX_ASSERT((ptrIn + computeByteSize(numWheels)) == ptr);
- return ptr;
- }
-
- PxVehicleWheelsSimData::PxVehicleWheelsSimData(const PxU32 numWheels)
- {
- const PxU32 numWheels4 =(((numWheels + 3) & ~3) >> 2);
-
- //Set numWheels
- mNbWheels4 = numWheels4;
- mNbActiveWheels = numWheels;
-
- //Set numAntiRollBars to zero.
- mNbAntiRollBars4 = 2*numWheels4;
- mNbActiveAntiRollBars = 0;
-
- //Placement new for wheels4
- for(PxU32 i=0;i<numWheels4;i++)
- {
- new(&mWheels4SimData[i]) PxVehicleWheels4SimData();
- }
-
- //Placement new for anti-roll bars
- for(PxU32 i=0;i<numWheels4*2;i++)
- {
- new(&mAntiRollBars[i]) PxVehicleAntiRollBarData();
- }
-
- //Placement new for tire load filter data.
- new(&mNormalisedLoadFilter) PxVehicleTireLoadFilterData();
-
- //Enable used wheels, disabled unused wheels.
- PxMemZero(mActiveWheelsBitmapBuffer, sizeof(PxU32) * (((PX_MAX_NB_WHEELS + 31) & ~31) >> 5));
- for(PxU32 i=0;i<numWheels;i++)
- {
- //Enabled used wheel.
- enableWheel(i);
- setWheelShapeMapping(i,PxI32(i));
- setSceneQueryFilterData(i, PxFilterData());
- }
- for(PxU32 i=numWheels;i<numWheels4*4;i++)
- {
- //Disable unused wheel.
- disableWheel(i);
- setWheelShapeMapping(i,-1);
- setSceneQueryFilterData(i, PxFilterData());
- }
-
- //Default values for substep count computation.
- mThresholdLongitudinalSpeed = gThresholdLongSpeed*gToleranceScaleLength;
- mLowForwardSpeedSubStepCount = gLowLongSpeedSubstepCount;
- mHighForwardSpeedSubStepCount = gHighLongSpeedSubstepCount;
- mMinLongSlipDenominator = gMinLongSlipDenominator*gToleranceScaleLength;
-
- mFlags = 0;
- }
-
- PxVehicleWheelsSimData* PxVehicleWheelsSimData::allocate(const PxU32 numWheels)
- {
- //Byte size
- const PxU32 byteSize = sizeof(PxVehicleWheelsSimData) + computeByteSize(numWheels);
-
- //Allocate
- PxU8* ptrStart = static_cast<PxU8*>(PX_ALLOC(byteSize, "PxVehicleWheelsSimData"));
-
- //Patchup pointers
- PxU8* ptr = ptrStart;
- PxVehicleWheelsSimData* simData = reinterpret_cast<PxVehicleWheelsSimData*>(ptr);
- ptr += sizeof(PxVehicleWheelsSimData);
- ptr = patchUpPointers(numWheels, simData, ptr);
- PX_ASSERT((ptrStart+ byteSize) == ptr);
-
- //Constructor.
- new(simData) PxVehicleWheelsSimData(numWheels);
-
- //Finished.
- return simData;
- }
-
- void PxVehicleWheelsSimData::setChassisMass(const PxF32 chassisMass)
- {
-
- //Target spring natural frequency = 9.66
- //Target spring damping ratio = 0.62
- const PxF32 mult=1.0f/(1.0f*mNbActiveWheels);
- const PxF32 sprungMass=chassisMass*mult;
- const PxF32 w0=9.66f;
- const PxF32 r=0.62f;
- for(PxU32 i=0;i<mNbActiveWheels;i++)
- {
- PxVehicleSuspensionData susp=getSuspensionData(i);
- susp.mSprungMass=sprungMass;
- susp.mSpringStrength=w0*w0*sprungMass;
- susp.mSpringDamperRate=r*2*sprungMass*w0;
- setSuspensionData(i,susp);
- }
- }
-
- void PxVehicleWheelsSimData::free()
- {
- for(PxU32 i=0;i<mNbWheels4;i++)
- {
- mWheels4SimData[i].~PxVehicleWheels4SimData();
- }
-
- PX_FREE(this);
- }
-
- PxVehicleWheelsSimData& PxVehicleWheelsSimData::operator=(const PxVehicleWheelsSimData& src)
- {
- PX_CHECK_MSG(mNbActiveWheels == src.mNbActiveWheels, "target PxVehicleSuspWheelTireNSimData must match the number of wheels in src");
-
- for(PxU32 i=0;i<src.mNbWheels4;i++)
- {
- mWheels4SimData[i] = src.mWheels4SimData[i];
- }
-
- mNbActiveAntiRollBars = src.mNbActiveAntiRollBars;
- for(PxU32 i=0; i<src.mNbActiveAntiRollBars; i++)
- {
- mAntiRollBars[i] = src.mAntiRollBars[i];
- }
-
- mNormalisedLoadFilter = src.mNormalisedLoadFilter;
-
- mThresholdLongitudinalSpeed = src.mThresholdLongitudinalSpeed;
- mLowForwardSpeedSubStepCount = src.mLowForwardSpeedSubStepCount;
- mHighForwardSpeedSubStepCount = src.mHighForwardSpeedSubStepCount;
- mMinLongSlipDenominator = src.mMinLongSlipDenominator;
-
- mFlags = src.mFlags;
-
- PxMemCopy(mActiveWheelsBitmapBuffer, src.mActiveWheelsBitmapBuffer, sizeof(PxU32)* (((PX_MAX_NB_WHEELS + 31) & ~31) >> 5));
-
- return *this;
- }
-
- void PxVehicleWheelsSimData::copy(const PxVehicleWheelsSimData& src, const PxU32 srcWheel, const PxU32 wheel)
- {
- PX_CHECK_AND_RETURN(srcWheel < src.mNbActiveWheels, "Illegal src wheel");
- PX_CHECK_AND_RETURN(wheel < mNbActiveWheels, "Illegal target wheel");
-
- setSuspensionData(wheel,src.getSuspensionData(srcWheel));
- setWheelData(wheel,src.getWheelData(srcWheel));
- setTireData(wheel,src.getTireData(srcWheel));
- setSuspTravelDirection(wheel,src.getSuspTravelDirection(srcWheel));
- setSuspForceAppPointOffset(wheel,src.getSuspForceAppPointOffset(srcWheel));
- setTireForceAppPointOffset(wheel,src.getTireForceAppPointOffset(srcWheel));
- setWheelCentreOffset(wheel,src.getWheelCentreOffset(srcWheel));
- setWheelShapeMapping(wheel, src.getWheelShapeMapping(srcWheel));
- setSceneQueryFilterData(wheel, src.getSceneQueryFilterData(srcWheel));
- if(src.getIsWheelDisabled(srcWheel))
- disableWheel(wheel);
- else
- enableWheel(wheel);
- }
-
- bool PxVehicleWheelsSimData::isValid() const
- {
- for(PxU32 i=0;i<mNbWheels4-1;i++)
- {
- mWheels4SimData[i].isValid(0);
- mWheels4SimData[i].isValid(1);
- mWheels4SimData[i].isValid(2);
- mWheels4SimData[i].isValid(3);
- }
- const PxU32 numInLastBlock = 4 - (4*mNbWheels4 - mNbActiveWheels);
- for(PxU32 i=0;i<numInLastBlock;i++)
- {
- mWheels4SimData[mNbWheels4-1].isValid(i);
- }
-
- PX_CHECK_AND_RETURN_VAL(mNormalisedLoadFilter.isValid(), "Invalid PxVehicleWheelsSimData.mNormalisedLoadFilter", false);
- return true;
- }
-
- void PxVehicleWheelsSimData::disableWheel(const PxU32 wheel)
- {
- PX_CHECK_AND_RETURN(wheel < 4*mNbWheels4, "PxVehicleWheelsSimData::disableWheel - Illegal wheel");
-
- Cm::BitMap bm;
- bm.setWords(mActiveWheelsBitmapBuffer, ((PX_MAX_NB_WHEELS + 31) & ~31) >> 5);
- bm.reset(wheel);
- }
-
- void PxVehicleWheelsSimData::enableWheel(const PxU32 wheel)
- {
- PX_CHECK_AND_RETURN(wheel < 4*mNbWheels4, "PxVehicleWheelsSimData::disableWheel - Illegal wheel");
-
- Cm::BitMap bm;
- bm.setWords(mActiveWheelsBitmapBuffer, ((PX_MAX_NB_WHEELS + 31) & ~31) >> 5);
- bm.set(wheel);
- }
-
- bool PxVehicleWheelsSimData::getIsWheelDisabled(const PxU32 wheel) const
- {
- PX_CHECK_AND_RETURN_VAL(wheel < 4*mNbWheels4, "PxVehicleWheelsSimData::getIsWheelDisabled - Illegal wheel", false);
- Cm::BitMap bm;
- bm.setWords(const_cast<PxU32*>(mActiveWheelsBitmapBuffer), ((PX_MAX_NB_WHEELS + 31) & ~31) >> 5);
- return (bm.test(wheel) ? false : true);
- }
-
- const PxVehicleSuspensionData& PxVehicleWheelsSimData::getSuspensionData(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getSuspensionData - Illegal wheel");
- return mWheels4SimData[id>>2].getSuspensionData(id & 3);
- }
-
- const PxVehicleWheelData& PxVehicleWheelsSimData::getWheelData(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getWheelData - Illegal wheel");
- return mWheels4SimData[id>>2].getWheelData(id & 3);
- }
-
- const PxVehicleTireData& PxVehicleWheelsSimData::getTireData(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getTireData - Illegal wheel");
- return mWheels4SimData[id>>2].getTireData(id & 3);
- }
-
- const PxVec3& PxVehicleWheelsSimData::getSuspTravelDirection(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getSuspTravelDirection - Illegal wheel");
- return mWheels4SimData[id>>2].getSuspTravelDirection(id & 3);
- }
-
- const PxVec3& PxVehicleWheelsSimData::getSuspForceAppPointOffset(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getSuspForceAppPointOffset - Illegal wheel");
- return mWheels4SimData[id>>2].getSuspForceAppPointOffset(id & 3);
- }
-
- const PxVec3& PxVehicleWheelsSimData::getTireForceAppPointOffset(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getTireForceAppPointOffset - Illegal wheel");
- return mWheels4SimData[id>>2].getTireForceAppPointOffset(id & 3);
- }
-
- const PxVec3& PxVehicleWheelsSimData::getWheelCentreOffset(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getWheelCentreOffset - Illegal wheel");
- return mWheels4SimData[id>>2].getWheelCentreOffset(id & 3);
- }
-
- PxI32 PxVehicleWheelsSimData::getWheelShapeMapping(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getWheelShapeMapping - Illegal wheel");
- return mWheels4SimData[id>>2].getWheelShapeMapping(id & 3);
- }
-
- const PxFilterData& PxVehicleWheelsSimData::getSceneQueryFilterData(const PxU32 id) const
- {
- PX_CHECK_MSG(id < 4*mNbWheels4, "PxVehicleWheelsSimData::getSceneQueryFilterData - Illegal wheel");
- return mWheels4SimData[id>>2].getSceneQueryFilterData(id & 3);
- }
-
- const PxVehicleAntiRollBarData& PxVehicleWheelsSimData::getAntiRollBarData(const PxU32 antiRollId) const
- {
- PX_CHECK_MSG(antiRollId < mNbActiveAntiRollBars, "PxVehicleWheelsSimData::getAntiRollBarData - Illegal anti-roll bar");
- return mAntiRollBars[antiRollId];
- }
-
- void PxVehicleWheelsSimData::setSuspensionData(const PxU32 id, const PxVehicleSuspensionData& susp)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setSuspensionData - Illegal wheel");
- mWheels4SimData[id>>2].setSuspensionData(id & 3, susp);
- }
-
- void PxVehicleWheelsSimData::setWheelData(const PxU32 id, const PxVehicleWheelData& wheel)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setWheelData - Illegal wheel");
- mWheels4SimData[id>>2].setWheelData(id & 3, wheel);
- }
-
- void PxVehicleWheelsSimData::setTireData(const PxU32 id, const PxVehicleTireData& tire)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setTireData - Illegal wheel");
- mWheels4SimData[id>>2].setTireData(id & 3, tire);
- }
-
- void PxVehicleWheelsSimData::setSuspTravelDirection(const PxU32 id, const PxVec3& dir)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setSuspTravelDirection - Illegal wheel");
- mWheels4SimData[id>>2].setSuspTravelDirection(id & 3, dir);
- }
-
- void PxVehicleWheelsSimData::setSuspForceAppPointOffset(const PxU32 id, const PxVec3& offset)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setSuspForceAppPointOffset - Illegal wheel");
- mWheels4SimData[id>>2].setSuspForceAppPointOffset(id & 3, offset);
- }
-
- void PxVehicleWheelsSimData::setTireForceAppPointOffset(const PxU32 id, const PxVec3& offset)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setTireForceAppPointOffset - Illegal wheel");
- mWheels4SimData[id>>2].setTireForceAppPointOffset(id & 3, offset);
- }
-
- void PxVehicleWheelsSimData::setWheelCentreOffset(const PxU32 id, const PxVec3& offset)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setWheelCentreOffset - Illegal wheel");
- mWheels4SimData[id>>2].setWheelCentreOffset(id & 3, offset);
- }
-
- void PxVehicleWheelsSimData::setWheelShapeMapping(const PxU32 id, const PxI32 shapeId)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setWheelShapeMapping - Illegal wheel");
- mWheels4SimData[id>>2].setWheelShapeMapping(id & 3, shapeId);
- }
-
- void PxVehicleWheelsSimData::setSceneQueryFilterData(const PxU32 id, const PxFilterData& sqFilterData)
- {
- PX_CHECK_AND_RETURN(id < 4*mNbWheels4, "PxVehicleWheelsSimData::setSceneQueryFilterData - Illegal wheel");
- mWheels4SimData[id>>2].setSceneQueryFilterData(id & 3, sqFilterData);
- }
-
- void PxVehicleWheelsSimData::setTireLoadFilterData(const PxVehicleTireLoadFilterData& tireLoadFilter)
- {
- PX_CHECK_AND_RETURN(tireLoadFilter.mMaxNormalisedLoad>tireLoadFilter.mMinNormalisedLoad, "Illegal graph points");
- PX_CHECK_AND_RETURN(tireLoadFilter.mMaxFilteredNormalisedLoad>0, "Max filtered load must be greater than zero");
- mNormalisedLoadFilter=tireLoadFilter;
- mNormalisedLoadFilter.mDenominator=1.0f/(mNormalisedLoadFilter.mMaxNormalisedLoad-mNormalisedLoadFilter.mMinNormalisedLoad);
- }
-
- PxU32 PxVehicleWheelsSimData::addAntiRollBarData(const PxVehicleAntiRollBarData& antiRollBar)
- {
- PX_CHECK_AND_RETURN_VAL(antiRollBar.isValid(), "Illegal antiRollBar", 0xffffffff)
- PX_CHECK_AND_RETURN_VAL(antiRollBar.mWheel0 < mNbActiveWheels, "Illegal wheel0", 0xffffffff);
- PX_CHECK_AND_RETURN_VAL(antiRollBar.mWheel1 < mNbActiveWheels, "Illegal wheel1", 0xffffffff);
-
- //If the anti-roll pair already exists then modify it.
- for(PxU32 i = 0; i < mNbActiveAntiRollBars; i++)
- {
- if( ((mAntiRollBars[i].mWheel0 == antiRollBar.mWheel0) && (mAntiRollBars[i].mWheel1 == antiRollBar.mWheel1)) ||
- ((mAntiRollBars[i].mWheel1 == antiRollBar.mWheel0) && (mAntiRollBars[i].mWheel0 == antiRollBar.mWheel1)) )
- {
- mAntiRollBars[i].mStiffness = antiRollBar.mStiffness;
- return i;
- }
- }
-
- //Check we have space for an extra anti-roll bar.
- PX_CHECK_AND_RETURN_VAL(mNbActiveAntiRollBars < 2*mNbWheels4, "The buffer of anti-roll bars is full", 0xffffffff);
-
- //Add a new anti-roll bar.
- const PxU32 id = mNbActiveAntiRollBars;
- mAntiRollBars[mNbActiveAntiRollBars] = antiRollBar;
- mNbActiveAntiRollBars++;
-
- //Finished.
- return id;
- }
-
- //Only used for serialization.
- void PxVehicleWheelsSimData::setAntiRollBarData(const PxU32 id, const PxVehicleAntiRollBarData& antiRoll)
- {
- PX_UNUSED(id);
- addAntiRollBarData(antiRoll);
- }
-
- void PxVehicleWheelsSimData::setSubStepCount(const PxReal thresholdLongitudinalSpeed, const PxU32 lowForwardSpeedSubStepCount, const PxU32 highForwardSpeedSubStepCount)
- {
- PX_CHECK_AND_RETURN(thresholdLongitudinalSpeed>=0, "thresholdLongitudinalSpeed must be greater than or equal to zero.");
- PX_CHECK_AND_RETURN(lowForwardSpeedSubStepCount>0, "lowForwardSpeedSubStepCount must be greater than zero.");
- PX_CHECK_AND_RETURN(highForwardSpeedSubStepCount>0, "highForwardSpeedSubStepCount must be greater than zero.");
-
- mThresholdLongitudinalSpeed=thresholdLongitudinalSpeed;
- mLowForwardSpeedSubStepCount=lowForwardSpeedSubStepCount;
- mHighForwardSpeedSubStepCount=highForwardSpeedSubStepCount;
- }
-
- void PxVehicleWheelsSimData::setMinLongSlipDenominator(const PxReal minLongSlipDenominator)
- {
- PX_CHECK_AND_RETURN(minLongSlipDenominator>0, "minLongSlipDenominator must be greater than or equal to zero.");
- mMinLongSlipDenominator=minLongSlipDenominator;
- }
-
- void PxVehicleWheelsSimData::setFlags(PxVehicleWheelsSimFlags flags)
- {
- mFlags = flags;
- }
-
- PxVehicleWheelsSimFlags PxVehicleWheelsSimData::getFlags() const
- {
- return PxVehicleWheelsSimFlags(mFlags);
- }
-
-
-
- /////////////////////////////
-
- PxU32 PxVehicleWheelsDynData::computeByteSize(const PxU32 numWheels)
- {
- const PxU32 numWheels4 =(((numWheels + 3) & ~3) >> 2);
- const PxU32 byteSize =
- sizeof(PxVehicleWheels4DynData)*numWheels4 +
- sizeof(PxVehicleTireForceCalculator) + sizeof(void*)*4*numWheels4 +
- sizeof(void*)*4*numWheels4 +
- sizeof(PxVehicleConstraintShader)*numWheels4;
- return byteSize;
- }
-
- PxU8* PxVehicleWheelsDynData::patchUpPointers(const PxU32 numWheels, PxVehicleWheelsDynData* dynData, PxU8* ptrIn)
- {
- const PxU32 numWheels4 =(((numWheels + 3) & ~3) >> 2);
- PxU8* ptr = ptrIn;
- dynData->mWheels4DynData = reinterpret_cast<PxVehicleWheels4DynData*>(ptr);
- ptr += sizeof(PxVehicleWheels4DynData)*numWheels4;
- dynData->mTireForceCalculators = reinterpret_cast<PxVehicleTireForceCalculator*>(ptr);
- ptr += sizeof(PxVehicleTireForceCalculator);
- dynData->mTireForceCalculators->mShaderData = reinterpret_cast<const void**>(ptr);
- ptr += sizeof(void*)*4*numWheels4;
- dynData->mUserDatas = reinterpret_cast<void**>(ptr);
- ptr += sizeof(void*)*4*numWheels4;
- for(PxU32 i=0;i<numWheels4;i++)
- {
- PxVehicleConstraintShader* shader = new(ptr) PxVehicleConstraintShader();
- dynData->mWheels4DynData[i].setVehicleConstraintShader(shader);
- ptr += sizeof(PxVehicleConstraintShader);
- }
-
- PX_ASSERT((ptrIn + computeByteSize(numWheels)) == ptr);
- return ptr;
- }
-
- PxVehicleWheelsDynData::PxVehicleWheelsDynData(const PxU32 numWheels)
- {
- const PxU32 numWheels4 =(((numWheels + 3) & ~3) >> 2);
-
- mNbWheels4=numWheels4;
- mNbActiveWheels=numWheels;
-
- //Placement new for wheels4
- for(PxU32 i=0;i<numWheels4;i++)
- {
- new(&mWheels4DynData[i]) PxVehicleWheels4DynData();
- }
-
- //Initialise tire calculator
- for(PxU32 i=0;i<4*numWheels4;i++)
- {
- mTireForceCalculators->mShaderData[i]=NULL;
- }
- new(mTireForceCalculators) PxVehicleTireForceCalculator;
-
- //Initialise user data
- for(PxU32 i=0;i<4*numWheels4;i++)
- {
- mUserDatas[i]=NULL;
- }
- }
-
- bool PxVehicleWheelsDynData::isValid() const
- {
- for(PxU32 i=0;i<mNbWheels4;i++)
- {
- PX_CHECK_AND_RETURN_VAL(mWheels4DynData[i].isValid(), "Invalid PxVehicleSuspWheelTireNDynData.mSuspWheelTire4DynData[i]", false);
- }
- return true;
- }
-
- void PxVehicleWheelsDynData::setToRestState()
- {
- //Set susp/wheel/tires to rest state.
- const PxU32 numSuspWheelTire4=mNbWheels4;
- for(PxU32 i=0;i<numSuspWheelTire4;i++)
- {
- mWheels4DynData[i].setToRestState();
- }
- }
-
- void PxVehicleWheelsDynData::setTireForceShaderFunction(PxVehicleComputeTireForce tireForceShaderFn)
- {
- mTireForceCalculators->mShader=tireForceShaderFn;
- }
-
- void PxVehicleWheelsDynData::setTireForceShaderData(const PxU32 tireId, const void* tireForceShaderData)
- {
- PX_CHECK_AND_RETURN(tireId < mNbActiveWheels, "PxVehicleWheelsDynData::setTireForceShaderData - Illegal tire");
- mTireForceCalculators->mShaderData[tireId]=tireForceShaderData;
- }
-
- const void* PxVehicleWheelsDynData::getTireForceShaderData(const PxU32 tireId) const
- {
- PX_CHECK_AND_RETURN_VAL(tireId < mNbActiveWheels, "PxVehicleWheelsDynData::getTireForceShaderData - Illegal tire", NULL);
- return mTireForceCalculators->mShaderData[tireId];
- }
-
- void PxVehicleWheelsDynData::setWheelRotationSpeed(const PxU32 wheelIdx, const PxReal speed)
- {
- PX_CHECK_AND_RETURN(wheelIdx < mNbActiveWheels, "PxVehicleWheelsDynData::setWheelRotationSpeed - Illegal wheel");
- PxVehicleWheels4DynData& suspWheelTire4=mWheels4DynData[(wheelIdx>>2)];
- suspWheelTire4.mWheelSpeeds[wheelIdx & 3] = speed;
- suspWheelTire4.mCorrectedWheelSpeeds[wheelIdx & 3] = speed;
- }
-
- PxReal PxVehicleWheelsDynData::getWheelRotationSpeed(const PxU32 wheelIdx) const
- {
- PX_CHECK_AND_RETURN_VAL(wheelIdx < mNbActiveWheels, "PxVehicleWheelsDynData::getWheelRotationSpeed - Illegal wheel", 0.0f);
- const PxVehicleWheels4DynData& suspWheelTire4=mWheels4DynData[(wheelIdx>>2)];
- return suspWheelTire4.mCorrectedWheelSpeeds[wheelIdx & 3];
- }
-
- void PxVehicleWheelsDynData::setWheelRotationAngle(const PxU32 wheelIdx, const PxReal angle)
- {
- PX_CHECK_AND_RETURN(wheelIdx < mNbActiveWheels, "PxVehicleWheelsDynData::setWheelRotationAngle - Illegal wheel");
- PxVehicleWheels4DynData& suspWheelTire4=mWheels4DynData[(wheelIdx>>2)];
- suspWheelTire4.mWheelRotationAngles[wheelIdx & 3] = angle;
- }
-
- PxReal PxVehicleWheelsDynData::getWheelRotationAngle(const PxU32 wheelIdx) const
- {
- PX_CHECK_AND_RETURN_VAL(wheelIdx < mNbActiveWheels, "PxVehicleWheelsDynData::getWheelRotationAngle - Illegal wheel", 0.0f);
- const PxVehicleWheels4DynData& suspWheelTire4=mWheels4DynData[(wheelIdx>>2)];
- return suspWheelTire4.mWheelRotationAngles[wheelIdx & 3];
- }
-
- void PxVehicleWheels::setToRestState()
- {
- //Set the rigid body to rest and clear all the accumulated forces and impulses.
- if(!(mActor->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC))
- {
- mActor->setLinearVelocity(PxVec3(0,0,0));
- mActor->setAngularVelocity(PxVec3(0,0,0));
-
- //Support case where actor is not in a scene and constraints get solved via immediate mode
- if (mActor->getScene())
- {
- mActor->clearForce(PxForceMode::eACCELERATION);
- mActor->clearForce(PxForceMode::eVELOCITY_CHANGE);
- mActor->clearTorque(PxForceMode::eACCELERATION);
- mActor->clearTorque(PxForceMode::eVELOCITY_CHANGE);
- }
- }
-
- //Set the wheels to rest state.
- mWheelsDynData.setToRestState();
- }
-
- bool PxVehicleWheels::isValid() const
- {
- PX_CHECK_AND_RETURN_VAL(mWheelsSimData.isValid(), "invalid mWheelsSimData", false);
- PX_CHECK_AND_RETURN_VAL(mWheelsDynData.isValid(), "invalid mWheelsDynData", false);
- return true;
- }
-
- PxU32 PxVehicleWheels::computeByteSize(const PxU32 numWheels)
- {
- const PxU32 byteSize =
- PxVehicleWheelsSimData::computeByteSize(numWheels) +
- PxVehicleWheelsDynData::computeByteSize(numWheels);
- return byteSize;
- }
-
- PxU8* PxVehicleWheels::patchupPointers(const PxU32 numWheels, PxVehicleWheels* vehWheels, PxU8* ptrIn)
- {
- PxU8* ptr = ptrIn;
- ptr = PxVehicleWheelsSimData::patchUpPointers(numWheels, &vehWheels->mWheelsSimData, ptr);
- ptr = PxVehicleWheelsDynData::patchUpPointers(numWheels, &vehWheels->mWheelsDynData, ptr);
- PX_ASSERT((ptrIn + computeByteSize(numWheels)) == ptr);
- return ptr;
- }
-
- void PxVehicleWheels::init(const PxU32 numWheels)
- {
- new(&mWheelsSimData) PxVehicleWheelsSimData(numWheels);
- new(&mWheelsDynData) PxVehicleWheelsDynData(numWheels);
-
- for(PxU32 i = 0; i < mWheelsSimData.mNbWheels4; i++)
- {
- new(&mWheelsDynData.mWheels4DynData[i].getVehicletConstraintShader()) PxVehicleConstraintShader(this);
- }
-
- mOnConstraintReleaseCounter = Ps::to8(mWheelsSimData.mNbWheels4);
- }
-
- void PxVehicleWheels::free()
- {
- PX_CHECK_AND_RETURN(mWheelsSimData.mNbWheels4>0, "Cars with zero wheels are illegal");
-
- const PxU32 numSuspWheelTire4 = mWheelsSimData.mNbWheels4;
-
- for(PxU32 i=0;i<numSuspWheelTire4;i++)
- {
- mWheelsDynData.mWheels4DynData[i].getVehicletConstraintShader().release();
- }
- }
-
- void PxVehicleWheels::onConstraintRelease()
- {
- mOnConstraintReleaseCounter--;
- if (0 == mOnConstraintReleaseCounter)
- {
- PX_FREE(this);
- }
- }
-
- static PxConstraintShaderTable t =
- {
- PxVehicleConstraintShader::vehicleSuspLimitConstraintSolverPrep,
- 0,
- PxVehicleConstraintShader::visualiseConstraint,
- PxConstraintFlag::Enum(0)
- };
-
- void PxVehicleWheels::setup
- (PxPhysics* physics, PxRigidDynamic* vehActor,
- const PxVehicleWheelsSimData& wheelsData,
- const PxU32 numDrivenWheels, const PxU32 numNonDrivenWheels)
- {
- mNbNonDrivenWheels = numNonDrivenWheels;
-
- PX_CHECK_AND_RETURN(wheelsData.getNbWheels() == mWheelsSimData.getNbWheels(), "PxVehicleWheels::setup - vehicle must be setup with same number of wheels as wheelsData");
- PX_CHECK_AND_RETURN(vehActor, "PxVehicleWheels::setup - vehActor is null ptr : you need to instantiate an empty PxRigidDynamic for the vehicle");
- PX_CHECK_AND_RETURN(wheelsData.isValid(), "PxVehicleWheels::setup -invalid wheelsData");
- PX_UNUSED(numDrivenWheels);
-
- #if PX_CHECKED
- PxF32 totalSprungMass=0.0f;
- for(PxU32 i=0;i<(numDrivenWheels+numNonDrivenWheels);i++)
- {
- totalSprungMass+=wheelsData.getSuspensionData(i).mSprungMass;
- }
- PX_CHECK_MSG(PxAbs((vehActor->getMass()-totalSprungMass)/vehActor->getMass()) < 0.01f, "Sum of suspension sprung masses doesn't match actor mass");
- #endif
-
- //Copy the simulation data.
- mWheelsSimData=wheelsData;
-
- //Set the actor pointer.
- mActor=vehActor;
-
- //Set all the sq result ptrs to null.
- const PxU32 numSuspWheelTire4=wheelsData.mNbWheels4;
- for(PxU32 i=0;i<numSuspWheelTire4;i++)
- {
- mWheelsDynData.mWheels4DynData[i].mRaycastResults=NULL;
- mWheelsDynData.mWheels4DynData[i].mSweepResults=NULL;
- }
-
- //Set up the suspension limits constraints.
- for(PxU32 i=0;i<numSuspWheelTire4;i++)
- {
- PxVehicleConstraintShader& shader=mWheelsDynData.mWheels4DynData[i].getVehicletConstraintShader();
- for(PxU32 j=0;j<4;j++)
- {
- shader.mData.mSuspLimitData.mCMOffsets[j]=wheelsData.mWheels4SimData[i].getSuspForceAppPointOffset(j);
- shader.mData.mSuspLimitData.mDirs[j]=wheelsData.mWheels4SimData[i].getSuspTravelDirection(j);
- shader.mData.mSuspLimitData.mErrors[j]=0.0f;
- shader.mData.mSuspLimitData.mActiveFlags[j]=false;
-
- shader.mData.mStickyTireForwardData.mCMOffsets[j]=PxVec3(0,0,0);
- shader.mData.mStickyTireForwardData.mDirs[j]=PxVec3(0,0,0);
- shader.mData.mStickyTireForwardData.mTargetSpeeds[j]=0.0f;
- shader.mData.mStickyTireForwardData.mActiveFlags[j]=false;
-
- shader.mData.mStickyTireSideData.mCMOffsets[j]=PxVec3(0,0,0);
- shader.mData.mStickyTireSideData.mDirs[j]=PxVec3(0,0,0);
- shader.mData.mStickyTireSideData.mTargetSpeeds[j]=0.0f;
- shader.mData.mStickyTireSideData.mActiveFlags[j]=false;
- }
-
-
- shader.mConstraint=physics->createConstraint(vehActor, NULL, shader, t, sizeof(PxVehicleConstraintShader::VehicleConstraintData));
- shader.mConstraint->markDirty();
- }
-
- //Set up the shader data ptrs.
- for(PxU32 i=0;i<wheelsData.mNbActiveWheels;i++)
- {
- mWheelsDynData.setTireForceShaderData(i,&mWheelsSimData.getTireData(i));
- }
-
- //Disable the unused wheels.
- for(PxU32 i=wheelsData.mNbActiveWheels;i<4*mWheelsSimData.mNbWheels4;i++)
- {
- mWheelsSimData.disableWheel(i);
- }
-
- //Pose the wheels that are mapped to shapes so that all shapes are at the rest pose.
- for(PxU32 i=0;i<wheelsData.mNbActiveWheels;i++)
- {
- const PxI32 shapeId = mWheelsSimData.getWheelShapeMapping(i);
- if(-1!=shapeId)
- {
- PX_CHECK_AND_RETURN(PxU32(shapeId) < mActor->getNbShapes(), "Illegal wheel shape mapping, shape does not exist on actor");
-
- //Compute the shape local pose
- const PxTransform chassisCMOffset=mActor->getCMassLocalPose();
- PxTransform wheelOffset=chassisCMOffset;
- wheelOffset.p+=mWheelsSimData.getWheelCentreOffset(i);
- //Pose the shape.
- PxShape* shapeBuffer[1];
- mActor->getShapes(shapeBuffer,1,PxU32(shapeId));
- shapeBuffer[0]->setLocalPose(wheelOffset);
- }
- }
- }
-
- void PxVehicleWheels::requiresObjects(PxProcessPxBaseCallback& c)
- {
- c.process(*mActor);
-
- for(PxU32 i=0;i<mWheelsSimData.mNbWheels4;i++)
- {
- c.process(*mWheelsDynData.mWheels4DynData[i].getVehicletConstraintShader().getPxConstraint());
- }
- }
-
- static PxConstraint* resolveConstraintPtr(PxDeserializationContext& context,
- PxConstraint* old,
- PxConstraintConnector* connector,
- PxConstraintShaderTable &shaders)
- {
- context.translatePxBase(old);
- PxConstraint* new_nx = static_cast<PxConstraint*>(old);
- new_nx->setConstraintFunctions(*connector, shaders);
- return new_nx;
- }
-
- void PxVehicleWheels::resolveReferences(PxDeserializationContext& context)
- {
- context.translatePxBase(mActor);
-
- for(PxU32 i=0;i<mWheelsSimData.mNbWheels4;i++)
- {
- PxVehicleConstraintShader& shader=mWheelsDynData.mWheels4DynData[i].getVehicletConstraintShader();
- shader.setPxConstraint(resolveConstraintPtr(context,shader.getPxConstraint(), shader.getConnector(), t));
- }
-
- //Set up the shader data ptrs.
- for(PxU32 i=0;i<mWheelsSimData.mNbActiveWheels;i++)
- {
- mWheelsDynData.setTireForceShaderData(i,&mWheelsSimData.getTireData(i));
- }
- }
-
- PxReal PxVehicleWheels::computeForwardSpeed() const
- {
- const PxTransform vehicleChassisTrnsfm=mActor->getGlobalPose().transform(mActor->getCMassLocalPose());
- return mActor->getLinearVelocity().dot(vehicleChassisTrnsfm.q.rotate(gForward));
- }
-
- PxReal PxVehicleWheels::computeSidewaysSpeed() const
- {
- const PxTransform vehicleChassisTrnsfm=mActor->getGlobalPose().transform(mActor->getCMassLocalPose());
- return mActor->getLinearVelocity().dot(vehicleChassisTrnsfm.q.rotate(gRight));
- }
-
- ////////////////////////////////////////////////////////////////////////////
-
- void PxVehicleWheelsDynData::setUserData(const PxU32 tireIdx, void* userData)
- {
- PX_CHECK_AND_RETURN(tireIdx < mNbActiveWheels, "PxVehicleWheelsDynData::setUserData - Illegal wheel");
- mUserDatas[tireIdx]=userData;
- }
-
- void* PxVehicleWheelsDynData::getUserData(const PxU32 tireIdx) const
- {
- PX_CHECK_AND_RETURN_VAL(tireIdx < mNbActiveWheels, "PxVehicleWheelsDynData::setUserData - Illegal wheel", NULL);
- return mUserDatas[tireIdx];
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
-
- void PxVehicleWheelsDynData::copy(const PxVehicleWheelsDynData& src, const PxU32 srcWheel, const PxU32 trgWheel)
- {
- PX_CHECK_AND_RETURN(srcWheel < src.mNbActiveWheels, "PxVehicleWheelsDynData::copy - Illegal src wheel");
- PX_CHECK_AND_RETURN(trgWheel < mNbActiveWheels, "PxVehicleWheelsDynData::copy - Illegal trg wheel");
-
- const PxVehicleWheels4DynData& src4 = src.mWheels4DynData[(srcWheel>>2)];
- PxVehicleWheels4DynData& trg4 = mWheels4DynData[(trgWheel>>2)];
-
- trg4.mWheelSpeeds[trgWheel & 3] = src4.mWheelSpeeds[srcWheel & 3];
- trg4.mCorrectedWheelSpeeds[trgWheel & 3] = src4.mCorrectedWheelSpeeds[srcWheel & 3];
- trg4.mTireLowForwardSpeedTimers[trgWheel & 3] = src4.mTireLowForwardSpeedTimers[srcWheel & 3];
- trg4.mTireLowSideSpeedTimers[trgWheel & 3] = src4.mTireLowSideSpeedTimers[srcWheel & 3];
- trg4.mWheelRotationAngles[trgWheel & 3] = src4.mWheelRotationAngles[srcWheel & 3];
-
- if(src4.mRaycastResults)
- {
- const PxVehicleWheels4DynData::SuspLineRaycast& suspLineRaycastSrc = reinterpret_cast<const PxVehicleWheels4DynData::SuspLineRaycast&>(src4.mQueryOrCachedHitResults);
- PxVehicleWheels4DynData::SuspLineRaycast& suspLineRaycastTrg = reinterpret_cast<PxVehicleWheels4DynData::SuspLineRaycast&>(trg4.mQueryOrCachedHitResults);
-
- suspLineRaycastTrg.mStarts[trgWheel & 3] = suspLineRaycastSrc.mStarts[srcWheel & 3];
- suspLineRaycastTrg.mDirs[trgWheel & 3] = suspLineRaycastSrc.mDirs[srcWheel & 3];
- suspLineRaycastTrg.mLengths[trgWheel & 3] = suspLineRaycastSrc.mLengths[srcWheel & 3];
- }
- else if(src4.mSweepResults)
- {
- const PxVehicleWheels4DynData::SuspLineSweep& suspLineSweepSrc = reinterpret_cast<const PxVehicleWheels4DynData::SuspLineSweep&>(src4.mQueryOrCachedHitResults);
- PxVehicleWheels4DynData::SuspLineSweep& suspLineSweepTrg = reinterpret_cast<PxVehicleWheels4DynData::SuspLineSweep&>(trg4.mQueryOrCachedHitResults);
-
- suspLineSweepTrg.mStartPose[trgWheel & 3] = suspLineSweepSrc.mStartPose[srcWheel & 3];
- suspLineSweepTrg.mDirs[trgWheel & 3] = suspLineSweepSrc.mDirs[srcWheel & 3];
- suspLineSweepTrg.mLengths[trgWheel & 3] = suspLineSweepSrc.mLengths[srcWheel & 3];
- }
- else
- {
- const PxVehicleWheels4DynData::CachedSuspLineSceneQuerytHitResult& cachedHitResultSrc = reinterpret_cast<const PxVehicleWheels4DynData::CachedSuspLineSceneQuerytHitResult&>(src4.mQueryOrCachedHitResults);
- PxVehicleWheels4DynData::CachedSuspLineSceneQuerytHitResult& cachedHitResultTrg = reinterpret_cast<PxVehicleWheels4DynData::CachedSuspLineSceneQuerytHitResult&>(trg4.mQueryOrCachedHitResults);
-
- cachedHitResultTrg.mPlanes[trgWheel & 3] = cachedHitResultSrc.mPlanes[srcWheel & 3];
- cachedHitResultTrg.mFrictionMultipliers[trgWheel & 3] = cachedHitResultSrc.mFrictionMultipliers[srcWheel & 3];
- cachedHitResultTrg.mCounts[trgWheel & 3] = cachedHitResultSrc.mCounts[srcWheel & 3];
- cachedHitResultTrg.mDistances[trgWheel & 3] = cachedHitResultSrc.mDistances[srcWheel & 3];
- }
- }
-
- PxU32 PxVehicleWheelsDynData::getConstraints(PxConstraint** userBuffer, PxU32 bufferSize, PxU32 startIndex) const
- {
- const PxU32 remainder = PxU32(PxMax<PxI32>(PxI32(mNbWheels4 - startIndex), 0));
- const PxU32 writeCount = PxMin(remainder, bufferSize);
- PxVehicleWheels4DynData* wheels4DynData = mWheels4DynData + startIndex;
- for (PxU32 i = 0; i < writeCount; i++)
- {
- userBuffer[i] = wheels4DynData->getVehicletConstraintShader().getPxConstraint();
- wheels4DynData++;
- }
- return writeCount;
- }
-
-
- } //namespace physx
-